1169689Skan/* Parser for C and Objective-C.
2169689Skan   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3169689Skan   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4169689Skan
5169689Skan   Parser actions based on the old Bison parser; structure somewhat
6169689Skan   influenced by and fragments based on the C++ parser.
7169689Skan
8169689SkanThis file is part of GCC.
9169689Skan
10169689SkanGCC is free software; you can redistribute it and/or modify it under
11169689Skanthe terms of the GNU General Public License as published by the Free
12169689SkanSoftware Foundation; either version 2, or (at your option) any later
13169689Skanversion.
14169689Skan
15169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
16169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
17169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18169689Skanfor more details.
19169689Skan
20169689SkanYou should have received a copy of the GNU General Public License
21169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
22169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23169689Skan02110-1301, USA.  */
24169689Skan
25169689Skan/* TODO:
26169689Skan
27169689Skan   Make sure all relevant comments, and all relevant code from all
28169689Skan   actions, brought over from old parser.  Verify exact correspondence
29169689Skan   of syntax accepted.
30169689Skan
31169689Skan   Add testcases covering every input symbol in every state in old and
32169689Skan   new parsers.
33169689Skan
34169689Skan   Include full syntax for GNU C, including erroneous cases accepted
35169689Skan   with error messages, in syntax productions in comments.
36169689Skan
37169689Skan   Make more diagnostics in the front end generally take an explicit
38169689Skan   location rather than implicitly using input_location.  */
39169689Skan
40169689Skan#include "config.h"
41169689Skan#include "system.h"
42169689Skan#include "coretypes.h"
43169689Skan#include "tm.h"
44169689Skan#include "tree.h"
45169689Skan#include "rtl.h"
46169689Skan#include "langhooks.h"
47169689Skan#include "input.h"
48169689Skan#include "cpplib.h"
49169689Skan#include "timevar.h"
50169689Skan#include "c-pragma.h"
51169689Skan#include "c-tree.h"
52169689Skan#include "flags.h"
53169689Skan#include "output.h"
54169689Skan#include "toplev.h"
55169689Skan#include "ggc.h"
56169689Skan#include "c-common.h"
57169689Skan#include "vec.h"
58169689Skan#include "target.h"
59169689Skan#include "cgraph.h"
60169689Skan
61169689Skan
62169689Skan/* Miscellaneous data and functions needed for the parser.  */
63169689Skan
64169689Skanint yydebug;
65169689Skan
66169689Skan/* Objective-C specific parser/lexer information.  */
67169689Skan
68169689Skanstatic int objc_pq_context = 0;
69169689Skan
70169689Skan/* The following flag is needed to contextualize Objective-C lexical
71169689Skan   analysis.  In some cases (e.g., 'int NSObject;'), it is undesirable
72169689Skan   to bind an identifier to an Objective-C class, even if a class with
73169689Skan   that name exists.  */
74169689Skanstatic int objc_need_raw_identifier = 0;
75169689Skan#define OBJC_NEED_RAW_IDENTIFIER(VAL)		\
76169689Skan  do {						\
77169689Skan    if (c_dialect_objc ())			\
78169689Skan      objc_need_raw_identifier = VAL;		\
79169689Skan  } while (0)
80169689Skan
81261188Spfg/* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 d) */
82261188Spfg/* For checking property attribute keywords */
83261188Spfgstatic int objc_property_attr_context;
84261188Spfg/* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 d) */
85261188Spfg/* APPLE LOCAL radar 3803157 - objc attribute (in 4.2 e) */
86261188Spfgstatic tree objc_method_attributes;
87261188Spfg/* APPLE LOCAL begin C* language (in 4.2 f) */
88261188Spfg/* For checking for 'foreach' context. */
89261188Spfgstatic int objc_foreach_context;
90261188Spfg/* APPLE LOCAL end C* language (in 4.2 f) */
91261188Spfg
92169689Skan/* The reserved keyword table.  */
93169689Skanstruct resword
94169689Skan{
95169689Skan  const char *word;
96169689Skan  ENUM_BITFIELD(rid) rid : 16;
97169689Skan  unsigned int disable   : 16;
98169689Skan};
99169689Skan
100169689Skan/* Disable mask.  Keywords are disabled if (reswords[i].disable &
101169689Skan   mask) is _true_.  */
102169689Skan#define D_C89	0x01	/* not in C89 */
103169689Skan#define D_EXT	0x02	/* GCC extension */
104169689Skan#define D_EXT89	0x04	/* GCC extension incorporated in C99 */
105169689Skan#define D_OBJC	0x08	/* Objective C only */
106169689Skan
107169689Skanstatic const struct resword reswords[] =
108169689Skan{
109169689Skan  { "_Bool",		RID_BOOL,	0 },
110169689Skan  { "_Complex",		RID_COMPLEX,	0 },
111169689Skan  { "_Decimal32",       RID_DFLOAT32,  D_EXT },
112169689Skan  { "_Decimal64",       RID_DFLOAT64,  D_EXT },
113169689Skan  { "_Decimal128",      RID_DFLOAT128, D_EXT },
114169689Skan  { "__FUNCTION__",	RID_FUNCTION_NAME, 0 },
115169689Skan  { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
116169689Skan  { "__alignof",	RID_ALIGNOF,	0 },
117169689Skan  { "__alignof__",	RID_ALIGNOF,	0 },
118169689Skan  { "__asm",		RID_ASM,	0 },
119169689Skan  { "__asm__",		RID_ASM,	0 },
120169689Skan  { "__attribute",	RID_ATTRIBUTE,	0 },
121169689Skan  { "__attribute__",	RID_ATTRIBUTE,	0 },
122169689Skan  { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
123169689Skan  { "__builtin_offsetof", RID_OFFSETOF, 0 },
124169689Skan  { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
125169689Skan  { "__builtin_va_arg",	RID_VA_ARG,	0 },
126169689Skan  { "__complex",	RID_COMPLEX,	0 },
127169689Skan  { "__complex__",	RID_COMPLEX,	0 },
128169689Skan  { "__const",		RID_CONST,	0 },
129169689Skan  { "__const__",	RID_CONST,	0 },
130169689Skan  { "__extension__",	RID_EXTENSION,	0 },
131169689Skan  { "__func__",		RID_C99_FUNCTION_NAME, 0 },
132169689Skan  { "__imag",		RID_IMAGPART,	0 },
133169689Skan  { "__imag__",		RID_IMAGPART,	0 },
134169689Skan  { "__inline",		RID_INLINE,	0 },
135169689Skan  { "__inline__",	RID_INLINE,	0 },
136169689Skan  { "__label__",	RID_LABEL,	0 },
137169689Skan  { "__real",		RID_REALPART,	0 },
138169689Skan  { "__real__",		RID_REALPART,	0 },
139169689Skan  { "__restrict",	RID_RESTRICT,	0 },
140169689Skan  { "__restrict__",	RID_RESTRICT,	0 },
141169689Skan  { "__signed",		RID_SIGNED,	0 },
142169689Skan  { "__signed__",	RID_SIGNED,	0 },
143169689Skan  { "__thread",		RID_THREAD,	0 },
144169689Skan  { "__typeof",		RID_TYPEOF,	0 },
145169689Skan  { "__typeof__",	RID_TYPEOF,	0 },
146169689Skan  { "__volatile",	RID_VOLATILE,	0 },
147169689Skan  { "__volatile__",	RID_VOLATILE,	0 },
148169689Skan  { "asm",		RID_ASM,	D_EXT },
149169689Skan  { "auto",		RID_AUTO,	0 },
150169689Skan  { "break",		RID_BREAK,	0 },
151169689Skan  { "case",		RID_CASE,	0 },
152169689Skan  { "char",		RID_CHAR,	0 },
153169689Skan  { "const",		RID_CONST,	0 },
154169689Skan  { "continue",		RID_CONTINUE,	0 },
155169689Skan  { "default",		RID_DEFAULT,	0 },
156169689Skan  { "do",		RID_DO,		0 },
157169689Skan  { "double",		RID_DOUBLE,	0 },
158169689Skan  { "else",		RID_ELSE,	0 },
159169689Skan  { "enum",		RID_ENUM,	0 },
160169689Skan  { "extern",		RID_EXTERN,	0 },
161169689Skan  { "float",		RID_FLOAT,	0 },
162169689Skan  { "for",		RID_FOR,	0 },
163169689Skan  { "goto",		RID_GOTO,	0 },
164169689Skan  { "if",		RID_IF,		0 },
165169689Skan  { "inline",		RID_INLINE,	D_EXT89 },
166169689Skan  { "int",		RID_INT,	0 },
167169689Skan  { "long",		RID_LONG,	0 },
168169689Skan  { "register",		RID_REGISTER,	0 },
169169689Skan  { "restrict",		RID_RESTRICT,	D_C89 },
170169689Skan  { "return",		RID_RETURN,	0 },
171169689Skan  { "short",		RID_SHORT,	0 },
172169689Skan  { "signed",		RID_SIGNED,	0 },
173169689Skan  { "sizeof",		RID_SIZEOF,	0 },
174169689Skan  { "static",		RID_STATIC,	0 },
175169689Skan  { "struct",		RID_STRUCT,	0 },
176169689Skan  { "switch",		RID_SWITCH,	0 },
177169689Skan  { "typedef",		RID_TYPEDEF,	0 },
178169689Skan  { "typeof",		RID_TYPEOF,	D_EXT },
179169689Skan  { "union",		RID_UNION,	0 },
180169689Skan  { "unsigned",		RID_UNSIGNED,	0 },
181169689Skan  { "void",		RID_VOID,	0 },
182169689Skan  { "volatile",		RID_VOLATILE,	0 },
183169689Skan  { "while",		RID_WHILE,	0 },
184169689Skan  /* These Objective-C keywords are recognized only immediately after
185169689Skan     an '@'.  */
186169689Skan  { "class",		RID_AT_CLASS,		D_OBJC },
187169689Skan  { "compatibility_alias", RID_AT_ALIAS,	D_OBJC },
188169689Skan  { "defs",		RID_AT_DEFS,		D_OBJC },
189169689Skan  { "encode",		RID_AT_ENCODE,		D_OBJC },
190169689Skan  { "end",		RID_AT_END,		D_OBJC },
191169689Skan  { "implementation",	RID_AT_IMPLEMENTATION,	D_OBJC },
192169689Skan  { "interface",	RID_AT_INTERFACE,	D_OBJC },
193261188Spfg  /* APPLE LOCAL begin C* language (in 4.2 j) */
194261188Spfg  { "optional",		RID_AT_OPTIONAL,	D_OBJC },
195261188Spfg  { "required",		RID_AT_REQUIRED,	D_OBJC },
196261188Spfg  /* APPLE LOCAL end C* language (in 4.2 j) */
197261188Spfg  /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 k) */
198261188Spfg  { "property",		RID_AT_PROPERTY,	D_OBJC },
199261188Spfg  /* APPLE LOCAL radar 4564694 */
200261188Spfg  { "package",          RID_AT_PACKAGE,         D_OBJC },
201169689Skan  { "private",		RID_AT_PRIVATE,		D_OBJC },
202169689Skan  { "protected",	RID_AT_PROTECTED,	D_OBJC },
203169689Skan  { "protocol",		RID_AT_PROTOCOL,	D_OBJC },
204169689Skan  { "public",		RID_AT_PUBLIC,		D_OBJC },
205169689Skan  { "selector",		RID_AT_SELECTOR,	D_OBJC },
206169689Skan  { "throw",		RID_AT_THROW,		D_OBJC },
207169689Skan  { "try",		RID_AT_TRY,		D_OBJC },
208169689Skan  { "catch",		RID_AT_CATCH,		D_OBJC },
209169689Skan  { "finally",		RID_AT_FINALLY,		D_OBJC },
210169689Skan  { "synchronized",	RID_AT_SYNCHRONIZED,	D_OBJC },
211169689Skan  /* These are recognized only in protocol-qualifier context
212169689Skan     (see above) */
213169689Skan  { "bycopy",		RID_BYCOPY,		D_OBJC },
214169689Skan  { "byref",		RID_BYREF,		D_OBJC },
215169689Skan  { "in",		RID_IN,			D_OBJC },
216169689Skan  { "inout",		RID_INOUT,		D_OBJC },
217169689Skan  { "oneway",		RID_ONEWAY,		D_OBJC },
218169689Skan  { "out",		RID_OUT,		D_OBJC },
219261188Spfg  /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 l) */
220261188Spfg  /* These are recognized inside a property attribute list */
221261188Spfg  { "readonly",		RID_READONLY,		D_OBJC },
222261188Spfg  { "getter",		RID_GETTER,		D_OBJC },
223261188Spfg  { "setter",		RID_SETTER,		D_OBJC },
224261188Spfg  /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 l) */
225261188Spfg  /* APPLE LOCAL radar 4947014 - objc atomic property */
226261188Spfg  { "nonatomic",        RID_NONATOMIC,          D_OBJC },
227169689Skan};
228169689Skan#define N_reswords (sizeof reswords / sizeof (struct resword))
229169689Skan
230169689Skan/* All OpenMP clauses.  OpenMP 2.5.  */
231169689Skantypedef enum pragma_omp_clause {
232169689Skan  PRAGMA_OMP_CLAUSE_NONE = 0,
233169689Skan
234169689Skan  PRAGMA_OMP_CLAUSE_COPYIN,
235169689Skan  PRAGMA_OMP_CLAUSE_COPYPRIVATE,
236169689Skan  PRAGMA_OMP_CLAUSE_DEFAULT,
237169689Skan  PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
238169689Skan  PRAGMA_OMP_CLAUSE_IF,
239169689Skan  PRAGMA_OMP_CLAUSE_LASTPRIVATE,
240169689Skan  PRAGMA_OMP_CLAUSE_NOWAIT,
241169689Skan  PRAGMA_OMP_CLAUSE_NUM_THREADS,
242169689Skan  PRAGMA_OMP_CLAUSE_ORDERED,
243169689Skan  PRAGMA_OMP_CLAUSE_PRIVATE,
244169689Skan  PRAGMA_OMP_CLAUSE_REDUCTION,
245169689Skan  PRAGMA_OMP_CLAUSE_SCHEDULE,
246169689Skan  PRAGMA_OMP_CLAUSE_SHARED
247169689Skan} pragma_omp_clause;
248169689Skan
249169689Skan
250169689Skan/* Initialization routine for this file.  */
251169689Skan
252169689Skanvoid
253169689Skanc_parse_init (void)
254169689Skan{
255169689Skan  /* The only initialization required is of the reserved word
256169689Skan     identifiers.  */
257169689Skan  unsigned int i;
258169689Skan  tree id;
259169689Skan  int mask = (flag_isoc99 ? 0 : D_C89)
260169689Skan	      | (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0);
261169689Skan
262169689Skan  if (!c_dialect_objc ())
263169689Skan     mask |= D_OBJC;
264169689Skan
265169689Skan  ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
266169689Skan  for (i = 0; i < N_reswords; i++)
267169689Skan    {
268169689Skan      /* If a keyword is disabled, do not enter it into the table
269169689Skan	 and so create a canonical spelling that isn't a keyword.  */
270169689Skan      if (reswords[i].disable & mask)
271169689Skan	continue;
272169689Skan
273169689Skan      id = get_identifier (reswords[i].word);
274169689Skan      C_RID_CODE (id) = reswords[i].rid;
275169689Skan      C_IS_RESERVED_WORD (id) = 1;
276169689Skan      ridpointers [(int) reswords[i].rid] = id;
277169689Skan    }
278169689Skan}
279169689Skan
280169689Skan/* The C lexer intermediates between the lexer in cpplib and c-lex.c
281169689Skan   and the C parser.  Unlike the C++ lexer, the parser structure
282169689Skan   stores the lexer information instead of using a separate structure.
283169689Skan   Identifiers are separated into ordinary identifiers, type names,
284169689Skan   keywords and some other Objective-C types of identifiers, and some
285169689Skan   look-ahead is maintained.
286169689Skan
287169689Skan   ??? It might be a good idea to lex the whole file up front (as for
288169689Skan   C++).  It would then be possible to share more of the C and C++
289169689Skan   lexer code, if desired.  */
290169689Skan
291169689Skan/* The following local token type is used.  */
292169689Skan
293169689Skan/* A keyword.  */
294169689Skan#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
295169689Skan
296169689Skan/* More information about the type of a CPP_NAME token.  */
297169689Skantypedef enum c_id_kind {
298169689Skan  /* An ordinary identifier.  */
299169689Skan  C_ID_ID,
300169689Skan  /* An identifier declared as a typedef name.  */
301169689Skan  C_ID_TYPENAME,
302169689Skan  /* An identifier declared as an Objective-C class name.  */
303169689Skan  C_ID_CLASSNAME,
304169689Skan  /* Not an identifier.  */
305169689Skan  C_ID_NONE
306169689Skan} c_id_kind;
307169689Skan
308169689Skan/* A single C token after string literal concatenation and conversion
309169689Skan   of preprocessing tokens to tokens.  */
310169689Skantypedef struct c_token GTY (())
311169689Skan{
312169689Skan  /* The kind of token.  */
313169689Skan  ENUM_BITFIELD (cpp_ttype) type : 8;
314169689Skan  /* If this token is a CPP_NAME, this value indicates whether also
315169689Skan     declared as some kind of type.  Otherwise, it is C_ID_NONE.  */
316169689Skan  ENUM_BITFIELD (c_id_kind) id_kind : 8;
317169689Skan  /* If this token is a keyword, this value indicates which keyword.
318169689Skan     Otherwise, this value is RID_MAX.  */
319169689Skan  ENUM_BITFIELD (rid) keyword : 8;
320169689Skan  /* If this token is a CPP_PRAGMA, this indicates the pragma that
321169689Skan     was seen.  Otherwise it is PRAGMA_NONE.  */
322169689Skan  ENUM_BITFIELD (pragma_kind) pragma_kind : 7;
323169689Skan  /* True if this token is from a system header.  */
324169689Skan  BOOL_BITFIELD in_system_header : 1;
325169689Skan  /* The value associated with this token, if any.  */
326169689Skan  tree value;
327169689Skan  /* The location at which this token was found.  */
328169689Skan  location_t location;
329169689Skan} c_token;
330169689Skan
331169689Skan/* A parser structure recording information about the state and
332169689Skan   context of parsing.  Includes lexer information with up to two
333169689Skan   tokens of look-ahead; more are not needed for C.  */
334169689Skantypedef struct c_parser GTY(())
335169689Skan{
336169689Skan  /* The look-ahead tokens.  */
337169689Skan  c_token tokens[2];
338169689Skan  /* How many look-ahead tokens are available (0, 1 or 2).  */
339169689Skan  short tokens_avail;
340169689Skan  /* True if a syntax error is being recovered from; false otherwise.
341169689Skan     c_parser_error sets this flag.  It should clear this flag when
342169689Skan     enough tokens have been consumed to recover from the error.  */
343169689Skan  BOOL_BITFIELD error : 1;
344169689Skan  /* True if we're processing a pragma, and shouldn't automatically
345169689Skan     consume CPP_PRAGMA_EOL.  */
346169689Skan  BOOL_BITFIELD in_pragma : 1;
347169689Skan} c_parser;
348169689Skan
349169689Skan
350169689Skan/* The actual parser and external interface.  ??? Does this need to be
351169689Skan   garbage-collected?  */
352169689Skan
353169689Skanstatic GTY (()) c_parser *the_parser;
354169689Skan
355261188Spfg/* APPLE LOCAL C* language (in 4.2 ae) */
356261188Spfgstatic c_token * c_parser_peek_2nd_token (c_parser *);
357169689Skan
358169689Skan/* Read in and lex a single token, storing it in *TOKEN.  */
359169689Skan
360169689Skanstatic void
361261188Spfgc_lex_one_token (c_token *token, c_parser *parser)
362169689Skan{
363169689Skan  timevar_push (TV_LEX);
364169689Skan
365169689Skan  token->type = c_lex_with_flags (&token->value, &token->location, NULL);
366169689Skan  token->id_kind = C_ID_NONE;
367169689Skan  token->keyword = RID_MAX;
368169689Skan  token->pragma_kind = PRAGMA_NONE;
369169689Skan  token->in_system_header = in_system_header;
370169689Skan
371169689Skan  switch (token->type)
372169689Skan    {
373169689Skan    case CPP_NAME:
374169689Skan      {
375169689Skan	tree decl;
376169689Skan
377169689Skan	int objc_force_identifier = objc_need_raw_identifier;
378169689Skan	OBJC_NEED_RAW_IDENTIFIER (0);
379169689Skan
380169689Skan	if (C_IS_RESERVED_WORD (token->value))
381169689Skan	  {
382169689Skan	    enum rid rid_code = C_RID_CODE (token->value);
383169689Skan
384169689Skan	    if (c_dialect_objc ())
385169689Skan	      {
386169689Skan		if (!OBJC_IS_AT_KEYWORD (rid_code)
387169689Skan		    && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
388169689Skan		  {
389169689Skan		    /* Return the canonical spelling for this keyword.  */
390169689Skan		    token->value = ridpointers[(int) rid_code];
391169689Skan		    token->type = CPP_KEYWORD;
392169689Skan		    token->keyword = rid_code;
393169689Skan		    break;
394169689Skan		  }
395261188Spfg		/* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */
396261188Spfg		else if (objc_foreach_context && rid_code == RID_IN)
397261188Spfg		  {
398261188Spfg		    /* This is dangerous, we assume we don't need 3 input tokens look ahead.  */
399261188Spfg		    c_token *tk = c_parser_peek_2nd_token (parser);
400261188Spfg		    if (tk->type == CPP_NAME
401261188Spfg			|| tk->type == CPP_OPEN_PAREN
402261188Spfg			|| tk->type == CPP_MULT
403261188Spfg			|| tk->type == CPP_PLUS
404261188Spfg			|| tk->type == CPP_PLUS_PLUS
405261188Spfg			|| tk->type == CPP_MINUS
406261188Spfg			|| tk->type == CPP_MINUS_MINUS
407261188Spfg			/* APPLE LOCAL radar 4529200 (in 4.2 af) */
408261188Spfg			|| tk->type == CPP_OPEN_SQUARE)
409261188Spfg		      {
410261188Spfg			token->type = CPP_KEYWORD;
411261188Spfg			token->keyword = rid_code;
412261188Spfg			break;
413261188Spfg		      }
414261188Spfg		  }
415261188Spfg		/* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */
416169689Skan	      }
417169689Skan	    else
418169689Skan	      {
419169689Skan		/* Return the canonical spelling for this keyword.  */
420169689Skan		token->value = ridpointers[(int) rid_code];
421169689Skan		token->type = CPP_KEYWORD;
422169689Skan		token->keyword = rid_code;
423169689Skan		break;
424169689Skan	      }
425169689Skan	  }
426169689Skan
427169689Skan	decl = lookup_name (token->value);
428169689Skan	if (decl)
429169689Skan	  {
430169689Skan	    if (TREE_CODE (decl) == TYPE_DECL)
431169689Skan	      {
432169689Skan		token->id_kind = C_ID_TYPENAME;
433169689Skan		break;
434169689Skan	      }
435169689Skan	  }
436169689Skan	else if (c_dialect_objc ())
437169689Skan	  {
438169689Skan	    tree objc_interface_decl = objc_is_class_name (token->value);
439169689Skan	    /* Objective-C class names are in the same namespace as
440169689Skan	       variables and typedefs, and hence are shadowed by local
441169689Skan	       declarations.  */
442169689Skan	    if (objc_interface_decl
443169689Skan		&& (global_bindings_p ()
444169689Skan		    || (!objc_force_identifier && !decl)))
445169689Skan	      {
446169689Skan		token->value = objc_interface_decl;
447169689Skan		token->id_kind = C_ID_CLASSNAME;
448169689Skan		break;
449169689Skan	      }
450169689Skan	  }
451169689Skan        token->id_kind = C_ID_ID;
452169689Skan      }
453169689Skan      break;
454169689Skan    case CPP_AT_NAME:
455169689Skan      /* This only happens in Objective-C; it must be a keyword.  */
456169689Skan      token->type = CPP_KEYWORD;
457169689Skan      token->keyword = C_RID_CODE (token->value);
458169689Skan      break;
459169689Skan    case CPP_COLON:
460169689Skan    case CPP_COMMA:
461169689Skan    case CPP_CLOSE_PAREN:
462169689Skan    case CPP_SEMICOLON:
463169689Skan      /* These tokens may affect the interpretation of any identifiers
464169689Skan	 following, if doing Objective-C.  */
465169689Skan      OBJC_NEED_RAW_IDENTIFIER (0);
466169689Skan      break;
467169689Skan    case CPP_PRAGMA:
468169689Skan      /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST.  */
469169689Skan      token->pragma_kind = TREE_INT_CST_LOW (token->value);
470169689Skan      token->value = NULL;
471169689Skan      break;
472169689Skan    default:
473169689Skan      break;
474169689Skan    }
475169689Skan  timevar_pop (TV_LEX);
476169689Skan}
477169689Skan
478169689Skan/* Return a pointer to the next token from PARSER, reading it in if
479169689Skan   necessary.  */
480169689Skan
481169689Skanstatic inline c_token *
482169689Skanc_parser_peek_token (c_parser *parser)
483169689Skan{
484169689Skan  if (parser->tokens_avail == 0)
485169689Skan    {
486261188Spfg      /* APPLE LOCAL begin switch these two */
487169689Skan      parser->tokens_avail = 1;
488261188Spfg      /* APPLE LOCAL C* language (in 4.2 ae) */
489261188Spfg      c_lex_one_token (&parser->tokens[0], parser);
490261188Spfg      /* APPLE LOCAL end switch these two */
491169689Skan    }
492169689Skan  return &parser->tokens[0];
493169689Skan}
494169689Skan
495169689Skan/* Return true if the next token from PARSER has the indicated
496169689Skan   TYPE.  */
497169689Skan
498169689Skanstatic inline bool
499169689Skanc_parser_next_token_is (c_parser *parser, enum cpp_ttype type)
500169689Skan{
501169689Skan  return c_parser_peek_token (parser)->type == type;
502169689Skan}
503169689Skan
504169689Skan/* Return true if the next token from PARSER does not have the
505169689Skan   indicated TYPE.  */
506169689Skan
507169689Skanstatic inline bool
508169689Skanc_parser_next_token_is_not (c_parser *parser, enum cpp_ttype type)
509169689Skan{
510169689Skan  return !c_parser_next_token_is (parser, type);
511169689Skan}
512169689Skan
513169689Skan/* Return true if the next token from PARSER is the indicated
514169689Skan   KEYWORD.  */
515169689Skan
516169689Skanstatic inline bool
517169689Skanc_parser_next_token_is_keyword (c_parser *parser, enum rid keyword)
518169689Skan{
519169689Skan  c_token *token;
520169689Skan
521169689Skan  /* Peek at the next token.  */
522169689Skan  token = c_parser_peek_token (parser);
523169689Skan  /* Check to see if it is the indicated keyword.  */
524169689Skan  return token->keyword == keyword;
525169689Skan}
526169689Skan
527169689Skan/* Return true if TOKEN can start a type name,
528169689Skan   false otherwise.  */
529169689Skanstatic bool
530169689Skanc_token_starts_typename (c_token *token)
531169689Skan{
532169689Skan  switch (token->type)
533169689Skan    {
534169689Skan    case CPP_NAME:
535169689Skan      switch (token->id_kind)
536169689Skan	{
537169689Skan	case C_ID_ID:
538169689Skan	  return false;
539169689Skan	case C_ID_TYPENAME:
540169689Skan	  return true;
541169689Skan	case C_ID_CLASSNAME:
542169689Skan	  gcc_assert (c_dialect_objc ());
543169689Skan	  return true;
544169689Skan	default:
545169689Skan	  gcc_unreachable ();
546169689Skan	}
547169689Skan    case CPP_KEYWORD:
548169689Skan      switch (token->keyword)
549169689Skan	{
550169689Skan	case RID_UNSIGNED:
551169689Skan	case RID_LONG:
552169689Skan	case RID_SHORT:
553169689Skan	case RID_SIGNED:
554169689Skan	case RID_COMPLEX:
555169689Skan	case RID_INT:
556169689Skan	case RID_CHAR:
557169689Skan	case RID_FLOAT:
558169689Skan	case RID_DOUBLE:
559169689Skan	case RID_VOID:
560169689Skan	case RID_DFLOAT32:
561169689Skan	case RID_DFLOAT64:
562169689Skan	case RID_DFLOAT128:
563169689Skan	case RID_BOOL:
564169689Skan	case RID_ENUM:
565169689Skan	case RID_STRUCT:
566169689Skan	case RID_UNION:
567169689Skan	case RID_TYPEOF:
568169689Skan	case RID_CONST:
569169689Skan	case RID_VOLATILE:
570169689Skan	case RID_RESTRICT:
571169689Skan	case RID_ATTRIBUTE:
572169689Skan	  return true;
573169689Skan	default:
574169689Skan	  return false;
575169689Skan	}
576169689Skan    case CPP_LESS:
577169689Skan      if (c_dialect_objc ())
578169689Skan	return true;
579169689Skan      return false;
580169689Skan    default:
581169689Skan      return false;
582169689Skan    }
583169689Skan}
584169689Skan
585169689Skan/* Return true if the next token from PARSER can start a type name,
586169689Skan   false otherwise.  */
587169689Skanstatic inline bool
588169689Skanc_parser_next_token_starts_typename (c_parser *parser)
589169689Skan{
590169689Skan  c_token *token = c_parser_peek_token (parser);
591169689Skan  return c_token_starts_typename (token);
592169689Skan}
593169689Skan
594169689Skan/* Return true if TOKEN can start declaration specifiers, false
595169689Skan   otherwise.  */
596169689Skanstatic bool
597169689Skanc_token_starts_declspecs (c_token *token)
598169689Skan{
599169689Skan  switch (token->type)
600169689Skan    {
601169689Skan    case CPP_NAME:
602169689Skan      switch (token->id_kind)
603169689Skan	{
604169689Skan	case C_ID_ID:
605169689Skan	  return false;
606169689Skan	case C_ID_TYPENAME:
607169689Skan	  return true;
608169689Skan	case C_ID_CLASSNAME:
609169689Skan	  gcc_assert (c_dialect_objc ());
610169689Skan	  return true;
611169689Skan	default:
612169689Skan	  gcc_unreachable ();
613169689Skan	}
614169689Skan    case CPP_KEYWORD:
615169689Skan      switch (token->keyword)
616169689Skan	{
617169689Skan	case RID_STATIC:
618169689Skan	case RID_EXTERN:
619169689Skan	case RID_REGISTER:
620169689Skan	case RID_TYPEDEF:
621169689Skan	case RID_INLINE:
622169689Skan	case RID_AUTO:
623169689Skan	case RID_THREAD:
624169689Skan	case RID_UNSIGNED:
625169689Skan	case RID_LONG:
626169689Skan	case RID_SHORT:
627169689Skan	case RID_SIGNED:
628169689Skan	case RID_COMPLEX:
629169689Skan	case RID_INT:
630169689Skan	case RID_CHAR:
631169689Skan	case RID_FLOAT:
632169689Skan	case RID_DOUBLE:
633169689Skan	case RID_VOID:
634169689Skan	case RID_DFLOAT32:
635169689Skan	case RID_DFLOAT64:
636169689Skan	case RID_DFLOAT128:
637169689Skan	case RID_BOOL:
638169689Skan	case RID_ENUM:
639169689Skan	case RID_STRUCT:
640169689Skan	case RID_UNION:
641169689Skan	case RID_TYPEOF:
642169689Skan	case RID_CONST:
643169689Skan	case RID_VOLATILE:
644169689Skan	case RID_RESTRICT:
645169689Skan	case RID_ATTRIBUTE:
646169689Skan	  return true;
647169689Skan	default:
648169689Skan	  return false;
649169689Skan	}
650169689Skan    case CPP_LESS:
651169689Skan      if (c_dialect_objc ())
652169689Skan	return true;
653169689Skan      return false;
654169689Skan    default:
655169689Skan      return false;
656169689Skan    }
657169689Skan}
658169689Skan
659169689Skan/* Return true if the next token from PARSER can start declaration
660169689Skan   specifiers, false otherwise.  */
661169689Skanstatic inline bool
662169689Skanc_parser_next_token_starts_declspecs (c_parser *parser)
663169689Skan{
664169689Skan  c_token *token = c_parser_peek_token (parser);
665261188Spfg  /* APPLE LOCAL begin radar 5277239 */
666261188Spfg  /* Yes, we can have CLASS.method to mean property-style dot-syntax
667261188Spfg     notation to call a class method (equiv to [CLASS meth]). */
668261188Spfg  return c_token_starts_declspecs (token)
669261188Spfg	 && (token->id_kind != C_ID_CLASSNAME
670261188Spfg	     || c_parser_peek_2nd_token (parser)->type != CPP_DOT);
671261188Spfg  /* APPLE LOCAL end radar 5277239 */
672169689Skan}
673169689Skan
674169689Skan/* Return a pointer to the next-but-one token from PARSER, reading it
675169689Skan   in if necessary.  The next token is already read in.  */
676169689Skan
677169689Skanstatic c_token *
678169689Skanc_parser_peek_2nd_token (c_parser *parser)
679169689Skan{
680169689Skan  if (parser->tokens_avail >= 2)
681169689Skan    return &parser->tokens[1];
682169689Skan  gcc_assert (parser->tokens_avail == 1);
683169689Skan  gcc_assert (parser->tokens[0].type != CPP_EOF);
684169689Skan  gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
685261188Spfg  /* APPLE LOCAL begin switch these two */
686169689Skan  parser->tokens_avail = 2;
687261188Spfg  /* APPLE LOCAL C* language (in 4.2 ae) */
688261188Spfg  c_lex_one_token (&parser->tokens[1], parser);
689261188Spfg  /* APPLE LOCAL end switch these two */
690169689Skan  return &parser->tokens[1];
691169689Skan}
692169689Skan
693169689Skan/* Consume the next token from PARSER.  */
694169689Skan
695169689Skanstatic void
696169689Skanc_parser_consume_token (c_parser *parser)
697169689Skan{
698169689Skan  gcc_assert (parser->tokens_avail >= 1);
699169689Skan  gcc_assert (parser->tokens[0].type != CPP_EOF);
700169689Skan  gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
701169689Skan  gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
702169689Skan  if (parser->tokens_avail == 2)
703169689Skan    parser->tokens[0] = parser->tokens[1];
704169689Skan  parser->tokens_avail--;
705169689Skan}
706169689Skan
707169689Skan/* Expect the current token to be a #pragma.  Consume it and remember
708169689Skan   that we've begun parsing a pragma.  */
709169689Skan
710169689Skanstatic void
711169689Skanc_parser_consume_pragma (c_parser *parser)
712169689Skan{
713169689Skan  gcc_assert (!parser->in_pragma);
714169689Skan  gcc_assert (parser->tokens_avail >= 1);
715169689Skan  gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
716169689Skan  if (parser->tokens_avail == 2)
717169689Skan    parser->tokens[0] = parser->tokens[1];
718169689Skan  parser->tokens_avail--;
719169689Skan  parser->in_pragma = true;
720169689Skan}
721169689Skan
722169689Skan/* Update the globals input_location and in_system_header from
723169689Skan   TOKEN.  */
724169689Skanstatic inline void
725169689Skanc_parser_set_source_position_from_token (c_token *token)
726169689Skan{
727169689Skan  if (token->type != CPP_EOF)
728169689Skan    {
729169689Skan      input_location = token->location;
730169689Skan      in_system_header = token->in_system_header;
731169689Skan    }
732169689Skan}
733169689Skan
734169689Skan/* Issue a diagnostic of the form
735169689Skan      FILE:LINE: MESSAGE before TOKEN
736169689Skan   where TOKEN is the next token in the input stream of PARSER.
737169689Skan   MESSAGE (specified by the caller) is usually of the form "expected
738169689Skan   OTHER-TOKEN".
739169689Skan
740169689Skan   Do not issue a diagnostic if still recovering from an error.
741169689Skan
742169689Skan   ??? This is taken from the C++ parser, but building up messages in
743169689Skan   this way is not i18n-friendly and some other approach should be
744169689Skan   used.  */
745169689Skan
746169689Skanstatic void
747169689Skanc_parser_error (c_parser *parser, const char *gmsgid)
748169689Skan{
749169689Skan  c_token *token = c_parser_peek_token (parser);
750169689Skan  if (parser->error)
751169689Skan    return;
752169689Skan  parser->error = true;
753169689Skan  if (!gmsgid)
754169689Skan    return;
755169689Skan  /* This diagnostic makes more sense if it is tagged to the line of
756169689Skan     the token we just peeked at.  */
757169689Skan  c_parser_set_source_position_from_token (token);
758169689Skan  c_parse_error (gmsgid,
759169689Skan		 /* Because c_parse_error does not understand
760169689Skan		    CPP_KEYWORD, keywords are treated like
761169689Skan		    identifiers.  */
762169689Skan		 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
763169689Skan		 token->value);
764169689Skan}
765169689Skan
766169689Skan/* If the next token is of the indicated TYPE, consume it.  Otherwise,
767169689Skan   issue the error MSGID.  If MSGID is NULL then a message has already
768169689Skan   been produced and no message will be produced this time.  Returns
769169689Skan   true if found, false otherwise.  */
770169689Skan
771169689Skanstatic bool
772169689Skanc_parser_require (c_parser *parser,
773169689Skan		  enum cpp_ttype type,
774169689Skan		  const char *msgid)
775169689Skan{
776169689Skan  if (c_parser_next_token_is (parser, type))
777169689Skan    {
778169689Skan      c_parser_consume_token (parser);
779169689Skan      return true;
780169689Skan    }
781169689Skan  else
782169689Skan    {
783169689Skan      c_parser_error (parser, msgid);
784169689Skan      return false;
785169689Skan    }
786169689Skan}
787169689Skan
788169689Skan/* If the next token is the indicated keyword, consume it.  Otherwise,
789169689Skan   issue the error MSGID.  Returns true if found, false otherwise.  */
790169689Skan
791169689Skanstatic bool
792169689Skanc_parser_require_keyword (c_parser *parser,
793169689Skan			  enum rid keyword,
794169689Skan			  const char *msgid)
795169689Skan{
796169689Skan  if (c_parser_next_token_is_keyword (parser, keyword))
797169689Skan    {
798169689Skan      c_parser_consume_token (parser);
799169689Skan      return true;
800169689Skan    }
801169689Skan  else
802169689Skan    {
803169689Skan      c_parser_error (parser, msgid);
804169689Skan      return false;
805169689Skan    }
806169689Skan}
807169689Skan
808169689Skan/* Like c_parser_require, except that tokens will be skipped until the
809169689Skan   desired token is found.  An error message is still produced if the
810169689Skan   next token is not as expected.  If MSGID is NULL then a message has
811169689Skan   already been produced and no message will be produced this
812169689Skan   time.  */
813169689Skan
814169689Skanstatic void
815169689Skanc_parser_skip_until_found (c_parser *parser,
816169689Skan			   enum cpp_ttype type,
817169689Skan			   const char *msgid)
818169689Skan{
819169689Skan  unsigned nesting_depth = 0;
820169689Skan
821169689Skan  if (c_parser_require (parser, type, msgid))
822169689Skan    return;
823169689Skan
824169689Skan  /* Skip tokens until the desired token is found.  */
825169689Skan  while (true)
826169689Skan    {
827169689Skan      /* Peek at the next token.  */
828169689Skan      c_token *token = c_parser_peek_token (parser);
829169689Skan      /* If we've reached the token we want, consume it and stop.  */
830169689Skan      if (token->type == type && !nesting_depth)
831169689Skan	{
832169689Skan	  c_parser_consume_token (parser);
833169689Skan	  break;
834169689Skan	}
835169689Skan
836169689Skan      /* If we've run out of tokens, stop.  */
837169689Skan      if (token->type == CPP_EOF)
838169689Skan	return;
839169689Skan      if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
840169689Skan	return;
841169689Skan      if (token->type == CPP_OPEN_BRACE
842169689Skan	  || token->type == CPP_OPEN_PAREN
843169689Skan	  || token->type == CPP_OPEN_SQUARE)
844169689Skan	++nesting_depth;
845169689Skan      else if (token->type == CPP_CLOSE_BRACE
846169689Skan	       || token->type == CPP_CLOSE_PAREN
847169689Skan	       || token->type == CPP_CLOSE_SQUARE)
848169689Skan	{
849169689Skan	  if (nesting_depth-- == 0)
850169689Skan	    break;
851169689Skan	}
852169689Skan      /* Consume this token.  */
853169689Skan      c_parser_consume_token (parser);
854169689Skan    }
855169689Skan  parser->error = false;
856169689Skan}
857169689Skan
858169689Skan/* Skip tokens until the end of a parameter is found, but do not
859169689Skan   consume the comma, semicolon or closing delimiter.  */
860169689Skan
861169689Skanstatic void
862169689Skanc_parser_skip_to_end_of_parameter (c_parser *parser)
863169689Skan{
864169689Skan  unsigned nesting_depth = 0;
865169689Skan
866169689Skan  while (true)
867169689Skan    {
868169689Skan      c_token *token = c_parser_peek_token (parser);
869169689Skan      if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
870169689Skan	  && !nesting_depth)
871169689Skan	break;
872169689Skan      /* If we've run out of tokens, stop.  */
873169689Skan      if (token->type == CPP_EOF)
874169689Skan	return;
875169689Skan      if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
876169689Skan	return;
877169689Skan      if (token->type == CPP_OPEN_BRACE
878169689Skan	  || token->type == CPP_OPEN_PAREN
879169689Skan	  || token->type == CPP_OPEN_SQUARE)
880169689Skan	++nesting_depth;
881169689Skan      else if (token->type == CPP_CLOSE_BRACE
882169689Skan	       || token->type == CPP_CLOSE_PAREN
883169689Skan	       || token->type == CPP_CLOSE_SQUARE)
884169689Skan	{
885169689Skan	  if (nesting_depth-- == 0)
886169689Skan	    break;
887169689Skan	}
888169689Skan      /* Consume this token.  */
889169689Skan      c_parser_consume_token (parser);
890169689Skan    }
891169689Skan  parser->error = false;
892169689Skan}
893169689Skan
894169689Skan/* Expect to be at the end of the pragma directive and consume an
895169689Skan   end of line marker.  */
896169689Skan
897169689Skanstatic void
898169689Skanc_parser_skip_to_pragma_eol (c_parser *parser)
899169689Skan{
900169689Skan  gcc_assert (parser->in_pragma);
901169689Skan  parser->in_pragma = false;
902169689Skan
903169689Skan  if (!c_parser_require (parser, CPP_PRAGMA_EOL, "expected end of line"))
904169689Skan    while (true)
905169689Skan      {
906169689Skan	c_token *token = c_parser_peek_token (parser);
907169689Skan	if (token->type == CPP_EOF)
908169689Skan	  break;
909169689Skan	if (token->type == CPP_PRAGMA_EOL)
910169689Skan	  {
911169689Skan	    c_parser_consume_token (parser);
912169689Skan	    break;
913169689Skan	  }
914169689Skan	c_parser_consume_token (parser);
915169689Skan      }
916169689Skan
917169689Skan  parser->error = false;
918169689Skan}
919169689Skan
920169689Skan/* Skip tokens until we have consumed an entire block, or until we
921169689Skan   have consumed a non-nested ';'.  */
922169689Skan
923169689Skanstatic void
924169689Skanc_parser_skip_to_end_of_block_or_statement (c_parser *parser)
925169689Skan{
926169689Skan  unsigned nesting_depth = 0;
927169689Skan  bool save_error = parser->error;
928169689Skan
929169689Skan  while (true)
930169689Skan    {
931169689Skan      c_token *token;
932169689Skan
933169689Skan      /* Peek at the next token.  */
934169689Skan      token = c_parser_peek_token (parser);
935169689Skan
936169689Skan      switch (token->type)
937169689Skan	{
938169689Skan	case CPP_EOF:
939169689Skan	  return;
940169689Skan
941169689Skan	case CPP_PRAGMA_EOL:
942169689Skan	  if (parser->in_pragma)
943169689Skan	    return;
944169689Skan	  break;
945169689Skan
946169689Skan	case CPP_SEMICOLON:
947169689Skan	  /* If the next token is a ';', we have reached the
948169689Skan	     end of the statement.  */
949169689Skan	  if (!nesting_depth)
950169689Skan	    {
951169689Skan	      /* Consume the ';'.  */
952169689Skan	      c_parser_consume_token (parser);
953169689Skan	      goto finished;
954169689Skan	    }
955169689Skan	  break;
956169689Skan
957169689Skan	case CPP_CLOSE_BRACE:
958169689Skan	  /* If the next token is a non-nested '}', then we have
959169689Skan	     reached the end of the current block.  */
960169689Skan	  if (nesting_depth == 0 || --nesting_depth == 0)
961169689Skan	    {
962169689Skan	      c_parser_consume_token (parser);
963169689Skan	      goto finished;
964169689Skan	    }
965169689Skan	  break;
966169689Skan
967169689Skan	case CPP_OPEN_BRACE:
968169689Skan	  /* If it the next token is a '{', then we are entering a new
969169689Skan	     block.  Consume the entire block.  */
970169689Skan	  ++nesting_depth;
971169689Skan	  break;
972169689Skan
973169689Skan	case CPP_PRAGMA:
974169689Skan	  /* If we see a pragma, consume the whole thing at once.  We
975169689Skan	     have some safeguards against consuming pragmas willy-nilly.
976169689Skan	     Normally, we'd expect to be here with parser->error set,
977169689Skan	     which disables these safeguards.  But it's possible to get
978169689Skan	     here for secondary error recovery, after parser->error has
979169689Skan	     been cleared.  */
980169689Skan	  c_parser_consume_pragma (parser);
981169689Skan	  c_parser_skip_to_pragma_eol (parser);
982169689Skan	  parser->error = save_error;
983169689Skan	  continue;
984169689Skan
985169689Skan	default:
986169689Skan	  break;
987169689Skan	}
988169689Skan
989169689Skan      c_parser_consume_token (parser);
990169689Skan    }
991169689Skan
992169689Skan finished:
993169689Skan  parser->error = false;
994169689Skan}
995169689Skan
996169689Skan/* Save the warning flags which are controlled by __extension__.  */
997169689Skan
998169689Skanstatic inline int
999169689Skandisable_extension_diagnostics (void)
1000169689Skan{
1001169689Skan  int ret = (pedantic
1002169689Skan	     | (warn_pointer_arith << 1)
1003169689Skan	     | (warn_traditional << 2)
1004169689Skan	     | (flag_iso << 3));
1005169689Skan  pedantic = 0;
1006169689Skan  warn_pointer_arith = 0;
1007169689Skan  warn_traditional = 0;
1008169689Skan  flag_iso = 0;
1009169689Skan  return ret;
1010169689Skan}
1011169689Skan
1012169689Skan/* Restore the warning flags which are controlled by __extension__.
1013169689Skan   FLAGS is the return value from disable_extension_diagnostics.  */
1014169689Skan
1015169689Skanstatic inline void
1016169689Skanrestore_extension_diagnostics (int flags)
1017169689Skan{
1018169689Skan  pedantic = flags & 1;
1019169689Skan  warn_pointer_arith = (flags >> 1) & 1;
1020169689Skan  warn_traditional = (flags >> 2) & 1;
1021169689Skan  flag_iso = (flags >> 3) & 1;
1022169689Skan}
1023169689Skan
1024169689Skan/* Possibly kinds of declarator to parse.  */
1025169689Skantypedef enum c_dtr_syn {
1026169689Skan  /* A normal declarator with an identifier.  */
1027169689Skan  C_DTR_NORMAL,
1028169689Skan  /* An abstract declarator (maybe empty).  */
1029169689Skan  C_DTR_ABSTRACT,
1030261188Spfg  /* APPLE LOCAL begin blocks 6339747 */
1031261188Spfg  /* A block declarator (maybe empty).  */
1032261188Spfg  C_DTR_BLOCK,
1033261188Spfg  /* APPLE LOCAL end blocks 6339747 */
1034169689Skan  /* A parameter declarator: may be either, but after a type name does
1035169689Skan     not redeclare a typedef name as an identifier if it can
1036169689Skan     alternatively be interpreted as a typedef name; see DR#009,
1037169689Skan     applied in C90 TC1, omitted from C99 and reapplied in C99 TC2
1038169689Skan     following DR#249.  For example, given a typedef T, "int T" and
1039169689Skan     "int *T" are valid parameter declarations redeclaring T, while
1040169689Skan     "int (T)" and "int * (T)" and "int (T[])" and "int (T (int))" are
1041169689Skan     abstract declarators rather than involving redundant parentheses;
1042169689Skan     the same applies with attributes inside the parentheses before
1043169689Skan     "T".  */
1044169689Skan  C_DTR_PARM
1045169689Skan} c_dtr_syn;
1046169689Skan
1047169689Skanstatic void c_parser_external_declaration (c_parser *);
1048169689Skanstatic void c_parser_asm_definition (c_parser *);
1049261188Spfg/* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
1050261188Spfgstatic void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, bool, tree*);
1051169689Skanstatic void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
1052169689Skan				bool);
1053169689Skanstatic struct c_typespec c_parser_enum_specifier (c_parser *);
1054169689Skanstatic struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1055169689Skanstatic tree c_parser_struct_declaration (c_parser *);
1056169689Skanstatic struct c_typespec c_parser_typeof_specifier (c_parser *);
1057169689Skanstatic struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn,
1058169689Skan						 bool *);
1059169689Skanstatic struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1060169689Skan							c_dtr_syn, bool *);
1061169689Skanstatic struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1062169689Skan							      bool,
1063169689Skan							      struct c_declarator *);
1064169689Skanstatic struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree);
1065169689Skanstatic struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree);
1066169689Skanstatic struct c_parm *c_parser_parameter_declaration (c_parser *, tree);
1067169689Skanstatic tree c_parser_simple_asm_expr (c_parser *);
1068169689Skanstatic tree c_parser_attributes (c_parser *);
1069169689Skanstatic struct c_type_name *c_parser_type_name (c_parser *);
1070169689Skanstatic struct c_expr c_parser_initializer (c_parser *);
1071169689Skanstatic struct c_expr c_parser_braced_init (c_parser *, tree, bool);
1072169689Skanstatic void c_parser_initelt (c_parser *);
1073169689Skanstatic void c_parser_initval (c_parser *, struct c_expr *);
1074169689Skanstatic tree c_parser_compound_statement (c_parser *);
1075169689Skanstatic void c_parser_compound_statement_nostart (c_parser *);
1076169689Skanstatic void c_parser_label (c_parser *);
1077169689Skanstatic void c_parser_statement (c_parser *);
1078169689Skanstatic void c_parser_statement_after_labels (c_parser *);
1079169689Skanstatic void c_parser_if_statement (c_parser *);
1080169689Skanstatic void c_parser_switch_statement (c_parser *);
1081169689Skanstatic void c_parser_while_statement (c_parser *);
1082169689Skanstatic void c_parser_do_statement (c_parser *);
1083169689Skanstatic void c_parser_for_statement (c_parser *);
1084169689Skanstatic tree c_parser_asm_statement (c_parser *);
1085261188Spfg/* APPLE LOCAL begin radar 5732232 - blocks (C++ ca) */
1086261188Spfgstatic tree c_parser_block_literal_expr (c_parser *);
1087261188Spfg/* APPLE LOCAL end radar 5732232 - blocks (C++ ca) */
1088169689Skanstatic tree c_parser_asm_operands (c_parser *, bool);
1089169689Skanstatic tree c_parser_asm_clobbers (c_parser *);
1090169689Skanstatic struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *);
1091169689Skanstatic struct c_expr c_parser_conditional_expression (c_parser *,
1092169689Skan						      struct c_expr *);
1093169689Skanstatic struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *);
1094169689Skanstatic struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1095169689Skanstatic struct c_expr c_parser_unary_expression (c_parser *);
1096169689Skanstatic struct c_expr c_parser_sizeof_expression (c_parser *);
1097169689Skanstatic struct c_expr c_parser_alignof_expression (c_parser *);
1098169689Skanstatic struct c_expr c_parser_postfix_expression (c_parser *);
1099169689Skanstatic struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1100169689Skan								   struct c_type_name *);
1101169689Skanstatic struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1102169689Skan								struct c_expr);
1103169689Skanstatic struct c_expr c_parser_expression (c_parser *);
1104169689Skanstatic struct c_expr c_parser_expression_conv (c_parser *);
1105169689Skanstatic tree c_parser_expr_list (c_parser *, bool);
1106169689Skanstatic void c_parser_omp_construct (c_parser *);
1107169689Skanstatic void c_parser_omp_threadprivate (c_parser *);
1108169689Skanstatic void c_parser_omp_barrier (c_parser *);
1109169689Skanstatic void c_parser_omp_flush (c_parser *);
1110169689Skan
1111169689Skanenum pragma_context { pragma_external, pragma_stmt, pragma_compound };
1112169689Skanstatic bool c_parser_pragma (c_parser *, enum pragma_context);
1113169689Skan
1114169689Skan/* These Objective-C parser functions are only ever called when
1115169689Skan   compiling Objective-C.  */
1116261188Spfg/* APPLE LOCAL radar 4548636 - class attributes. */
1117261188Spfgstatic void c_parser_objc_class_definition (c_parser *, tree);
1118169689Skanstatic void c_parser_objc_class_instance_variables (c_parser *);
1119169689Skanstatic void c_parser_objc_class_declaration (c_parser *);
1120169689Skanstatic void c_parser_objc_alias_declaration (c_parser *);
1121261188Spfg/* APPLE LOCAL radar 4947311 - protocol attributes */
1122261188Spfgstatic void c_parser_objc_protocol_definition (c_parser *, tree);
1123169689Skanstatic enum tree_code c_parser_objc_method_type (c_parser *);
1124169689Skanstatic void c_parser_objc_method_definition (c_parser *);
1125261188Spfg/* APPLE LOCAL C* property (Radar 4436866) (in 4.2 b) */
1126261188Spfgstatic void c_parser_objc_interfacedecllist (c_parser *);
1127261188Spfg/* APPLE LOCAL C* property (Radar 4436866) (in 4.2 x) */
1128261188Spfgstatic void c_parser_objc_property_declaration (c_parser *);
1129169689Skanstatic void c_parser_objc_methodproto (c_parser *);
1130169689Skanstatic tree c_parser_objc_method_decl (c_parser *);
1131169689Skanstatic tree c_parser_objc_type_name (c_parser *);
1132169689Skanstatic tree c_parser_objc_protocol_refs (c_parser *);
1133169689Skanstatic void c_parser_objc_try_catch_statement (c_parser *);
1134169689Skanstatic void c_parser_objc_synchronized_statement (c_parser *);
1135169689Skanstatic tree c_parser_objc_selector (c_parser *);
1136169689Skanstatic tree c_parser_objc_selector_arg (c_parser *);
1137169689Skanstatic tree c_parser_objc_receiver (c_parser *);
1138169689Skanstatic tree c_parser_objc_message_args (c_parser *);
1139169689Skanstatic tree c_parser_objc_keywordexpr (c_parser *);
1140169689Skan
1141169689Skan/* Parse a translation unit (C90 6.7, C99 6.9).
1142169689Skan
1143169689Skan   translation-unit:
1144169689Skan     external-declarations
1145169689Skan
1146169689Skan   external-declarations:
1147169689Skan     external-declaration
1148169689Skan     external-declarations external-declaration
1149169689Skan
1150169689Skan   GNU extensions:
1151169689Skan
1152169689Skan   translation-unit:
1153169689Skan     empty
1154169689Skan*/
1155169689Skan
1156169689Skanstatic void
1157169689Skanc_parser_translation_unit (c_parser *parser)
1158169689Skan{
1159169689Skan  if (c_parser_next_token_is (parser, CPP_EOF))
1160169689Skan    {
1161169689Skan      if (pedantic)
1162169689Skan	pedwarn ("ISO C forbids an empty source file");
1163169689Skan    }
1164169689Skan  else
1165169689Skan    {
1166169689Skan      void *obstack_position = obstack_alloc (&parser_obstack, 0);
1167169689Skan      do
1168169689Skan	{
1169169689Skan	  ggc_collect ();
1170169689Skan	  c_parser_external_declaration (parser);
1171169689Skan	  obstack_free (&parser_obstack, obstack_position);
1172169689Skan	}
1173169689Skan      while (c_parser_next_token_is_not (parser, CPP_EOF));
1174169689Skan    }
1175169689Skan}
1176169689Skan
1177169689Skan/* Parse an external declaration (C90 6.7, C99 6.9).
1178169689Skan
1179169689Skan   external-declaration:
1180169689Skan     function-definition
1181169689Skan     declaration
1182169689Skan
1183169689Skan   GNU extensions:
1184169689Skan
1185169689Skan   external-declaration:
1186169689Skan     asm-definition
1187169689Skan     ;
1188169689Skan     __extension__ external-declaration
1189169689Skan
1190169689Skan   Objective-C:
1191169689Skan
1192169689Skan   external-declaration:
1193169689Skan     objc-class-definition
1194169689Skan     objc-class-declaration
1195169689Skan     objc-alias-declaration
1196169689Skan     objc-protocol-definition
1197169689Skan     objc-method-definition
1198169689Skan     @end
1199169689Skan*/
1200169689Skan
1201169689Skanstatic void
1202169689Skanc_parser_external_declaration (c_parser *parser)
1203169689Skan{
1204169689Skan  int ext;
1205169689Skan  switch (c_parser_peek_token (parser)->type)
1206169689Skan    {
1207169689Skan    case CPP_KEYWORD:
1208169689Skan      switch (c_parser_peek_token (parser)->keyword)
1209169689Skan	{
1210169689Skan	case RID_EXTENSION:
1211169689Skan	  ext = disable_extension_diagnostics ();
1212169689Skan	  c_parser_consume_token (parser);
1213169689Skan	  c_parser_external_declaration (parser);
1214169689Skan	  restore_extension_diagnostics (ext);
1215169689Skan	  break;
1216169689Skan	case RID_ASM:
1217169689Skan	  c_parser_asm_definition (parser);
1218169689Skan	  break;
1219169689Skan	case RID_AT_INTERFACE:
1220169689Skan	case RID_AT_IMPLEMENTATION:
1221169689Skan	  gcc_assert (c_dialect_objc ());
1222261188Spfg	  /* APPLE LOCAL radar 4548636 - class attributes. */
1223261188Spfg	  c_parser_objc_class_definition (parser, NULL_TREE);
1224169689Skan	  break;
1225169689Skan	case RID_AT_CLASS:
1226169689Skan	  gcc_assert (c_dialect_objc ());
1227169689Skan	  c_parser_objc_class_declaration (parser);
1228169689Skan	  break;
1229169689Skan	case RID_AT_ALIAS:
1230169689Skan	  gcc_assert (c_dialect_objc ());
1231169689Skan	  c_parser_objc_alias_declaration (parser);
1232169689Skan	  break;
1233169689Skan	case RID_AT_PROTOCOL:
1234169689Skan	  gcc_assert (c_dialect_objc ());
1235261188Spfg	  /* APPLE LOCAL begin radar 4947311 - protocol attributes */
1236261188Spfg	  c_parser_objc_protocol_definition (parser, NULL_TREE);
1237169689Skan	  break;
1238261188Spfg	  /* APPLE LOCAL end radar 4947311 - protocol attributes */
1239261188Spfg	  /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 x) */
1240261188Spfg	case RID_AT_PROPERTY:
1241261188Spfg	  c_parser_objc_property_declaration (parser);
1242261188Spfg	  break;
1243261188Spfg	  /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 x) */
1244169689Skan	case RID_AT_END:
1245169689Skan	  gcc_assert (c_dialect_objc ());
1246169689Skan	  c_parser_consume_token (parser);
1247169689Skan	  objc_finish_implementation ();
1248169689Skan	  break;
1249169689Skan	default:
1250169689Skan	  goto decl_or_fndef;
1251169689Skan	}
1252169689Skan      break;
1253169689Skan    case CPP_SEMICOLON:
1254169689Skan      if (pedantic)
1255169689Skan	pedwarn ("ISO C does not allow extra %<;%> outside of a function");
1256169689Skan      c_parser_consume_token (parser);
1257169689Skan      break;
1258169689Skan    case CPP_PRAGMA:
1259169689Skan      c_parser_pragma (parser, pragma_external);
1260169689Skan      break;
1261169689Skan    case CPP_PLUS:
1262169689Skan    case CPP_MINUS:
1263169689Skan      if (c_dialect_objc ())
1264169689Skan	{
1265169689Skan	  c_parser_objc_method_definition (parser);
1266169689Skan	  break;
1267169689Skan	}
1268169689Skan      /* Else fall through, and yield a syntax error trying to parse
1269169689Skan	 as a declaration or function definition.  */
1270169689Skan    default:
1271169689Skan    decl_or_fndef:
1272169689Skan      /* A declaration or a function definition.  We can only tell
1273169689Skan	 which after parsing the declaration specifiers, if any, and
1274169689Skan	 the first declarator.  */
1275261188Spfg      /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
1276261188Spfg      c_parser_declaration_or_fndef (parser, true, true, false, true, NULL);
1277169689Skan      break;
1278169689Skan    }
1279169689Skan}
1280169689Skan
1281169689Skan
1282169689Skan/* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1283169689Skan   6.7, 6.9.1).  If FNDEF_OK is true, a function definition is
1284169689Skan   accepted; otherwise (old-style parameter declarations) only other
1285169689Skan   declarations are accepted.  If NESTED is true, we are inside a
1286169689Skan   function or parsing old-style parameter declarations; any functions
1287169689Skan   encountered are nested functions and declaration specifiers are
1288169689Skan   required; otherwise we are at top level and functions are normal
1289169689Skan   functions and declaration specifiers may be optional.  If EMPTY_OK
1290169689Skan   is true, empty declarations are OK (subject to all other
1291169689Skan   constraints); otherwise (old-style parameter declarations) they are
1292169689Skan   diagnosed.  If START_ATTR_OK is true, the declaration specifiers
1293169689Skan   may start with attributes; otherwise they may not.
1294169689Skan
1295169689Skan   declaration:
1296169689Skan     declaration-specifiers init-declarator-list[opt] ;
1297169689Skan
1298169689Skan   function-definition:
1299169689Skan     declaration-specifiers[opt] declarator declaration-list[opt]
1300169689Skan       compound-statement
1301169689Skan
1302169689Skan   declaration-list:
1303169689Skan     declaration
1304169689Skan     declaration-list declaration
1305169689Skan
1306169689Skan   init-declarator-list:
1307169689Skan     init-declarator
1308169689Skan     init-declarator-list , init-declarator
1309169689Skan
1310169689Skan   init-declarator:
1311169689Skan     declarator simple-asm-expr[opt] attributes[opt]
1312169689Skan     declarator simple-asm-expr[opt] attributes[opt] = initializer
1313169689Skan
1314169689Skan   GNU extensions:
1315169689Skan
1316169689Skan   nested-function-definition:
1317169689Skan     declaration-specifiers declarator declaration-list[opt]
1318169689Skan       compound-statement
1319169689Skan
1320169689Skan   The simple-asm-expr and attributes are GNU extensions.
1321169689Skan
1322169689Skan   This function does not handle __extension__; that is handled in its
1323169689Skan   callers.  ??? Following the old parser, __extension__ may start
1324169689Skan   external declarations, declarations in functions and declarations
1325169689Skan   at the start of "for" loops, but not old-style parameter
1326169689Skan   declarations.
1327169689Skan
1328169689Skan   C99 requires declaration specifiers in a function definition; the
1329169689Skan   absence is diagnosed through the diagnosis of implicit int.  In GNU
1330169689Skan   C we also allow but diagnose declarations without declaration
1331169689Skan   specifiers, but only at top level (elsewhere they conflict with
1332169689Skan   other syntax).
1333169689Skan
1334169689Skan   OpenMP:
1335169689Skan
1336169689Skan   declaration:
1337169689Skan     threadprivate-directive  */
1338169689Skan
1339169689Skanstatic void
1340169689Skanc_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
1341261188Spfg			       /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
1342261188Spfg			       bool nested, bool start_attr_ok, tree *foreach_elem)
1343169689Skan{
1344169689Skan  struct c_declspecs *specs;
1345169689Skan  tree prefix_attrs;
1346169689Skan  tree all_prefix_attrs;
1347169689Skan  bool diagnosed_no_specs = false;
1348169689Skan
1349169689Skan  specs = build_null_declspecs ();
1350169689Skan  c_parser_declspecs (parser, specs, true, true, start_attr_ok);
1351169689Skan  if (parser->error)
1352169689Skan    {
1353169689Skan      c_parser_skip_to_end_of_block_or_statement (parser);
1354169689Skan      return;
1355169689Skan    }
1356169689Skan  if (nested && !specs->declspecs_seen_p)
1357169689Skan    {
1358169689Skan      c_parser_error (parser, "expected declaration specifiers");
1359169689Skan      c_parser_skip_to_end_of_block_or_statement (parser);
1360169689Skan      return;
1361169689Skan    }
1362169689Skan  finish_declspecs (specs);
1363169689Skan  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1364169689Skan    {
1365169689Skan      if (empty_ok)
1366169689Skan	shadow_tag (specs);
1367169689Skan      else
1368169689Skan	{
1369169689Skan	  shadow_tag_warned (specs, 1);
1370169689Skan	  pedwarn ("empty declaration");
1371169689Skan	}
1372169689Skan      c_parser_consume_token (parser);
1373169689Skan      return;
1374169689Skan    }
1375261188Spfg  /* APPLE LOCAL begin radar 4548636 - class attributes. */
1376261188Spfg  else if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE)
1377261188Spfg	   || c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
1378261188Spfg    {
1379261188Spfg      gcc_assert (c_dialect_objc ());
1380261188Spfg      if (!specs->declspecs_seen_p || specs->attrs == NULL_TREE
1381261188Spfg	  || specs->type_seen_p || specs->non_sc_seen_p)
1382261188Spfg	c_parser_error (parser, "no type or storage class may be specified here");
1383261188Spfg      c_parser_objc_class_definition (parser, specs->attrs);
1384261188Spfg      return;
1385261188Spfg    }
1386261188Spfg  /* APPLE LOCAL end radar 4548636 - class attributes. */
1387261188Spfg  /* APPLE LOCAL begin radar 4947311 - protocol attributes */
1388261188Spfg  else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL))
1389261188Spfg    {
1390261188Spfg      gcc_assert (c_dialect_objc ());
1391261188Spfg      if (!specs->declspecs_seen_p || specs->attrs == NULL_TREE
1392261188Spfg	  || specs->type_seen_p || specs->non_sc_seen_p)
1393261188Spfg	c_parser_error (parser, "no type or storage class may be specified here");
1394261188Spfg      c_parser_objc_protocol_definition (parser, specs->attrs);
1395261188Spfg      return;
1396261188Spfg    }
1397261188Spfg  /* APPLE LOCAL end radar 4947311 - protocol attributes */
1398169689Skan  pending_xref_error ();
1399169689Skan  prefix_attrs = specs->attrs;
1400169689Skan  all_prefix_attrs = prefix_attrs;
1401169689Skan  specs->attrs = NULL_TREE;
1402169689Skan  while (true)
1403169689Skan    {
1404169689Skan      struct c_declarator *declarator;
1405169689Skan      bool dummy = false;
1406169689Skan      tree fnbody;
1407169689Skan      /* Declaring either one or more declarators (in which case we
1408169689Skan	 should diagnose if there were no declaration specifiers) or a
1409169689Skan	 function definition (in which case the diagnostic for
1410169689Skan	 implicit int suffices).  */
1411169689Skan      declarator = c_parser_declarator (parser, specs->type_seen_p,
1412169689Skan					C_DTR_NORMAL, &dummy);
1413169689Skan      if (declarator == NULL)
1414169689Skan	{
1415169689Skan	  c_parser_skip_to_end_of_block_or_statement (parser);
1416169689Skan	  return;
1417169689Skan	}
1418169689Skan      if (c_parser_next_token_is (parser, CPP_EQ)
1419169689Skan	  || c_parser_next_token_is (parser, CPP_COMMA)
1420169689Skan	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
1421169689Skan	  || c_parser_next_token_is_keyword (parser, RID_ASM)
1422261188Spfg	  /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
1423261188Spfg	  || c_parser_next_token_is_keyword (parser, RID_IN)
1424169689Skan	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
1425169689Skan	{
1426169689Skan	  tree asm_name = NULL_TREE;
1427169689Skan	  tree postfix_attrs = NULL_TREE;
1428169689Skan	  if (!diagnosed_no_specs && !specs->declspecs_seen_p)
1429169689Skan	    {
1430169689Skan	      diagnosed_no_specs = true;
1431169689Skan	      pedwarn ("data definition has no type or storage class");
1432169689Skan	    }
1433169689Skan	  /* Having seen a data definition, there cannot now be a
1434169689Skan	     function definition.  */
1435169689Skan	  fndef_ok = false;
1436169689Skan	  if (c_parser_next_token_is_keyword (parser, RID_ASM))
1437169689Skan	    asm_name = c_parser_simple_asm_expr (parser);
1438169689Skan	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
1439169689Skan	    postfix_attrs = c_parser_attributes (parser);
1440261188Spfg	  /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */
1441261188Spfg	  if (c_parser_next_token_is_keyword (parser, RID_IN))
1442261188Spfg	    {
1443261188Spfg	      gcc_assert (foreach_elem);
1444261188Spfg	      *foreach_elem = start_decl (declarator, specs, true,
1445261188Spfg					  chainon (postfix_attrs, all_prefix_attrs));
1446261188Spfg	      if (!*foreach_elem)
1447261188Spfg		*foreach_elem = error_mark_node;
1448261188Spfg	      start_init (*foreach_elem, asm_name, global_bindings_p ());
1449261188Spfg	      return;
1450261188Spfg	    }
1451261188Spfg	  /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */
1452169689Skan	  if (c_parser_next_token_is (parser, CPP_EQ))
1453169689Skan	    {
1454169689Skan	      tree d;
1455169689Skan	      struct c_expr init;
1456169689Skan	      c_parser_consume_token (parser);
1457169689Skan	      /* The declaration of the variable is in effect while
1458169689Skan		 its initializer is parsed.  */
1459169689Skan	      d = start_decl (declarator, specs, true,
1460169689Skan			      chainon (postfix_attrs, all_prefix_attrs));
1461169689Skan	      if (!d)
1462169689Skan		d = error_mark_node;
1463169689Skan	      start_init (d, asm_name, global_bindings_p ());
1464169689Skan	      init = c_parser_initializer (parser);
1465169689Skan	      finish_init ();
1466169689Skan	      if (d != error_mark_node)
1467169689Skan		{
1468169689Skan		  maybe_warn_string_init (TREE_TYPE (d), init);
1469169689Skan		  finish_decl (d, init.value, asm_name);
1470169689Skan		}
1471169689Skan	    }
1472169689Skan	  else
1473169689Skan	    {
1474169689Skan	      tree d = start_decl (declarator, specs, false,
1475169689Skan				   chainon (postfix_attrs,
1476169689Skan					    all_prefix_attrs));
1477169689Skan	      if (d)
1478169689Skan		finish_decl (d, NULL_TREE, asm_name);
1479169689Skan	    }
1480169689Skan	  if (c_parser_next_token_is (parser, CPP_COMMA))
1481169689Skan	    {
1482169689Skan	      c_parser_consume_token (parser);
1483169689Skan	      if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
1484169689Skan		all_prefix_attrs = chainon (c_parser_attributes (parser),
1485169689Skan					    prefix_attrs);
1486169689Skan	      else
1487169689Skan		all_prefix_attrs = prefix_attrs;
1488169689Skan	      continue;
1489169689Skan	    }
1490169689Skan	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1491169689Skan	    {
1492169689Skan	      c_parser_consume_token (parser);
1493169689Skan	      return;
1494169689Skan	    }
1495169689Skan	  else
1496169689Skan	    {
1497169689Skan	      c_parser_error (parser, "expected %<,%> or %<;%>");
1498169689Skan	      c_parser_skip_to_end_of_block_or_statement (parser);
1499169689Skan	      return;
1500169689Skan	    }
1501169689Skan	}
1502169689Skan      else if (!fndef_ok)
1503169689Skan	{
1504169689Skan	  c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
1505169689Skan			  "%<asm%> or %<__attribute__%>");
1506169689Skan	  c_parser_skip_to_end_of_block_or_statement (parser);
1507169689Skan	  return;
1508169689Skan	}
1509169689Skan      /* Function definition (nested or otherwise).  */
1510169689Skan      if (nested)
1511169689Skan	{
1512261188Spfg	   /* APPLE LOCAL begin radar 5985368 */
1513261188Spfg	   if (declarator->declarator && declarator->declarator->kind == cdk_block_pointer)
1514261188Spfg	     error ("bad definition of a block");
1515261188Spfg	  else if (pedantic)
1516261188Spfg	   /* APPLE LOCAL end radar 5985368 */
1517169689Skan	    pedwarn ("ISO C forbids nested functions");
1518261188Spfg	  /* APPLE LOCAL begin nested functions 4258406 4357979 (in 4.2 m) */
1519261188Spfg	  else if (flag_nested_functions == 0)
1520261188Spfg	    error ("nested functions are disabled, use -fnested-functions to re-enable");
1521261188Spfg	  /* APPLE LOCAL end nested functions 4258406 4357979 (in 4.2 m) */
1522261188Spfg
1523169689Skan	  push_function_context ();
1524169689Skan	}
1525169689Skan      if (!start_function (specs, declarator, all_prefix_attrs))
1526169689Skan	{
1527169689Skan	  /* This can appear in many cases looking nothing like a
1528169689Skan	     function definition, so we don't give a more specific
1529169689Skan	     error suggesting there was one.  */
1530169689Skan	  c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
1531169689Skan			  "or %<__attribute__%>");
1532169689Skan	  if (nested)
1533169689Skan	    pop_function_context ();
1534169689Skan	  break;
1535169689Skan	}
1536169689Skan      /* Parse old-style parameter declarations.  ??? Attributes are
1537169689Skan	 not allowed to start declaration specifiers here because of a
1538169689Skan	 syntax conflict between a function declaration with attribute
1539169689Skan	 suffix and a function definition with an attribute prefix on
1540169689Skan	 first old-style parameter declaration.  Following the old
1541169689Skan	 parser, they are not accepted on subsequent old-style
1542169689Skan	 parameter declarations either.  However, there is no
1543169689Skan	 ambiguity after the first declaration, nor indeed on the
1544169689Skan	 first as long as we don't allow postfix attributes after a
1545169689Skan	 declarator with a nonempty identifier list in a definition;
1546169689Skan	 and postfix attributes have never been accepted here in
1547169689Skan	 function definitions either.  */
1548169689Skan      while (c_parser_next_token_is_not (parser, CPP_EOF)
1549169689Skan	     && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
1550261188Spfg	/* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
1551261188Spfg	c_parser_declaration_or_fndef (parser, false, false, true, false, NULL);
1552169689Skan      DECL_SOURCE_LOCATION (current_function_decl)
1553169689Skan	= c_parser_peek_token (parser)->location;
1554169689Skan      store_parm_decls ();
1555169689Skan      fnbody = c_parser_compound_statement (parser);
1556169689Skan      if (nested)
1557169689Skan	{
1558169689Skan	  tree decl = current_function_decl;
1559169689Skan	  add_stmt (fnbody);
1560169689Skan	  finish_function ();
1561169689Skan	  pop_function_context ();
1562169689Skan	  add_stmt (build_stmt (DECL_EXPR, decl));
1563169689Skan	}
1564169689Skan      else
1565169689Skan	{
1566169689Skan	  add_stmt (fnbody);
1567169689Skan	  finish_function ();
1568169689Skan	}
1569169689Skan      break;
1570169689Skan    }
1571169689Skan}
1572169689Skan
1573261188Spfgstatic tree
1574261188Spfgfinish_parse_foreach_header (c_parser *parser, tree foreach_elem_selector)
1575261188Spfg{
1576261188Spfg  tree res;
1577261188Spfg  int save_flag_isoc99 = flag_isoc99;
1578261188Spfg  gcc_assert (foreach_elem_selector);
1579261188Spfg  /* Consume 'in' keyword */
1580261188Spfg  c_parser_consume_token (parser);
1581261188Spfg  res = build_tree_list (foreach_elem_selector, c_parser_initializer (parser).value);
1582261188Spfg  finish_init ();
1583261188Spfg  flag_isoc99 = 1;
1584261188Spfg  check_for_loop_decls ();
1585261188Spfg  flag_isoc99 = save_flag_isoc99;
1586261188Spfg  return res;
1587261188Spfg}
1588261188Spfg/* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */
1589261188Spfg
1590169689Skan/* Parse an asm-definition (asm() outside a function body).  This is a
1591169689Skan   GNU extension.
1592169689Skan
1593169689Skan   asm-definition:
1594169689Skan     simple-asm-expr ;
1595169689Skan*/
1596169689Skan
1597169689Skanstatic void
1598169689Skanc_parser_asm_definition (c_parser *parser)
1599169689Skan{
1600169689Skan  tree asm_str = c_parser_simple_asm_expr (parser);
1601169689Skan  if (asm_str)
1602169689Skan    cgraph_add_asm_node (asm_str);
1603169689Skan  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
1604169689Skan}
1605169689Skan
1606169689Skan/* Parse some declaration specifiers (possibly none) (C90 6.5, C99
1607169689Skan   6.7), adding them to SPECS (which may already include some).
1608169689Skan   Storage class specifiers are accepted iff SCSPEC_OK; type
1609169689Skan   specifiers are accepted iff TYPESPEC_OK; attributes are accepted at
1610169689Skan   the start iff START_ATTR_OK.
1611169689Skan
1612169689Skan   declaration-specifiers:
1613169689Skan     storage-class-specifier declaration-specifiers[opt]
1614169689Skan     type-specifier declaration-specifiers[opt]
1615169689Skan     type-qualifier declaration-specifiers[opt]
1616169689Skan     function-specifier declaration-specifiers[opt]
1617169689Skan
1618169689Skan   Function specifiers (inline) are from C99, and are currently
1619169689Skan   handled as storage class specifiers, as is __thread.
1620169689Skan
1621169689Skan   C90 6.5.1, C99 6.7.1:
1622169689Skan   storage-class-specifier:
1623169689Skan     typedef
1624169689Skan     extern
1625169689Skan     static
1626169689Skan     auto
1627169689Skan     register
1628169689Skan
1629169689Skan   C99 6.7.4:
1630169689Skan   function-specifier:
1631169689Skan     inline
1632169689Skan
1633169689Skan   C90 6.5.2, C99 6.7.2:
1634169689Skan   type-specifier:
1635169689Skan     void
1636169689Skan     char
1637169689Skan     short
1638169689Skan     int
1639169689Skan     long
1640169689Skan     float
1641169689Skan     double
1642169689Skan     signed
1643169689Skan     unsigned
1644169689Skan     _Bool
1645169689Skan     _Complex
1646169689Skan     [_Imaginary removed in C99 TC2]
1647169689Skan     struct-or-union-specifier
1648169689Skan     enum-specifier
1649169689Skan     typedef-name
1650169689Skan
1651169689Skan   (_Bool and _Complex are new in C99.)
1652169689Skan
1653169689Skan   C90 6.5.3, C99 6.7.3:
1654169689Skan
1655169689Skan   type-qualifier:
1656169689Skan     const
1657169689Skan     restrict
1658169689Skan     volatile
1659169689Skan
1660169689Skan   (restrict is new in C99.)
1661169689Skan
1662169689Skan   GNU extensions:
1663169689Skan
1664169689Skan   declaration-specifiers:
1665169689Skan     attributes declaration-specifiers[opt]
1666169689Skan
1667169689Skan   storage-class-specifier:
1668169689Skan     __thread
1669169689Skan
1670169689Skan   type-specifier:
1671169689Skan     typeof-specifier
1672169689Skan     _Decimal32
1673169689Skan     _Decimal64
1674169689Skan     _Decimal128
1675169689Skan
1676169689Skan   Objective-C:
1677169689Skan
1678169689Skan   type-specifier:
1679169689Skan     class-name objc-protocol-refs[opt]
1680169689Skan     typedef-name objc-protocol-refs
1681169689Skan     objc-protocol-refs
1682169689Skan*/
1683169689Skan
1684169689Skanstatic void
1685169689Skanc_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
1686169689Skan		    bool scspec_ok, bool typespec_ok, bool start_attr_ok)
1687169689Skan{
1688169689Skan  bool attrs_ok = start_attr_ok;
1689169689Skan  bool seen_type = specs->type_seen_p;
1690169689Skan  while (c_parser_next_token_is (parser, CPP_NAME)
1691169689Skan	 || c_parser_next_token_is (parser, CPP_KEYWORD)
1692169689Skan	 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
1693169689Skan    {
1694169689Skan      struct c_typespec t;
1695169689Skan      tree attrs;
1696169689Skan      if (c_parser_next_token_is (parser, CPP_NAME))
1697169689Skan	{
1698169689Skan	  tree value = c_parser_peek_token (parser)->value;
1699169689Skan	  c_id_kind kind = c_parser_peek_token (parser)->id_kind;
1700169689Skan	  /* This finishes the specifiers unless a type name is OK, it
1701169689Skan	     is declared as a type name and a type name hasn't yet
1702169689Skan	     been seen.  */
1703169689Skan	  if (!typespec_ok || seen_type
1704169689Skan	      || (kind != C_ID_TYPENAME && kind != C_ID_CLASSNAME))
1705169689Skan	    break;
1706169689Skan	  c_parser_consume_token (parser);
1707169689Skan	  seen_type = true;
1708169689Skan	  attrs_ok = true;
1709169689Skan	  if (kind == C_ID_TYPENAME
1710169689Skan	      && (!c_dialect_objc ()
1711169689Skan		  || c_parser_next_token_is_not (parser, CPP_LESS)))
1712169689Skan	    {
1713169689Skan	      t.kind = ctsk_typedef;
1714169689Skan	      /* For a typedef name, record the meaning, not the name.
1715169689Skan		 In case of 'foo foo, bar;'.  */
1716169689Skan	      t.spec = lookup_name (value);
1717169689Skan	    }
1718169689Skan	  else
1719169689Skan	    {
1720169689Skan	      tree proto = NULL_TREE;
1721169689Skan	      gcc_assert (c_dialect_objc ());
1722169689Skan	      t.kind = ctsk_objc;
1723169689Skan	      if (c_parser_next_token_is (parser, CPP_LESS))
1724169689Skan		proto = c_parser_objc_protocol_refs (parser);
1725169689Skan	      t.spec = objc_get_protocol_qualified_type (value, proto);
1726169689Skan	    }
1727169689Skan	  declspecs_add_type (specs, t);
1728169689Skan	  continue;
1729169689Skan	}
1730169689Skan      if (c_parser_next_token_is (parser, CPP_LESS))
1731169689Skan	{
1732169689Skan	  /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
1733169689Skan	     nisse@lysator.liu.se.  */
1734169689Skan	  tree proto;
1735169689Skan	  gcc_assert (c_dialect_objc ());
1736169689Skan	  if (!typespec_ok || seen_type)
1737169689Skan	    break;
1738169689Skan	  proto = c_parser_objc_protocol_refs (parser);
1739169689Skan	  t.kind = ctsk_objc;
1740169689Skan	  t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
1741169689Skan	  declspecs_add_type (specs, t);
1742169689Skan	  continue;
1743169689Skan	}
1744169689Skan      gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
1745169689Skan      switch (c_parser_peek_token (parser)->keyword)
1746169689Skan	{
1747169689Skan	case RID_STATIC:
1748169689Skan	case RID_EXTERN:
1749169689Skan	case RID_REGISTER:
1750169689Skan	case RID_TYPEDEF:
1751169689Skan	case RID_INLINE:
1752169689Skan	case RID_AUTO:
1753169689Skan	case RID_THREAD:
1754169689Skan	  if (!scspec_ok)
1755169689Skan	    goto out;
1756169689Skan	  attrs_ok = true;
1757169689Skan	  /* TODO: Distinguish between function specifiers (inline)
1758169689Skan	     and storage class specifiers, either here or in
1759169689Skan	     declspecs_add_scspec.  */
1760169689Skan	  declspecs_add_scspec (specs, c_parser_peek_token (parser)->value);
1761169689Skan	  c_parser_consume_token (parser);
1762169689Skan	  break;
1763169689Skan	case RID_UNSIGNED:
1764169689Skan	case RID_LONG:
1765169689Skan	case RID_SHORT:
1766169689Skan	case RID_SIGNED:
1767169689Skan	case RID_COMPLEX:
1768169689Skan	case RID_INT:
1769169689Skan	case RID_CHAR:
1770169689Skan	case RID_FLOAT:
1771169689Skan	case RID_DOUBLE:
1772169689Skan	case RID_VOID:
1773169689Skan	case RID_DFLOAT32:
1774169689Skan	case RID_DFLOAT64:
1775169689Skan	case RID_DFLOAT128:
1776169689Skan	case RID_BOOL:
1777169689Skan	  if (!typespec_ok)
1778169689Skan	    goto out;
1779169689Skan	  attrs_ok = true;
1780169689Skan	  seen_type = true;
1781169689Skan	  OBJC_NEED_RAW_IDENTIFIER (1);
1782169689Skan	  t.kind = ctsk_resword;
1783169689Skan	  t.spec = c_parser_peek_token (parser)->value;
1784169689Skan	  declspecs_add_type (specs, t);
1785169689Skan	  c_parser_consume_token (parser);
1786169689Skan	  break;
1787169689Skan	case RID_ENUM:
1788169689Skan	  if (!typespec_ok)
1789169689Skan	    goto out;
1790169689Skan	  attrs_ok = true;
1791169689Skan	  seen_type = true;
1792169689Skan	  t = c_parser_enum_specifier (parser);
1793169689Skan	  declspecs_add_type (specs, t);
1794169689Skan	  break;
1795169689Skan	case RID_STRUCT:
1796169689Skan	case RID_UNION:
1797169689Skan	  if (!typespec_ok)
1798169689Skan	    goto out;
1799169689Skan	  attrs_ok = true;
1800169689Skan	  seen_type = true;
1801169689Skan	  t = c_parser_struct_or_union_specifier (parser);
1802169689Skan	  declspecs_add_type (specs, t);
1803169689Skan	  break;
1804169689Skan	case RID_TYPEOF:
1805169689Skan	  /* ??? The old parser rejected typeof after other type
1806169689Skan	     specifiers, but is a syntax error the best way of
1807169689Skan	     handling this?  */
1808169689Skan	  if (!typespec_ok || seen_type)
1809169689Skan	    goto out;
1810169689Skan	  attrs_ok = true;
1811169689Skan	  seen_type = true;
1812169689Skan	  t = c_parser_typeof_specifier (parser);
1813169689Skan	  declspecs_add_type (specs, t);
1814169689Skan	  break;
1815169689Skan	case RID_CONST:
1816169689Skan	case RID_VOLATILE:
1817169689Skan	case RID_RESTRICT:
1818169689Skan	  attrs_ok = true;
1819169689Skan	  declspecs_add_qual (specs, c_parser_peek_token (parser)->value);
1820169689Skan	  c_parser_consume_token (parser);
1821169689Skan	  break;
1822169689Skan	case RID_ATTRIBUTE:
1823169689Skan	  if (!attrs_ok)
1824169689Skan	    goto out;
1825169689Skan	  attrs = c_parser_attributes (parser);
1826169689Skan	  declspecs_add_attrs (specs, attrs);
1827169689Skan	  break;
1828169689Skan	default:
1829169689Skan	  goto out;
1830169689Skan	}
1831169689Skan    }
1832169689Skan out: ;
1833169689Skan}
1834169689Skan
1835169689Skan/* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2).
1836169689Skan
1837169689Skan   enum-specifier:
1838169689Skan     enum attributes[opt] identifier[opt] { enumerator-list } attributes[opt]
1839169689Skan     enum attributes[opt] identifier[opt] { enumerator-list , } attributes[opt]
1840169689Skan     enum attributes[opt] identifier
1841169689Skan
1842169689Skan   The form with trailing comma is new in C99.  The forms with
1843169689Skan   attributes are GNU extensions.  In GNU C, we accept any expression
1844169689Skan   without commas in the syntax (assignment expressions, not just
1845169689Skan   conditional expressions); assignment expressions will be diagnosed
1846169689Skan   as non-constant.
1847169689Skan
1848169689Skan   enumerator-list:
1849169689Skan     enumerator
1850169689Skan     enumerator-list , enumerator
1851169689Skan
1852169689Skan   enumerator:
1853169689Skan     enumeration-constant
1854169689Skan     enumeration-constant = constant-expression
1855169689Skan*/
1856169689Skan
1857169689Skanstatic struct c_typespec
1858169689Skanc_parser_enum_specifier (c_parser *parser)
1859169689Skan{
1860169689Skan  struct c_typespec ret;
1861169689Skan  tree attrs;
1862169689Skan  tree ident = NULL_TREE;
1863169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
1864169689Skan  c_parser_consume_token (parser);
1865169689Skan  attrs = c_parser_attributes (parser);
1866169689Skan  if (c_parser_next_token_is (parser, CPP_NAME))
1867169689Skan    {
1868169689Skan      ident = c_parser_peek_token (parser)->value;
1869169689Skan      c_parser_consume_token (parser);
1870169689Skan    }
1871169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
1872169689Skan    {
1873169689Skan      /* Parse an enum definition.  */
1874169689Skan      tree type = start_enum (ident);
1875169689Skan      tree postfix_attrs;
1876169689Skan      /* We chain the enumerators in reverse order, then put them in
1877169689Skan	 forward order at the end.  */
1878169689Skan      tree values = NULL_TREE;
1879169689Skan      c_parser_consume_token (parser);
1880169689Skan      while (true)
1881169689Skan	{
1882169689Skan	  tree enum_id;
1883169689Skan	  tree enum_value;
1884169689Skan	  tree enum_decl;
1885169689Skan	  bool seen_comma;
1886169689Skan	  if (c_parser_next_token_is_not (parser, CPP_NAME))
1887169689Skan	    {
1888169689Skan	      c_parser_error (parser, "expected identifier");
1889169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
1890169689Skan	      values = error_mark_node;
1891169689Skan	      break;
1892169689Skan	    }
1893169689Skan	  enum_id = c_parser_peek_token (parser)->value;
1894169689Skan	  c_parser_consume_token (parser);
1895169689Skan	  if (c_parser_next_token_is (parser, CPP_EQ))
1896169689Skan	    {
1897169689Skan	      c_parser_consume_token (parser);
1898169689Skan	      enum_value = c_parser_expr_no_commas (parser, NULL).value;
1899169689Skan	    }
1900169689Skan	  else
1901169689Skan	    enum_value = NULL_TREE;
1902169689Skan	  enum_decl = build_enumerator (enum_id, enum_value);
1903169689Skan	  TREE_CHAIN (enum_decl) = values;
1904169689Skan	  values = enum_decl;
1905169689Skan	  seen_comma = false;
1906169689Skan	  if (c_parser_next_token_is (parser, CPP_COMMA))
1907169689Skan	    {
1908169689Skan	      seen_comma = true;
1909169689Skan	      c_parser_consume_token (parser);
1910169689Skan	    }
1911169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
1912169689Skan	    {
1913169689Skan	      if (seen_comma && pedantic && !flag_isoc99)
1914169689Skan		pedwarn ("comma at end of enumerator list");
1915169689Skan	      c_parser_consume_token (parser);
1916169689Skan	      break;
1917169689Skan	    }
1918169689Skan	  if (!seen_comma)
1919169689Skan	    {
1920169689Skan	      c_parser_error (parser, "expected %<,%> or %<}%>");
1921169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
1922169689Skan	      values = error_mark_node;
1923169689Skan	      break;
1924169689Skan	    }
1925169689Skan	}
1926169689Skan      postfix_attrs = c_parser_attributes (parser);
1927169689Skan      ret.spec = finish_enum (type, nreverse (values),
1928169689Skan			      chainon (attrs, postfix_attrs));
1929169689Skan      ret.kind = ctsk_tagdef;
1930169689Skan      return ret;
1931169689Skan    }
1932169689Skan  else if (!ident)
1933169689Skan    {
1934169689Skan      c_parser_error (parser, "expected %<{%>");
1935169689Skan      ret.spec = error_mark_node;
1936169689Skan      ret.kind = ctsk_tagref;
1937169689Skan      return ret;
1938169689Skan    }
1939169689Skan  ret = parser_xref_tag (ENUMERAL_TYPE, ident);
1940169689Skan  /* In ISO C, enumerated types can be referred to only if already
1941169689Skan     defined.  */
1942169689Skan  if (pedantic && !COMPLETE_TYPE_P (ret.spec))
1943169689Skan    pedwarn ("ISO C forbids forward references to %<enum%> types");
1944169689Skan  return ret;
1945169689Skan}
1946169689Skan
1947169689Skan/* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1).
1948169689Skan
1949169689Skan   struct-or-union-specifier:
1950169689Skan     struct-or-union attributes[opt] identifier[opt]
1951169689Skan       { struct-contents } attributes[opt]
1952169689Skan     struct-or-union attributes[opt] identifier
1953169689Skan
1954169689Skan   struct-contents:
1955169689Skan     struct-declaration-list
1956169689Skan
1957169689Skan   struct-declaration-list:
1958169689Skan     struct-declaration ;
1959169689Skan     struct-declaration-list struct-declaration ;
1960169689Skan
1961169689Skan   GNU extensions:
1962169689Skan
1963169689Skan   struct-contents:
1964169689Skan     empty
1965169689Skan     struct-declaration
1966169689Skan     struct-declaration-list struct-declaration
1967169689Skan
1968169689Skan   struct-declaration-list:
1969169689Skan     struct-declaration-list ;
1970169689Skan     ;
1971169689Skan
1972169689Skan   (Note that in the syntax here, unlike that in ISO C, the semicolons
1973169689Skan   are included here rather than in struct-declaration, in order to
1974169689Skan   describe the syntax with extra semicolons and missing semicolon at
1975169689Skan   end.)
1976169689Skan
1977169689Skan   Objective-C:
1978169689Skan
1979169689Skan   struct-declaration-list:
1980169689Skan     @defs ( class-name )
1981169689Skan
1982169689Skan   (Note this does not include a trailing semicolon, but can be
1983169689Skan   followed by further declarations, and gets a pedwarn-if-pedantic
1984169689Skan   when followed by a semicolon.)  */
1985169689Skan
1986169689Skanstatic struct c_typespec
1987169689Skanc_parser_struct_or_union_specifier (c_parser *parser)
1988169689Skan{
1989169689Skan  struct c_typespec ret;
1990169689Skan  tree attrs;
1991169689Skan  tree ident = NULL_TREE;
1992169689Skan  enum tree_code code;
1993169689Skan  switch (c_parser_peek_token (parser)->keyword)
1994169689Skan    {
1995169689Skan    case RID_STRUCT:
1996169689Skan      code = RECORD_TYPE;
1997169689Skan      break;
1998169689Skan    case RID_UNION:
1999169689Skan      code = UNION_TYPE;
2000169689Skan      break;
2001169689Skan    default:
2002169689Skan      gcc_unreachable ();
2003169689Skan    }
2004169689Skan  c_parser_consume_token (parser);
2005169689Skan  attrs = c_parser_attributes (parser);
2006169689Skan  if (c_parser_next_token_is (parser, CPP_NAME))
2007169689Skan    {
2008169689Skan      ident = c_parser_peek_token (parser)->value;
2009169689Skan      c_parser_consume_token (parser);
2010169689Skan    }
2011169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2012169689Skan    {
2013169689Skan      /* Parse a struct or union definition.  Start the scope of the
2014169689Skan	 tag before parsing components.  */
2015169689Skan      tree type = start_struct (code, ident);
2016169689Skan      tree postfix_attrs;
2017169689Skan      /* We chain the components in reverse order, then put them in
2018169689Skan	 forward order at the end.  Each struct-declaration may
2019169689Skan	 declare multiple components (comma-separated), so we must use
2020169689Skan	 chainon to join them, although when parsing each
2021169689Skan	 struct-declaration we can use TREE_CHAIN directly.
2022169689Skan
2023169689Skan	 The theory behind all this is that there will be more
2024169689Skan	 semicolon separated fields than comma separated fields, and
2025169689Skan	 so we'll be minimizing the number of node traversals required
2026169689Skan	 by chainon.  */
2027169689Skan      tree contents = NULL_TREE;
2028169689Skan      c_parser_consume_token (parser);
2029169689Skan      /* Handle the Objective-C @defs construct,
2030169689Skan	 e.g. foo(sizeof(struct{ @defs(ClassName) }));.  */
2031169689Skan      if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
2032169689Skan	{
2033169689Skan	  tree name;
2034169689Skan	  gcc_assert (c_dialect_objc ());
2035169689Skan	  c_parser_consume_token (parser);
2036169689Skan	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2037169689Skan	    goto end_at_defs;
2038169689Skan	  if (c_parser_next_token_is (parser, CPP_NAME)
2039169689Skan	      && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
2040169689Skan	    {
2041169689Skan	      name = c_parser_peek_token (parser)->value;
2042169689Skan	      c_parser_consume_token (parser);
2043169689Skan	    }
2044169689Skan	  else
2045169689Skan	    {
2046169689Skan	      c_parser_error (parser, "expected class name");
2047169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
2048169689Skan	      goto end_at_defs;
2049169689Skan	    }
2050169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2051169689Skan				     "expected %<)%>");
2052169689Skan	  contents = nreverse (objc_get_class_ivars (name));
2053169689Skan	}
2054169689Skan    end_at_defs:
2055169689Skan      /* Parse the struct-declarations and semicolons.  Problems with
2056169689Skan	 semicolons are diagnosed here; empty structures are diagnosed
2057169689Skan	 elsewhere.  */
2058169689Skan      while (true)
2059169689Skan	{
2060169689Skan	  tree decls;
2061169689Skan	  /* Parse any stray semicolon.  */
2062169689Skan	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2063169689Skan	    {
2064169689Skan	      if (pedantic)
2065169689Skan		pedwarn ("extra semicolon in struct or union specified");
2066169689Skan	      c_parser_consume_token (parser);
2067169689Skan	      continue;
2068169689Skan	    }
2069169689Skan	  /* Stop if at the end of the struct or union contents.  */
2070169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2071169689Skan	    {
2072169689Skan	      c_parser_consume_token (parser);
2073169689Skan	      break;
2074169689Skan	    }
2075169689Skan	  /* Accept #pragmas at struct scope.  */
2076169689Skan	  if (c_parser_next_token_is (parser, CPP_PRAGMA))
2077169689Skan	    {
2078169689Skan	      c_parser_pragma (parser, pragma_external);
2079169689Skan	      continue;
2080169689Skan	    }
2081169689Skan	  /* Parse some comma-separated declarations, but not the
2082169689Skan	     trailing semicolon if any.  */
2083169689Skan	  decls = c_parser_struct_declaration (parser);
2084169689Skan	  contents = chainon (decls, contents);
2085169689Skan	  /* If no semicolon follows, either we have a parse error or
2086169689Skan	     are at the end of the struct or union and should
2087169689Skan	     pedwarn.  */
2088169689Skan	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2089169689Skan	    c_parser_consume_token (parser);
2090169689Skan	  else
2091169689Skan	    {
2092169689Skan	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2093169689Skan		pedwarn ("no semicolon at end of struct or union");
2094169689Skan	      else
2095169689Skan		{
2096169689Skan		  c_parser_error (parser, "expected %<;%>");
2097169689Skan		  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
2098169689Skan		  break;
2099169689Skan		}
2100169689Skan	    }
2101169689Skan	}
2102169689Skan      postfix_attrs = c_parser_attributes (parser);
2103169689Skan      ret.spec = finish_struct (type, nreverse (contents),
2104169689Skan				chainon (attrs, postfix_attrs));
2105169689Skan      ret.kind = ctsk_tagdef;
2106169689Skan      return ret;
2107169689Skan    }
2108169689Skan  else if (!ident)
2109169689Skan    {
2110169689Skan      c_parser_error (parser, "expected %<{%>");
2111169689Skan      ret.spec = error_mark_node;
2112169689Skan      ret.kind = ctsk_tagref;
2113169689Skan      return ret;
2114169689Skan    }
2115169689Skan  ret = parser_xref_tag (code, ident);
2116169689Skan  return ret;
2117169689Skan}
2118169689Skan
2119169689Skan/* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1), *without*
2120169689Skan   the trailing semicolon.
2121169689Skan
2122169689Skan   struct-declaration:
2123169689Skan     specifier-qualifier-list struct-declarator-list
2124169689Skan
2125169689Skan   specifier-qualifier-list:
2126169689Skan     type-specifier specifier-qualifier-list[opt]
2127169689Skan     type-qualifier specifier-qualifier-list[opt]
2128169689Skan     attributes specifier-qualifier-list[opt]
2129169689Skan
2130169689Skan   struct-declarator-list:
2131169689Skan     struct-declarator
2132169689Skan     struct-declarator-list , attributes[opt] struct-declarator
2133169689Skan
2134169689Skan   struct-declarator:
2135169689Skan     declarator attributes[opt]
2136169689Skan     declarator[opt] : constant-expression attributes[opt]
2137169689Skan
2138169689Skan   GNU extensions:
2139169689Skan
2140169689Skan   struct-declaration:
2141169689Skan     __extension__ struct-declaration
2142169689Skan     specifier-qualifier-list
2143169689Skan
2144169689Skan   Unlike the ISO C syntax, semicolons are handled elsewhere.  The use
2145169689Skan   of attributes where shown is a GNU extension.  In GNU C, we accept
2146169689Skan   any expression without commas in the syntax (assignment
2147169689Skan   expressions, not just conditional expressions); assignment
2148169689Skan   expressions will be diagnosed as non-constant.  */
2149169689Skan
2150169689Skanstatic tree
2151169689Skanc_parser_struct_declaration (c_parser *parser)
2152169689Skan{
2153169689Skan  struct c_declspecs *specs;
2154169689Skan  tree prefix_attrs;
2155169689Skan  tree all_prefix_attrs;
2156169689Skan  tree decls;
2157169689Skan  if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
2158169689Skan    {
2159169689Skan      int ext;
2160169689Skan      tree decl;
2161169689Skan      ext = disable_extension_diagnostics ();
2162169689Skan      c_parser_consume_token (parser);
2163169689Skan      decl = c_parser_struct_declaration (parser);
2164169689Skan      restore_extension_diagnostics (ext);
2165169689Skan      return decl;
2166169689Skan    }
2167169689Skan  specs = build_null_declspecs ();
2168169689Skan  c_parser_declspecs (parser, specs, false, true, true);
2169169689Skan  if (parser->error)
2170169689Skan    return NULL_TREE;
2171169689Skan  if (!specs->declspecs_seen_p)
2172169689Skan    {
2173169689Skan      c_parser_error (parser, "expected specifier-qualifier-list");
2174169689Skan      return NULL_TREE;
2175169689Skan    }
2176169689Skan  finish_declspecs (specs);
2177169689Skan  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2178169689Skan    {
2179169689Skan      tree ret;
2180169689Skan      if (!specs->type_seen_p)
2181169689Skan	{
2182169689Skan	  if (pedantic)
2183169689Skan	    pedwarn ("ISO C forbids member declarations with no members");
2184169689Skan	  shadow_tag_warned (specs, pedantic);
2185169689Skan	  ret = NULL_TREE;
2186169689Skan	}
2187169689Skan      else
2188169689Skan	{
2189169689Skan	  /* Support for unnamed structs or unions as members of
2190169689Skan	     structs or unions (which is [a] useful and [b] supports
2191169689Skan	     MS P-SDK).  */
2192169689Skan	  ret = grokfield (build_id_declarator (NULL_TREE), specs, NULL_TREE);
2193169689Skan	}
2194169689Skan      return ret;
2195169689Skan    }
2196169689Skan  pending_xref_error ();
2197169689Skan  prefix_attrs = specs->attrs;
2198169689Skan  all_prefix_attrs = prefix_attrs;
2199169689Skan  specs->attrs = NULL_TREE;
2200169689Skan  decls = NULL_TREE;
2201169689Skan  while (true)
2202169689Skan    {
2203169689Skan      /* Declaring one or more declarators or un-named bit-fields.  */
2204169689Skan      struct c_declarator *declarator;
2205169689Skan      bool dummy = false;
2206169689Skan      if (c_parser_next_token_is (parser, CPP_COLON))
2207169689Skan	declarator = build_id_declarator (NULL_TREE);
2208169689Skan      else
2209169689Skan	declarator = c_parser_declarator (parser, specs->type_seen_p,
2210169689Skan					  C_DTR_NORMAL, &dummy);
2211169689Skan      if (declarator == NULL)
2212169689Skan	{
2213169689Skan	  c_parser_skip_to_end_of_block_or_statement (parser);
2214169689Skan	  break;
2215169689Skan	}
2216169689Skan      if (c_parser_next_token_is (parser, CPP_COLON)
2217169689Skan	  || c_parser_next_token_is (parser, CPP_COMMA)
2218169689Skan	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
2219169689Skan	  || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
2220169689Skan	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2221169689Skan	{
2222169689Skan	  tree postfix_attrs = NULL_TREE;
2223169689Skan	  tree width = NULL_TREE;
2224169689Skan	  tree d;
2225169689Skan	  if (c_parser_next_token_is (parser, CPP_COLON))
2226169689Skan	    {
2227169689Skan	      c_parser_consume_token (parser);
2228169689Skan	      width = c_parser_expr_no_commas (parser, NULL).value;
2229169689Skan	    }
2230169689Skan	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2231169689Skan	    postfix_attrs = c_parser_attributes (parser);
2232169689Skan	  d = grokfield (declarator, specs, width);
2233169689Skan	  decl_attributes (&d, chainon (postfix_attrs,
2234169689Skan					all_prefix_attrs), 0);
2235169689Skan	  TREE_CHAIN (d) = decls;
2236169689Skan	  decls = d;
2237169689Skan	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2238169689Skan	    all_prefix_attrs = chainon (c_parser_attributes (parser),
2239169689Skan					prefix_attrs);
2240169689Skan	  else
2241169689Skan	    all_prefix_attrs = prefix_attrs;
2242169689Skan	  if (c_parser_next_token_is (parser, CPP_COMMA))
2243169689Skan	    c_parser_consume_token (parser);
2244169689Skan	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
2245169689Skan		   || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2246169689Skan	    {
2247169689Skan	      /* Semicolon consumed in caller.  */
2248169689Skan	      break;
2249169689Skan	    }
2250169689Skan	  else
2251169689Skan	    {
2252169689Skan	      c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
2253169689Skan	      break;
2254169689Skan	    }
2255169689Skan	}
2256169689Skan      else
2257169689Skan	{
2258169689Skan	  c_parser_error (parser,
2259169689Skan			  "expected %<:%>, %<,%>, %<;%>, %<}%> or "
2260169689Skan			  "%<__attribute__%>");
2261169689Skan	  break;
2262169689Skan	}
2263169689Skan    }
2264169689Skan  return decls;
2265169689Skan}
2266169689Skan
2267169689Skan/* Parse a typeof specifier (a GNU extension).
2268169689Skan
2269169689Skan   typeof-specifier:
2270169689Skan     typeof ( expression )
2271169689Skan     typeof ( type-name )
2272169689Skan*/
2273169689Skan
2274169689Skanstatic struct c_typespec
2275169689Skanc_parser_typeof_specifier (c_parser *parser)
2276169689Skan{
2277169689Skan  struct c_typespec ret;
2278169689Skan  ret.kind = ctsk_typeof;
2279169689Skan  ret.spec = error_mark_node;
2280169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
2281169689Skan  c_parser_consume_token (parser);
2282169689Skan  skip_evaluation++;
2283169689Skan  in_typeof++;
2284169689Skan  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2285169689Skan    {
2286169689Skan      skip_evaluation--;
2287169689Skan      in_typeof--;
2288169689Skan      return ret;
2289169689Skan    }
2290169689Skan  if (c_parser_next_token_starts_typename (parser))
2291169689Skan    {
2292169689Skan      struct c_type_name *type = c_parser_type_name (parser);
2293169689Skan      skip_evaluation--;
2294169689Skan      in_typeof--;
2295169689Skan      if (type != NULL)
2296169689Skan	{
2297169689Skan	  ret.spec = groktypename (type);
2298169689Skan	  pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
2299169689Skan	}
2300169689Skan    }
2301169689Skan  else
2302169689Skan    {
2303169689Skan      bool was_vm;
2304169689Skan      struct c_expr expr = c_parser_expression (parser);
2305169689Skan      skip_evaluation--;
2306169689Skan      in_typeof--;
2307169689Skan      if (TREE_CODE (expr.value) == COMPONENT_REF
2308169689Skan	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
2309169689Skan	error ("%<typeof%> applied to a bit-field");
2310169689Skan      ret.spec = TREE_TYPE (expr.value);
2311169689Skan      was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
2312169689Skan      /* This should be returned with the type so that when the type
2313169689Skan	 is evaluated, this can be evaluated.  For now, we avoid
2314169689Skan	 evaluation when the context might.  */
2315169689Skan      if (!skip_evaluation && was_vm)
2316169689Skan	{
2317169689Skan	  tree e = expr.value;
2318169689Skan
2319169689Skan	  /* If the expression is not of a type to which we cannot assign a line
2320169689Skan	     number, wrap the thing in a no-op NOP_EXPR.  */
2321169689Skan	  if (DECL_P (e) || CONSTANT_CLASS_P (e))
2322169689Skan	    e = build1 (NOP_EXPR, void_type_node, e);
2323169689Skan
2324169689Skan	  if (EXPR_P (e))
2325169689Skan	    SET_EXPR_LOCATION (e, input_location);
2326169689Skan
2327169689Skan	  add_stmt (e);
2328169689Skan	}
2329169689Skan      pop_maybe_used (was_vm);
2330169689Skan    }
2331169689Skan  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
2332169689Skan  return ret;
2333169689Skan}
2334169689Skan
2335169689Skan/* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
2336169689Skan   6.5.5, C99 6.7.5, 6.7.6).  If TYPE_SEEN_P then a typedef name may
2337169689Skan   be redeclared; otherwise it may not.  KIND indicates which kind of
2338169689Skan   declarator is wanted.  Returns a valid declarator except in the
2339169689Skan   case of a syntax error in which case NULL is returned.  *SEEN_ID is
2340169689Skan   set to true if an identifier being declared is seen; this is used
2341169689Skan   to diagnose bad forms of abstract array declarators and to
2342169689Skan   determine whether an identifier list is syntactically permitted.
2343169689Skan
2344169689Skan   declarator:
2345169689Skan     pointer[opt] direct-declarator
2346169689Skan
2347169689Skan   direct-declarator:
2348169689Skan     identifier
2349169689Skan     ( attributes[opt] declarator )
2350169689Skan     direct-declarator array-declarator
2351169689Skan     direct-declarator ( parameter-type-list )
2352169689Skan     direct-declarator ( identifier-list[opt] )
2353169689Skan
2354169689Skan   pointer:
2355169689Skan     * type-qualifier-list[opt]
2356169689Skan     * type-qualifier-list[opt] pointer
2357169689Skan
2358169689Skan   type-qualifier-list:
2359169689Skan     type-qualifier
2360169689Skan     attributes
2361169689Skan     type-qualifier-list type-qualifier
2362169689Skan     type-qualifier-list attributes
2363169689Skan
2364169689Skan   parameter-type-list:
2365169689Skan     parameter-list
2366169689Skan     parameter-list , ...
2367169689Skan
2368169689Skan   parameter-list:
2369169689Skan     parameter-declaration
2370169689Skan     parameter-list , parameter-declaration
2371169689Skan
2372169689Skan   parameter-declaration:
2373169689Skan     declaration-specifiers declarator attributes[opt]
2374169689Skan     declaration-specifiers abstract-declarator[opt] attributes[opt]
2375169689Skan
2376169689Skan   identifier-list:
2377169689Skan     identifier
2378169689Skan     identifier-list , identifier
2379169689Skan
2380169689Skan   abstract-declarator:
2381169689Skan     pointer
2382169689Skan     pointer[opt] direct-abstract-declarator
2383169689Skan
2384169689Skan   direct-abstract-declarator:
2385169689Skan     ( attributes[opt] abstract-declarator )
2386169689Skan     direct-abstract-declarator[opt] array-declarator
2387169689Skan     direct-abstract-declarator[opt] ( parameter-type-list[opt] )
2388169689Skan
2389169689Skan   GNU extensions:
2390169689Skan
2391169689Skan   direct-declarator:
2392169689Skan     direct-declarator ( parameter-forward-declarations
2393169689Skan			 parameter-type-list[opt] )
2394169689Skan
2395169689Skan   direct-abstract-declarator:
2396169689Skan     direct-abstract-declarator[opt] ( parameter-forward-declarations
2397169689Skan				       parameter-type-list[opt] )
2398169689Skan
2399169689Skan   parameter-forward-declarations:
2400169689Skan     parameter-list ;
2401169689Skan     parameter-forward-declarations parameter-list ;
2402169689Skan
2403261188Spfg     APPLE LOCAL begin blocks 6339747
2404261188Spfg   block-declarator:
2405261188Spfg     pointer
2406261188Spfg     pointer[opt] direct-block-declarator
2407261188Spfg
2408261188Spfg   direct-block-declarator:
2409261188Spfg     ( attributes[opt] block-declarator )
2410261188Spfg     direct-block-declarator[opt] array-declarator
2411261188Spfg     direct-block-declarator[opt]
2412261188Spfg	( parameter-type-list[opt] ) [opt]
2413261188Spfg     APPLE LOCAL end blocks 6339747
2414261188Spfg
2415169689Skan   The uses of attributes shown above are GNU extensions.
2416169689Skan
2417169689Skan   Some forms of array declarator are not included in C99 in the
2418169689Skan   syntax for abstract declarators; these are disallowed elsewhere.
2419169689Skan   This may be a defect (DR#289).
2420169689Skan
2421169689Skan   This function also accepts an omitted abstract declarator as being
2422169689Skan   an abstract declarator, although not part of the formal syntax.  */
2423169689Skan
2424169689Skanstatic struct c_declarator *
2425169689Skanc_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
2426169689Skan		     bool *seen_id)
2427169689Skan{
2428169689Skan  /* Parse any initial pointer part.  */
2429169689Skan  if (c_parser_next_token_is (parser, CPP_MULT))
2430169689Skan    {
2431169689Skan      struct c_declspecs *quals_attrs = build_null_declspecs ();
2432169689Skan      struct c_declarator *inner;
2433169689Skan      c_parser_consume_token (parser);
2434169689Skan      c_parser_declspecs (parser, quals_attrs, false, false, true);
2435169689Skan      inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
2436169689Skan      if (inner == NULL)
2437169689Skan	return NULL;
2438169689Skan      else
2439169689Skan	return make_pointer_declarator (quals_attrs, inner);
2440169689Skan    }
2441261188Spfg  /* APPLE LOCAL begin radar 5732232 - blocks (C++ cc) */
2442261188Spfg  else if (flag_blocks && c_parser_next_token_is (parser, CPP_XOR)) {
2443261188Spfg    struct c_declspecs *quals_attrs = build_null_declspecs ();
2444261188Spfg    struct c_declarator *inner;
2445261188Spfg    c_parser_consume_token (parser);
2446261188Spfg    c_parser_declspecs (parser, quals_attrs, false, false, true);
2447261188Spfg    inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
2448261188Spfg    if (inner == NULL)
2449261188Spfg      return NULL;
2450261188Spfg    else
2451261188Spfg      /* APPLE LOCAL radar 5814025 (C++ cc) */
2452261188Spfg      return make_block_pointer_declarator (quals_attrs, inner);
2453261188Spfg  }
2454261188Spfg  /* APPLE LOCAL end radar 5732232 - blocks (C++ cc) */
2455169689Skan  /* Now we have a direct declarator, direct abstract declarator or
2456169689Skan     nothing (which counts as a direct abstract declarator here).  */
2457169689Skan  return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
2458169689Skan}
2459169689Skan
2460169689Skan/* Parse a direct declarator or direct abstract declarator; arguments
2461169689Skan   as c_parser_declarator.  */
2462169689Skan
2463169689Skanstatic struct c_declarator *
2464169689Skanc_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
2465169689Skan			    bool *seen_id)
2466169689Skan{
2467169689Skan  /* The direct declarator must start with an identifier (possibly
2468169689Skan     omitted) or a parenthesized declarator (possibly abstract).  In
2469169689Skan     an ordinary declarator, initial parentheses must start a
2470169689Skan     parenthesized declarator.  In an abstract declarator or parameter
2471169689Skan     declarator, they could start a parenthesized declarator or a
2472169689Skan     parameter list.  To tell which, the open parenthesis and any
2473169689Skan     following attributes must be read.  If a declaration specifier
2474169689Skan     follows, then it is a parameter list; if the specifier is a
2475169689Skan     typedef name, there might be an ambiguity about redeclaring it,
2476169689Skan     which is resolved in the direction of treating it as a typedef
2477169689Skan     name.  If a close parenthesis follows, it is also an empty
2478169689Skan     parameter list, as the syntax does not permit empty abstract
2479169689Skan     declarators.  Otherwise, it is a parenthesized declarator (in
2480169689Skan     which case the analysis may be repeated inside it, recursively).
2481169689Skan
2482169689Skan     ??? There is an ambiguity in a parameter declaration "int
2483169689Skan     (__attribute__((foo)) x)", where x is not a typedef name: it
2484169689Skan     could be an abstract declarator for a function, or declare x with
2485169689Skan     parentheses.  The proper resolution of this ambiguity needs
2486169689Skan     documenting.  At present we follow an accident of the old
2487169689Skan     parser's implementation, whereby the first parameter must have
2488169689Skan     some declaration specifiers other than just attributes.  Thus as
2489169689Skan     a parameter declaration it is treated as a parenthesized
2490169689Skan     parameter named x, and as an abstract declarator it is
2491169689Skan     rejected.
2492169689Skan
2493169689Skan     ??? Also following the old parser, attributes inside an empty
2494169689Skan     parameter list are ignored, making it a list not yielding a
2495169689Skan     prototype, rather than giving an error or making it have one
2496169689Skan     parameter with implicit type int.
2497169689Skan
2498169689Skan     ??? Also following the old parser, typedef names may be
2499169689Skan     redeclared in declarators, but not Objective-C class names.  */
2500169689Skan
2501261188Spfg  /* APPLE LOCAL blocks 6339747 */
2502261188Spfg  if ((kind != C_DTR_ABSTRACT && kind != C_DTR_BLOCK)
2503169689Skan      && c_parser_next_token_is (parser, CPP_NAME)
2504169689Skan      && ((type_seen_p
2505261188Spfg	   /* APPLE LOCAL begin radar 4281748 */
2506261188Spfg	   && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
2507261188Spfg	       || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
2508261188Spfg	   /* APPLE LOCAL end radar 4281748 */
2509169689Skan	  || c_parser_peek_token (parser)->id_kind == C_ID_ID))
2510169689Skan    {
2511169689Skan      struct c_declarator *inner
2512169689Skan	= build_id_declarator (c_parser_peek_token (parser)->value);
2513169689Skan      *seen_id = true;
2514169689Skan      inner->id_loc = c_parser_peek_token (parser)->location;
2515169689Skan      c_parser_consume_token (parser);
2516169689Skan      return c_parser_direct_declarator_inner (parser, *seen_id, inner);
2517169689Skan    }
2518169689Skan
2519169689Skan  if (kind != C_DTR_NORMAL
2520169689Skan      && c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
2521169689Skan    {
2522169689Skan      struct c_declarator *inner = build_id_declarator (NULL_TREE);
2523169689Skan      return c_parser_direct_declarator_inner (parser, *seen_id, inner);
2524169689Skan    }
2525169689Skan
2526169689Skan  /* Either we are at the end of an abstract declarator, or we have
2527169689Skan     parentheses.  */
2528169689Skan
2529169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2530169689Skan    {
2531169689Skan      tree attrs;
2532169689Skan      struct c_declarator *inner;
2533169689Skan      c_parser_consume_token (parser);
2534169689Skan      attrs = c_parser_attributes (parser);
2535169689Skan      if (kind != C_DTR_NORMAL
2536169689Skan	  && (c_parser_next_token_starts_declspecs (parser)
2537169689Skan	      || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
2538169689Skan	{
2539169689Skan	  struct c_arg_info *args
2540169689Skan	    = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
2541169689Skan					 attrs);
2542169689Skan	  if (args == NULL)
2543169689Skan	    return NULL;
2544169689Skan	  else
2545169689Skan	    {
2546169689Skan	      inner
2547169689Skan		= build_function_declarator (args,
2548169689Skan					     build_id_declarator (NULL_TREE));
2549169689Skan	      return c_parser_direct_declarator_inner (parser, *seen_id,
2550169689Skan						       inner);
2551169689Skan	    }
2552169689Skan	}
2553169689Skan      /* A parenthesized declarator.  */
2554169689Skan      inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
2555169689Skan      if (inner != NULL && attrs != NULL)
2556169689Skan	inner = build_attrs_declarator (attrs, inner);
2557169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
2558169689Skan	{
2559169689Skan	  c_parser_consume_token (parser);
2560169689Skan	  if (inner == NULL)
2561169689Skan	    return NULL;
2562169689Skan	  else
2563169689Skan	    return c_parser_direct_declarator_inner (parser, *seen_id, inner);
2564169689Skan	}
2565169689Skan      else
2566169689Skan	{
2567169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2568169689Skan				     "expected %<)%>");
2569169689Skan	  return NULL;
2570169689Skan	}
2571169689Skan    }
2572169689Skan  else
2573169689Skan    {
2574169689Skan      if (kind == C_DTR_NORMAL)
2575169689Skan	{
2576169689Skan	  c_parser_error (parser, "expected identifier or %<(%>");
2577169689Skan	  return NULL;
2578169689Skan	}
2579169689Skan      else
2580169689Skan	return build_id_declarator (NULL_TREE);
2581169689Skan    }
2582169689Skan}
2583169689Skan
2584169689Skan/* Parse part of a direct declarator or direct abstract declarator,
2585169689Skan   given that some (in INNER) has already been parsed; ID_PRESENT is
2586169689Skan   true if an identifier is present, false for an abstract
2587169689Skan   declarator.  */
2588169689Skan
2589169689Skanstatic struct c_declarator *
2590169689Skanc_parser_direct_declarator_inner (c_parser *parser, bool id_present,
2591169689Skan				  struct c_declarator *inner)
2592169689Skan{
2593169689Skan  /* Parse a sequence of array declarators and parameter lists.  */
2594169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
2595169689Skan    {
2596169689Skan      struct c_declarator *declarator;
2597169689Skan      struct c_declspecs *quals_attrs = build_null_declspecs ();
2598169689Skan      bool static_seen;
2599169689Skan      bool star_seen;
2600169689Skan      tree dimen;
2601169689Skan      c_parser_consume_token (parser);
2602169689Skan      c_parser_declspecs (parser, quals_attrs, false, false, true);
2603169689Skan      static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
2604169689Skan      if (static_seen)
2605169689Skan	c_parser_consume_token (parser);
2606169689Skan      if (static_seen && !quals_attrs->declspecs_seen_p)
2607169689Skan	c_parser_declspecs (parser, quals_attrs, false, false, true);
2608169689Skan      if (!quals_attrs->declspecs_seen_p)
2609169689Skan	quals_attrs = NULL;
2610169689Skan      /* If "static" is present, there must be an array dimension.
2611169689Skan	 Otherwise, there may be a dimension, "*", or no
2612169689Skan	 dimension.  */
2613169689Skan      if (static_seen)
2614169689Skan	{
2615169689Skan	  star_seen = false;
2616169689Skan	  dimen = c_parser_expr_no_commas (parser, NULL).value;
2617169689Skan	}
2618169689Skan      else
2619169689Skan	{
2620169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
2621169689Skan	    {
2622169689Skan	      dimen = NULL_TREE;
2623169689Skan	      star_seen = false;
2624169689Skan	    }
2625169689Skan	  else if (c_parser_next_token_is (parser, CPP_MULT))
2626169689Skan	    {
2627169689Skan	      if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
2628169689Skan		{
2629169689Skan		  dimen = NULL_TREE;
2630169689Skan		  star_seen = true;
2631169689Skan		  c_parser_consume_token (parser);
2632169689Skan		}
2633169689Skan	      else
2634169689Skan		{
2635169689Skan		  star_seen = false;
2636169689Skan		  dimen = c_parser_expr_no_commas (parser, NULL).value;
2637169689Skan		}
2638169689Skan	    }
2639169689Skan	  else
2640169689Skan	    {
2641169689Skan	      star_seen = false;
2642169689Skan	      dimen = c_parser_expr_no_commas (parser, NULL).value;
2643169689Skan	    }
2644169689Skan	}
2645169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
2646169689Skan	c_parser_consume_token (parser);
2647169689Skan      else
2648169689Skan	{
2649169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
2650169689Skan				     "expected %<]%>");
2651169689Skan	  return NULL;
2652169689Skan	}
2653169689Skan      declarator = build_array_declarator (dimen, quals_attrs, static_seen,
2654169689Skan					   star_seen);
2655169689Skan      if (declarator == NULL)
2656169689Skan	return NULL;
2657169689Skan      inner = set_array_declarator_inner (declarator, inner, !id_present);
2658169689Skan      return c_parser_direct_declarator_inner (parser, id_present, inner);
2659169689Skan    }
2660169689Skan  else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2661169689Skan    {
2662169689Skan      tree attrs;
2663169689Skan      struct c_arg_info *args;
2664169689Skan      c_parser_consume_token (parser);
2665169689Skan      attrs = c_parser_attributes (parser);
2666169689Skan      args = c_parser_parms_declarator (parser, id_present, attrs);
2667169689Skan      if (args == NULL)
2668169689Skan	return NULL;
2669169689Skan      else
2670169689Skan	{
2671169689Skan	  inner = build_function_declarator (args, inner);
2672169689Skan	  return c_parser_direct_declarator_inner (parser, id_present, inner);
2673169689Skan	}
2674169689Skan    }
2675169689Skan  return inner;
2676169689Skan}
2677169689Skan
2678169689Skan/* Parse a parameter list or identifier list, including the closing
2679169689Skan   parenthesis but not the opening one.  ATTRS are the attributes at
2680169689Skan   the start of the list.  ID_LIST_OK is true if an identifier list is
2681169689Skan   acceptable; such a list must not have attributes at the start.  */
2682169689Skan
2683169689Skanstatic struct c_arg_info *
2684169689Skanc_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs)
2685169689Skan{
2686169689Skan  push_scope ();
2687169689Skan  declare_parm_level ();
2688169689Skan  /* If the list starts with an identifier, it is an identifier list.
2689169689Skan     Otherwise, it is either a prototype list or an empty list.  */
2690169689Skan  if (id_list_ok
2691169689Skan      && !attrs
2692169689Skan      && c_parser_next_token_is (parser, CPP_NAME)
2693169689Skan      && c_parser_peek_token (parser)->id_kind == C_ID_ID)
2694169689Skan    {
2695169689Skan      tree list = NULL_TREE, *nextp = &list;
2696169689Skan      while (c_parser_next_token_is (parser, CPP_NAME)
2697169689Skan	     && c_parser_peek_token (parser)->id_kind == C_ID_ID)
2698169689Skan	{
2699169689Skan	  *nextp = build_tree_list (NULL_TREE,
2700169689Skan				    c_parser_peek_token (parser)->value);
2701169689Skan	  nextp = & TREE_CHAIN (*nextp);
2702169689Skan	  c_parser_consume_token (parser);
2703169689Skan	  if (c_parser_next_token_is_not (parser, CPP_COMMA))
2704169689Skan	    break;
2705169689Skan	  c_parser_consume_token (parser);
2706169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
2707169689Skan	    {
2708169689Skan	      c_parser_error (parser, "expected identifier");
2709169689Skan	      break;
2710169689Skan	    }
2711169689Skan	}
2712169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
2713169689Skan	{
2714169689Skan	  struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info);
2715169689Skan	  ret->parms = 0;
2716169689Skan	  ret->tags = 0;
2717169689Skan	  ret->types = list;
2718169689Skan	  ret->others = 0;
2719169689Skan	  ret->pending_sizes = 0;
2720169689Skan	  ret->had_vla_unspec = 0;
2721169689Skan	  c_parser_consume_token (parser);
2722169689Skan	  pop_scope ();
2723169689Skan	  return ret;
2724169689Skan	}
2725169689Skan      else
2726169689Skan	{
2727169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2728169689Skan				     "expected %<)%>");
2729169689Skan	  pop_scope ();
2730169689Skan	  return NULL;
2731169689Skan	}
2732169689Skan    }
2733169689Skan  else
2734169689Skan    {
2735169689Skan      struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs);
2736169689Skan      pop_scope ();
2737169689Skan      return ret;
2738169689Skan    }
2739169689Skan}
2740169689Skan
2741169689Skan/* Parse a parameter list (possibly empty), including the closing
2742169689Skan   parenthesis but not the opening one.  ATTRS are the attributes at
2743169689Skan   the start of the list.  */
2744169689Skan
2745169689Skanstatic struct c_arg_info *
2746169689Skanc_parser_parms_list_declarator (c_parser *parser, tree attrs)
2747169689Skan{
2748169689Skan  bool good_parm = false;
2749169689Skan  /* ??? Following the old parser, forward parameter declarations may
2750169689Skan     use abstract declarators, and if no real parameter declarations
2751169689Skan     follow the forward declarations then this is not diagnosed.  Also
2752169689Skan     note as above that attributes are ignored as the only contents of
2753169689Skan     the parentheses, or as the only contents after forward
2754169689Skan     declarations.  */
2755169689Skan  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
2756169689Skan    {
2757169689Skan      struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info);
2758169689Skan      ret->parms = 0;
2759169689Skan      ret->tags = 0;
2760169689Skan      ret->types = 0;
2761169689Skan      ret->others = 0;
2762169689Skan      ret->pending_sizes = 0;
2763169689Skan      ret->had_vla_unspec = 0;
2764169689Skan      c_parser_consume_token (parser);
2765169689Skan      return ret;
2766169689Skan    }
2767169689Skan  if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
2768169689Skan    {
2769169689Skan      struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info);
2770169689Skan      ret->parms = 0;
2771169689Skan      ret->tags = 0;
2772169689Skan      ret->others = 0;
2773169689Skan      ret->pending_sizes = 0;
2774169689Skan      ret->had_vla_unspec = 0;
2775169689Skan      /* Suppress -Wold-style-definition for this case.  */
2776169689Skan      ret->types = error_mark_node;
2777169689Skan      error ("ISO C requires a named argument before %<...%>");
2778169689Skan      c_parser_consume_token (parser);
2779169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
2780169689Skan	{
2781169689Skan	  c_parser_consume_token (parser);
2782169689Skan	  return ret;
2783169689Skan	}
2784169689Skan      else
2785169689Skan	{
2786169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2787169689Skan				     "expected %<)%>");
2788169689Skan	  return NULL;
2789169689Skan	}
2790169689Skan    }
2791169689Skan  /* Nonempty list of parameters, either terminated with semicolon
2792169689Skan     (forward declarations; recurse) or with close parenthesis (normal
2793169689Skan     function) or with ", ... )" (variadic function).  */
2794169689Skan  while (true)
2795169689Skan    {
2796169689Skan      /* Parse a parameter.  */
2797169689Skan      struct c_parm *parm = c_parser_parameter_declaration (parser, attrs);
2798169689Skan      attrs = NULL_TREE;
2799169689Skan      if (parm != NULL)
2800169689Skan	{
2801169689Skan	  good_parm = true;
2802169689Skan	  push_parm_decl (parm);
2803169689Skan	}
2804169689Skan      if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2805169689Skan	{
2806169689Skan	  tree new_attrs;
2807169689Skan	  c_parser_consume_token (parser);
2808169689Skan	  mark_forward_parm_decls ();
2809169689Skan	  new_attrs = c_parser_attributes (parser);
2810169689Skan	  return c_parser_parms_list_declarator (parser, new_attrs);
2811169689Skan	}
2812169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
2813169689Skan	{
2814169689Skan	  c_parser_consume_token (parser);
2815169689Skan	  if (good_parm)
2816169689Skan	    return get_parm_info (false);
2817169689Skan	  else
2818169689Skan	    {
2819169689Skan	      struct c_arg_info *ret
2820169689Skan		= XOBNEW (&parser_obstack, struct c_arg_info);
2821169689Skan	      ret->parms = 0;
2822169689Skan	      ret->tags = 0;
2823169689Skan	      ret->types = 0;
2824169689Skan	      ret->others = 0;
2825169689Skan	      ret->pending_sizes = 0;
2826169689Skan	      ret->had_vla_unspec = 0;
2827169689Skan	      return ret;
2828169689Skan	    }
2829169689Skan	}
2830169689Skan      if (!c_parser_require (parser, CPP_COMMA,
2831169689Skan			     "expected %<;%>, %<,%> or %<)%>"))
2832169689Skan	{
2833169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
2834169689Skan	  return NULL;
2835169689Skan	}
2836169689Skan      if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
2837169689Skan	{
2838169689Skan	  c_parser_consume_token (parser);
2839169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
2840169689Skan	    {
2841169689Skan	      c_parser_consume_token (parser);
2842169689Skan	      if (good_parm)
2843169689Skan		return get_parm_info (true);
2844169689Skan	      else
2845169689Skan		{
2846169689Skan		  struct c_arg_info *ret
2847169689Skan		    = XOBNEW (&parser_obstack, struct c_arg_info);
2848169689Skan		  ret->parms = 0;
2849169689Skan		  ret->tags = 0;
2850169689Skan		  ret->types = 0;
2851169689Skan		  ret->others = 0;
2852169689Skan		  ret->pending_sizes = 0;
2853169689Skan		  ret->had_vla_unspec = 0;
2854169689Skan		  return ret;
2855169689Skan		}
2856169689Skan	    }
2857169689Skan	  else
2858169689Skan	    {
2859169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2860169689Skan					 "expected %<)%>");
2861169689Skan	      return NULL;
2862169689Skan	    }
2863169689Skan	}
2864169689Skan    }
2865169689Skan}
2866169689Skan
2867169689Skan/* Parse a parameter declaration.  ATTRS are the attributes at the
2868169689Skan   start of the declaration if it is the first parameter.  */
2869169689Skan
2870169689Skanstatic struct c_parm *
2871169689Skanc_parser_parameter_declaration (c_parser *parser, tree attrs)
2872169689Skan{
2873169689Skan  struct c_declspecs *specs;
2874169689Skan  struct c_declarator *declarator;
2875169689Skan  tree prefix_attrs;
2876169689Skan  tree postfix_attrs = NULL_TREE;
2877169689Skan  bool dummy = false;
2878169689Skan  if (!c_parser_next_token_starts_declspecs (parser))
2879169689Skan    {
2880169689Skan      /* ??? In some Objective-C cases '...' isn't applicable so there
2881169689Skan	 should be a different message.  */
2882169689Skan      c_parser_error (parser,
2883169689Skan		      "expected declaration specifiers or %<...%>");
2884169689Skan      c_parser_skip_to_end_of_parameter (parser);
2885169689Skan      return NULL;
2886169689Skan    }
2887169689Skan  specs = build_null_declspecs ();
2888169689Skan  if (attrs)
2889169689Skan    {
2890169689Skan      declspecs_add_attrs (specs, attrs);
2891169689Skan      attrs = NULL_TREE;
2892169689Skan    }
2893169689Skan  c_parser_declspecs (parser, specs, true, true, true);
2894169689Skan  finish_declspecs (specs);
2895169689Skan  pending_xref_error ();
2896169689Skan  prefix_attrs = specs->attrs;
2897169689Skan  specs->attrs = NULL_TREE;
2898169689Skan  declarator = c_parser_declarator (parser, specs->type_seen_p,
2899169689Skan				    C_DTR_PARM, &dummy);
2900169689Skan  if (declarator == NULL)
2901169689Skan    {
2902169689Skan      c_parser_skip_until_found (parser, CPP_COMMA, NULL);
2903169689Skan      return NULL;
2904169689Skan    }
2905169689Skan  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2906169689Skan    postfix_attrs = c_parser_attributes (parser);
2907169689Skan  return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
2908169689Skan		       declarator);
2909169689Skan}
2910169689Skan
2911169689Skan/* Parse a string literal in an asm expression.  It should not be
2912169689Skan   translated, and wide string literals are an error although
2913169689Skan   permitted by the syntax.  This is a GNU extension.
2914169689Skan
2915169689Skan   asm-string-literal:
2916169689Skan     string-literal
2917169689Skan
2918169689Skan   ??? At present, following the old parser, the caller needs to have
2919169689Skan   set c_lex_string_translate to 0.  It would be better to follow the
2920169689Skan   C++ parser rather than using the c_lex_string_translate kludge.  */
2921169689Skan
2922169689Skanstatic tree
2923169689Skanc_parser_asm_string_literal (c_parser *parser)
2924169689Skan{
2925169689Skan  tree str;
2926169689Skan  if (c_parser_next_token_is (parser, CPP_STRING))
2927169689Skan    {
2928169689Skan      str = c_parser_peek_token (parser)->value;
2929169689Skan      c_parser_consume_token (parser);
2930169689Skan    }
2931169689Skan  else if (c_parser_next_token_is (parser, CPP_WSTRING))
2932169689Skan    {
2933169689Skan      error ("wide string literal in %<asm%>");
2934169689Skan      str = build_string (1, "");
2935169689Skan      c_parser_consume_token (parser);
2936169689Skan    }
2937169689Skan  else
2938169689Skan    {
2939169689Skan      c_parser_error (parser, "expected string literal");
2940169689Skan      str = NULL_TREE;
2941169689Skan    }
2942169689Skan  return str;
2943169689Skan}
2944169689Skan
2945169689Skan/* Parse a simple asm expression.  This is used in restricted
2946169689Skan   contexts, where a full expression with inputs and outputs does not
2947169689Skan   make sense.  This is a GNU extension.
2948169689Skan
2949169689Skan   simple-asm-expr:
2950169689Skan     asm ( asm-string-literal )
2951169689Skan*/
2952169689Skan
2953169689Skanstatic tree
2954169689Skanc_parser_simple_asm_expr (c_parser *parser)
2955169689Skan{
2956169689Skan  tree str;
2957169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
2958169689Skan  /* ??? Follow the C++ parser rather than using the
2959169689Skan     c_lex_string_translate kludge.  */
2960169689Skan  c_lex_string_translate = 0;
2961169689Skan  c_parser_consume_token (parser);
2962169689Skan  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2963169689Skan    {
2964169689Skan      c_lex_string_translate = 1;
2965169689Skan      return NULL_TREE;
2966169689Skan    }
2967169689Skan  str = c_parser_asm_string_literal (parser);
2968169689Skan  c_lex_string_translate = 1;
2969169689Skan  if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
2970169689Skan    {
2971169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
2972169689Skan      return NULL_TREE;
2973169689Skan    }
2974169689Skan  return str;
2975169689Skan}
2976169689Skan
2977169689Skan/* Parse (possibly empty) attributes.  This is a GNU extension.
2978169689Skan
2979169689Skan   attributes:
2980169689Skan     empty
2981169689Skan     attributes attribute
2982169689Skan
2983169689Skan   attribute:
2984169689Skan     __attribute__ ( ( attribute-list ) )
2985169689Skan
2986169689Skan   attribute-list:
2987169689Skan     attrib
2988169689Skan     attribute_list , attrib
2989169689Skan
2990169689Skan   attrib:
2991169689Skan     empty
2992169689Skan     any-word
2993169689Skan     any-word ( identifier )
2994169689Skan     any-word ( identifier , nonempty-expr-list )
2995169689Skan     any-word ( expr-list )
2996169689Skan
2997169689Skan   where the "identifier" must not be declared as a type, and
2998169689Skan   "any-word" may be any identifier (including one declared as a
2999169689Skan   type), a reserved word storage class specifier, type specifier or
3000169689Skan   type qualifier.  ??? This still leaves out most reserved keywords
3001169689Skan   (following the old parser), shouldn't we include them, and why not
3002169689Skan   allow identifiers declared as types to start the arguments?  */
3003169689Skan
3004169689Skanstatic tree
3005169689Skanc_parser_attributes (c_parser *parser)
3006169689Skan{
3007169689Skan  tree attrs = NULL_TREE;
3008169689Skan  while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3009169689Skan    {
3010169689Skan      /* ??? Follow the C++ parser rather than using the
3011169689Skan	 c_lex_string_translate kludge.  */
3012169689Skan      c_lex_string_translate = 0;
3013169689Skan      c_parser_consume_token (parser);
3014169689Skan      if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
3015169689Skan	{
3016169689Skan	  c_lex_string_translate = 1;
3017169689Skan	  return attrs;
3018169689Skan	}
3019169689Skan      if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
3020169689Skan	{
3021169689Skan	  c_lex_string_translate = 1;
3022169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3023169689Skan	  return attrs;
3024169689Skan	}
3025169689Skan      /* Parse the attribute list.  */
3026169689Skan      while (c_parser_next_token_is (parser, CPP_COMMA)
3027169689Skan	     || c_parser_next_token_is (parser, CPP_NAME)
3028169689Skan	     || c_parser_next_token_is (parser, CPP_KEYWORD))
3029169689Skan	{
3030169689Skan	  tree attr, attr_name, attr_args;
3031169689Skan	  if (c_parser_next_token_is (parser, CPP_COMMA))
3032169689Skan	    {
3033169689Skan	      c_parser_consume_token (parser);
3034169689Skan	      continue;
3035169689Skan	    }
3036169689Skan	  if (c_parser_next_token_is (parser, CPP_KEYWORD))
3037169689Skan	    {
3038169689Skan	      /* ??? See comment above about what keywords are
3039169689Skan		 accepted here.  */
3040169689Skan	      bool ok;
3041169689Skan	      switch (c_parser_peek_token (parser)->keyword)
3042169689Skan		{
3043169689Skan		case RID_STATIC:
3044169689Skan		case RID_UNSIGNED:
3045169689Skan		case RID_LONG:
3046169689Skan		case RID_CONST:
3047169689Skan		case RID_EXTERN:
3048169689Skan		case RID_REGISTER:
3049169689Skan		case RID_TYPEDEF:
3050169689Skan		case RID_SHORT:
3051169689Skan		case RID_INLINE:
3052169689Skan		case RID_VOLATILE:
3053169689Skan		case RID_SIGNED:
3054169689Skan		case RID_AUTO:
3055169689Skan		case RID_RESTRICT:
3056169689Skan		case RID_COMPLEX:
3057169689Skan		case RID_THREAD:
3058169689Skan		case RID_INT:
3059169689Skan		case RID_CHAR:
3060169689Skan		case RID_FLOAT:
3061169689Skan		case RID_DOUBLE:
3062169689Skan		case RID_VOID:
3063169689Skan		case RID_DFLOAT32:
3064169689Skan		case RID_DFLOAT64:
3065169689Skan		case RID_DFLOAT128:
3066169689Skan		case RID_BOOL:
3067169689Skan		  ok = true;
3068169689Skan		  break;
3069169689Skan		default:
3070169689Skan		  ok = false;
3071169689Skan		  break;
3072169689Skan		}
3073169689Skan	      if (!ok)
3074169689Skan		break;
3075169689Skan	    }
3076169689Skan	  attr_name = c_parser_peek_token (parser)->value;
3077169689Skan	  c_parser_consume_token (parser);
3078169689Skan	  if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
3079169689Skan	    {
3080169689Skan	      attr = build_tree_list (attr_name, NULL_TREE);
3081169689Skan	      attrs = chainon (attrs, attr);
3082169689Skan	      continue;
3083169689Skan	    }
3084169689Skan	  c_parser_consume_token (parser);
3085169689Skan	  /* Parse the attribute contents.  If they start with an
3086169689Skan	     identifier which is followed by a comma or close
3087169689Skan	     parenthesis, then the arguments start with that
3088169689Skan	     identifier; otherwise they are an expression list.  */
3089169689Skan	  if (c_parser_next_token_is (parser, CPP_NAME)
3090169689Skan	      && c_parser_peek_token (parser)->id_kind == C_ID_ID
3091169689Skan	      && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
3092169689Skan		  || (c_parser_peek_2nd_token (parser)->type
3093169689Skan		      == CPP_CLOSE_PAREN)))
3094169689Skan	    {
3095169689Skan	      tree arg1 = c_parser_peek_token (parser)->value;
3096169689Skan	      c_parser_consume_token (parser);
3097169689Skan	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3098169689Skan		attr_args = build_tree_list (NULL_TREE, arg1);
3099169689Skan	      else
3100169689Skan		{
3101169689Skan		  c_parser_consume_token (parser);
3102169689Skan		  attr_args = tree_cons (NULL_TREE, arg1,
3103169689Skan					 c_parser_expr_list (parser, false));
3104169689Skan		}
3105169689Skan	    }
3106169689Skan	  else
3107169689Skan	    {
3108169689Skan	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3109169689Skan		attr_args = NULL_TREE;
3110169689Skan	      else
3111169689Skan		attr_args = c_parser_expr_list (parser, false);
3112169689Skan	    }
3113169689Skan	  attr = build_tree_list (attr_name, attr_args);
3114169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3115169689Skan	    c_parser_consume_token (parser);
3116169689Skan	  else
3117169689Skan	    {
3118169689Skan	      c_lex_string_translate = 1;
3119169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3120169689Skan					 "expected %<)%>");
3121169689Skan	      return attrs;
3122169689Skan	    }
3123169689Skan	  attrs = chainon (attrs, attr);
3124169689Skan	}
3125169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3126169689Skan	c_parser_consume_token (parser);
3127169689Skan      else
3128169689Skan	{
3129169689Skan	  c_lex_string_translate = 1;
3130169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3131169689Skan				     "expected %<)%>");
3132169689Skan	  return attrs;
3133169689Skan	}
3134169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3135169689Skan	c_parser_consume_token (parser);
3136169689Skan      else
3137169689Skan	{
3138169689Skan	  c_lex_string_translate = 1;
3139169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3140169689Skan				     "expected %<)%>");
3141169689Skan	  return attrs;
3142169689Skan	}
3143169689Skan      c_lex_string_translate = 1;
3144169689Skan    }
3145169689Skan  return attrs;
3146169689Skan}
3147169689Skan
3148169689Skan/* Parse a type name (C90 6.5.5, C99 6.7.6).
3149169689Skan
3150169689Skan   type-name:
3151169689Skan     specifier-qualifier-list abstract-declarator[opt]
3152169689Skan*/
3153169689Skan
3154169689Skanstatic struct c_type_name *
3155169689Skanc_parser_type_name (c_parser *parser)
3156169689Skan{
3157169689Skan  struct c_declspecs *specs = build_null_declspecs ();
3158169689Skan  struct c_declarator *declarator;
3159169689Skan  struct c_type_name *ret;
3160169689Skan  bool dummy = false;
3161169689Skan  c_parser_declspecs (parser, specs, false, true, true);
3162169689Skan  if (!specs->declspecs_seen_p)
3163169689Skan    {
3164169689Skan      c_parser_error (parser, "expected specifier-qualifier-list");
3165169689Skan      return NULL;
3166169689Skan    }
3167169689Skan  pending_xref_error ();
3168169689Skan  finish_declspecs (specs);
3169169689Skan  declarator = c_parser_declarator (parser, specs->type_seen_p,
3170169689Skan				    C_DTR_ABSTRACT, &dummy);
3171169689Skan  if (declarator == NULL)
3172169689Skan    return NULL;
3173169689Skan  ret = XOBNEW (&parser_obstack, struct c_type_name);
3174169689Skan  ret->specs = specs;
3175169689Skan  ret->declarator = declarator;
3176169689Skan  return ret;
3177169689Skan}
3178169689Skan
3179169689Skan/* Parse an initializer (C90 6.5.7, C99 6.7.8).
3180169689Skan
3181169689Skan   initializer:
3182169689Skan     assignment-expression
3183169689Skan     { initializer-list }
3184169689Skan     { initializer-list , }
3185169689Skan
3186169689Skan   initializer-list:
3187169689Skan     designation[opt] initializer
3188169689Skan     initializer-list , designation[opt] initializer
3189169689Skan
3190169689Skan   designation:
3191169689Skan     designator-list =
3192169689Skan
3193169689Skan   designator-list:
3194169689Skan     designator
3195169689Skan     designator-list designator
3196169689Skan
3197169689Skan   designator:
3198169689Skan     array-designator
3199169689Skan     . identifier
3200169689Skan
3201169689Skan   array-designator:
3202169689Skan     [ constant-expression ]
3203169689Skan
3204169689Skan   GNU extensions:
3205169689Skan
3206169689Skan   initializer:
3207169689Skan     { }
3208169689Skan
3209169689Skan   designation:
3210169689Skan     array-designator
3211169689Skan     identifier :
3212169689Skan
3213169689Skan   array-designator:
3214169689Skan     [ constant-expression ... constant-expression ]
3215169689Skan
3216169689Skan   Any expression without commas is accepted in the syntax for the
3217169689Skan   constant-expressions, with non-constant expressions rejected later.
3218169689Skan
3219169689Skan   This function is only used for top-level initializers; for nested
3220169689Skan   ones, see c_parser_initval.  */
3221169689Skan
3222169689Skanstatic struct c_expr
3223169689Skanc_parser_initializer (c_parser *parser)
3224169689Skan{
3225169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3226169689Skan    return c_parser_braced_init (parser, NULL_TREE, false);
3227169689Skan  else
3228169689Skan    {
3229169689Skan      struct c_expr ret;
3230169689Skan      ret = c_parser_expr_no_commas (parser, NULL);
3231169689Skan      if (TREE_CODE (ret.value) != STRING_CST
3232169689Skan	  && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
3233169689Skan	ret = default_function_array_conversion (ret);
3234169689Skan      return ret;
3235169689Skan    }
3236169689Skan}
3237169689Skan
3238169689Skan/* Parse a braced initializer list.  TYPE is the type specified for a
3239169689Skan   compound literal, and NULL_TREE for other initializers and for
3240169689Skan   nested braced lists.  NESTED_P is true for nested braced lists,
3241169689Skan   false for the list of a compound literal or the list that is the
3242169689Skan   top-level initializer in a declaration.  */
3243169689Skan
3244169689Skanstatic struct c_expr
3245169689Skanc_parser_braced_init (c_parser *parser, tree type, bool nested_p)
3246169689Skan{
3247169689Skan  gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
3248169689Skan  c_parser_consume_token (parser);
3249169689Skan  if (nested_p)
3250169689Skan    push_init_level (0);
3251169689Skan  else
3252169689Skan    really_start_incremental_init (type);
3253169689Skan  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3254169689Skan    {
3255169689Skan      if (pedantic)
3256169689Skan	pedwarn ("ISO C forbids empty initializer braces");
3257169689Skan    }
3258169689Skan  else
3259169689Skan    {
3260169689Skan      /* Parse a non-empty initializer list, possibly with a trailing
3261169689Skan	 comma.  */
3262169689Skan      while (true)
3263169689Skan	{
3264169689Skan	  c_parser_initelt (parser);
3265169689Skan	  if (parser->error)
3266169689Skan	    break;
3267169689Skan	  if (c_parser_next_token_is (parser, CPP_COMMA))
3268169689Skan	    c_parser_consume_token (parser);
3269169689Skan	  else
3270169689Skan	    break;
3271169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3272169689Skan	    break;
3273169689Skan	}
3274169689Skan    }
3275169689Skan  if (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
3276169689Skan    {
3277169689Skan      struct c_expr ret;
3278169689Skan      ret.value = error_mark_node;
3279169689Skan      ret.original_code = ERROR_MARK;
3280169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>");
3281169689Skan      return ret;
3282169689Skan    }
3283169689Skan  c_parser_consume_token (parser);
3284169689Skan  return pop_init_level (0);
3285169689Skan}
3286169689Skan
3287169689Skan/* Parse a nested initializer, including designators.  */
3288169689Skan
3289169689Skanstatic void
3290169689Skanc_parser_initelt (c_parser *parser)
3291169689Skan{
3292169689Skan  /* Parse any designator or designator list.  A single array
3293169689Skan     designator may have the subsequent "=" omitted in GNU C, but a
3294169689Skan     longer list or a structure member designator may not.  */
3295169689Skan  if (c_parser_next_token_is (parser, CPP_NAME)
3296169689Skan      && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
3297169689Skan    {
3298169689Skan      /* Old-style structure member designator.  */
3299169689Skan      set_init_label (c_parser_peek_token (parser)->value);
3300169689Skan      if (pedantic)
3301169689Skan	pedwarn ("obsolete use of designated initializer with %<:%>");
3302169689Skan      c_parser_consume_token (parser);
3303169689Skan      c_parser_consume_token (parser);
3304169689Skan    }
3305169689Skan  else
3306169689Skan    {
3307169689Skan      /* des_seen is 0 if there have been no designators, 1 if there
3308169689Skan	 has been a single array designator and 2 otherwise.  */
3309169689Skan      int des_seen = 0;
3310169689Skan      while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3311169689Skan	     || c_parser_next_token_is (parser, CPP_DOT))
3312169689Skan	{
3313169689Skan	  int des_prev = des_seen;
3314169689Skan	  if (des_seen < 2)
3315169689Skan	    des_seen++;
3316169689Skan	  if (c_parser_next_token_is (parser, CPP_DOT))
3317169689Skan	    {
3318169689Skan	      des_seen = 2;
3319169689Skan	      c_parser_consume_token (parser);
3320169689Skan	      if (c_parser_next_token_is (parser, CPP_NAME))
3321169689Skan		{
3322169689Skan		  set_init_label (c_parser_peek_token (parser)->value);
3323169689Skan		  c_parser_consume_token (parser);
3324169689Skan		}
3325169689Skan	      else
3326169689Skan		{
3327169689Skan		  struct c_expr init;
3328169689Skan		  init.value = error_mark_node;
3329169689Skan		  init.original_code = ERROR_MARK;
3330169689Skan		  c_parser_error (parser, "expected identifier");
3331169689Skan		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
3332169689Skan		  process_init_element (init);
3333169689Skan		  return;
3334169689Skan		}
3335169689Skan	    }
3336169689Skan	  else
3337169689Skan	    {
3338169689Skan	      tree first, second;
3339169689Skan	      /* ??? Following the old parser, [ objc-receiver
3340169689Skan		 objc-message-args ] is accepted as an initializer,
3341169689Skan		 being distinguished from a designator by what follows
3342169689Skan		 the first assignment expression inside the square
3343169689Skan		 brackets, but after a first array designator a
3344169689Skan		 subsequent square bracket is for Objective-C taken to
3345169689Skan		 start an expression, using the obsolete form of
3346169689Skan		 designated initializer without '=', rather than
3347169689Skan		 possibly being a second level of designation: in LALR
3348169689Skan		 terms, the '[' is shifted rather than reducing
3349169689Skan		 designator to designator-list.  */
3350169689Skan	      if (des_prev == 1 && c_dialect_objc ())
3351169689Skan		{
3352169689Skan		  des_seen = des_prev;
3353169689Skan		  break;
3354169689Skan		}
3355169689Skan	      if (des_prev == 0 && c_dialect_objc ())
3356169689Skan		{
3357169689Skan		  /* This might be an array designator or an
3358169689Skan		     Objective-C message expression.  If the former,
3359169689Skan		     continue parsing here; if the latter, parse the
3360169689Skan		     remainder of the initializer given the starting
3361169689Skan		     primary-expression.  ??? It might make sense to
3362169689Skan		     distinguish when des_prev == 1 as well; see
3363169689Skan		     previous comment.  */
3364169689Skan		  tree rec, args;
3365169689Skan		  struct c_expr mexpr;
3366169689Skan		  c_parser_consume_token (parser);
3367169689Skan		  if (c_parser_peek_token (parser)->type == CPP_NAME
3368169689Skan		      && ((c_parser_peek_token (parser)->id_kind
3369169689Skan			   == C_ID_TYPENAME)
3370169689Skan			  || (c_parser_peek_token (parser)->id_kind
3371169689Skan			      == C_ID_CLASSNAME)))
3372169689Skan		    {
3373169689Skan		      /* Type name receiver.  */
3374169689Skan		      tree id = c_parser_peek_token (parser)->value;
3375169689Skan		      c_parser_consume_token (parser);
3376169689Skan		      rec = objc_get_class_reference (id);
3377169689Skan		      goto parse_message_args;
3378169689Skan		    }
3379169689Skan		  first = c_parser_expr_no_commas (parser, NULL).value;
3380169689Skan		  if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
3381169689Skan		      || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3382169689Skan		    goto array_desig_after_first;
3383169689Skan		  /* Expression receiver.  So far only one part
3384169689Skan		     without commas has been parsed; there might be
3385169689Skan		     more of the expression.  */
3386169689Skan		  rec = first;
3387169689Skan		  while (c_parser_next_token_is (parser, CPP_COMMA))
3388169689Skan		    {
3389169689Skan		      struct c_expr next;
3390169689Skan		      c_parser_consume_token (parser);
3391169689Skan		      next = c_parser_expr_no_commas (parser, NULL);
3392169689Skan		      next = default_function_array_conversion (next);
3393169689Skan		      rec = build_compound_expr (rec, next.value);
3394169689Skan		    }
3395169689Skan		parse_message_args:
3396169689Skan		  /* Now parse the objc-message-args.  */
3397169689Skan		  args = c_parser_objc_message_args (parser);
3398169689Skan		  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3399169689Skan					     "expected %<]%>");
3400169689Skan		  mexpr.value
3401169689Skan		    = objc_build_message_expr (build_tree_list (rec, args));
3402169689Skan		  mexpr.original_code = ERROR_MARK;
3403169689Skan		  /* Now parse and process the remainder of the
3404169689Skan		     initializer, starting with this message
3405169689Skan		     expression as a primary-expression.  */
3406169689Skan		  c_parser_initval (parser, &mexpr);
3407169689Skan		  return;
3408169689Skan		}
3409169689Skan	      c_parser_consume_token (parser);
3410169689Skan	      first = c_parser_expr_no_commas (parser, NULL).value;
3411169689Skan	    array_desig_after_first:
3412169689Skan	      if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3413169689Skan		{
3414169689Skan		  c_parser_consume_token (parser);
3415169689Skan		  second = c_parser_expr_no_commas (parser, NULL).value;
3416169689Skan		}
3417169689Skan	      else
3418169689Skan		second = NULL_TREE;
3419169689Skan	      if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3420169689Skan		{
3421169689Skan		  c_parser_consume_token (parser);
3422169689Skan		  set_init_index (first, second);
3423169689Skan		  if (pedantic && second)
3424169689Skan		    pedwarn ("ISO C forbids specifying range of "
3425169689Skan			     "elements to initialize");
3426169689Skan		}
3427169689Skan	      else
3428169689Skan		c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3429169689Skan					   "expected %<]%>");
3430169689Skan	    }
3431169689Skan	}
3432169689Skan      if (des_seen >= 1)
3433169689Skan	{
3434169689Skan	  if (c_parser_next_token_is (parser, CPP_EQ))
3435169689Skan	    {
3436169689Skan	      if (pedantic && !flag_isoc99)
3437169689Skan		pedwarn ("ISO C90 forbids specifying subobject to initialize");
3438169689Skan	      c_parser_consume_token (parser);
3439169689Skan	    }
3440169689Skan	  else
3441169689Skan	    {
3442169689Skan	      if (des_seen == 1)
3443169689Skan		{
3444169689Skan		  if (pedantic)
3445169689Skan		    pedwarn ("obsolete use of designated initializer "
3446169689Skan			     "without %<=%>");
3447169689Skan		}
3448169689Skan	      else
3449169689Skan		{
3450169689Skan		  struct c_expr init;
3451169689Skan		  init.value = error_mark_node;
3452169689Skan		  init.original_code = ERROR_MARK;
3453169689Skan		  c_parser_error (parser, "expected %<=%>");
3454169689Skan		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
3455169689Skan		  process_init_element (init);
3456169689Skan		  return;
3457169689Skan		}
3458169689Skan	    }
3459169689Skan	}
3460169689Skan    }
3461169689Skan  c_parser_initval (parser, NULL);
3462169689Skan}
3463169689Skan
3464169689Skan/* Parse a nested initializer; as c_parser_initializer but parses
3465169689Skan   initializers within braced lists, after any designators have been
3466169689Skan   applied.  If AFTER is not NULL then it is an Objective-C message
3467169689Skan   expression which is the primary-expression starting the
3468169689Skan   initializer.  */
3469169689Skan
3470169689Skanstatic void
3471169689Skanc_parser_initval (c_parser *parser, struct c_expr *after)
3472169689Skan{
3473169689Skan  struct c_expr init;
3474169689Skan  gcc_assert (!after || c_dialect_objc ());
3475169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
3476169689Skan    init = c_parser_braced_init (parser, NULL_TREE, true);
3477169689Skan  else
3478169689Skan    {
3479169689Skan      init = c_parser_expr_no_commas (parser, after);
3480169689Skan      if (init.value != NULL_TREE
3481169689Skan	  && TREE_CODE (init.value) != STRING_CST
3482169689Skan	  && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
3483169689Skan	init = default_function_array_conversion (init);
3484169689Skan    }
3485169689Skan  process_init_element (init);
3486169689Skan}
3487169689Skan
3488169689Skan/* Parse a compound statement (possibly a function body) (C90 6.6.2,
3489169689Skan   C99 6.8.2).
3490169689Skan
3491169689Skan   compound-statement:
3492169689Skan     { block-item-list[opt] }
3493169689Skan     { label-declarations block-item-list }
3494169689Skan
3495169689Skan   block-item-list:
3496169689Skan     block-item
3497169689Skan     block-item-list block-item
3498169689Skan
3499169689Skan   block-item:
3500169689Skan     nested-declaration
3501169689Skan     statement
3502169689Skan
3503169689Skan   nested-declaration:
3504169689Skan     declaration
3505169689Skan
3506169689Skan   GNU extensions:
3507169689Skan
3508169689Skan   compound-statement:
3509169689Skan     { label-declarations block-item-list }
3510169689Skan
3511169689Skan   nested-declaration:
3512169689Skan     __extension__ nested-declaration
3513169689Skan     nested-function-definition
3514169689Skan
3515169689Skan   label-declarations:
3516169689Skan     label-declaration
3517169689Skan     label-declarations label-declaration
3518169689Skan
3519169689Skan   label-declaration:
3520169689Skan     __label__ identifier-list ;
3521169689Skan
3522169689Skan   Allowing the mixing of declarations and code is new in C99.  The
3523169689Skan   GNU syntax also permits (not shown above) labels at the end of
3524169689Skan   compound statements, which yield an error.  We don't allow labels
3525169689Skan   on declarations; this might seem like a natural extension, but
3526169689Skan   there would be a conflict between attributes on the label and
3527169689Skan   prefix attributes on the declaration.  ??? The syntax follows the
3528169689Skan   old parser in requiring something after label declarations.
3529169689Skan   Although they are erroneous if the labels declared aren't defined,
3530169689Skan   is it useful for the syntax to be this way?
3531169689Skan
3532169689Skan   OpenMP:
3533169689Skan
3534169689Skan   block-item:
3535169689Skan     openmp-directive
3536169689Skan
3537169689Skan   openmp-directive:
3538169689Skan     barrier-directive
3539169689Skan     flush-directive  */
3540169689Skan
3541169689Skanstatic tree
3542169689Skanc_parser_compound_statement (c_parser *parser)
3543169689Skan{
3544169689Skan  tree stmt;
3545169689Skan  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
3546169689Skan    return error_mark_node;
3547169689Skan  stmt = c_begin_compound_stmt (true);
3548169689Skan  c_parser_compound_statement_nostart (parser);
3549169689Skan  return c_end_compound_stmt (stmt, true);
3550169689Skan}
3551169689Skan
3552169689Skan/* Parse a compound statement except for the opening brace.  This is
3553169689Skan   used for parsing both compound statements and statement expressions
3554169689Skan   (which follow different paths to handling the opening).  */
3555169689Skan
3556169689Skanstatic void
3557169689Skanc_parser_compound_statement_nostart (c_parser *parser)
3558169689Skan{
3559169689Skan  bool last_stmt = false;
3560169689Skan  bool last_label = false;
3561261188Spfg  /* APPLE LOCAL radar 5732232 - blocks (not in C++) */
3562261188Spfg  bool first_stmt = true;
3563169689Skan  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3564169689Skan    {
3565169689Skan      c_parser_consume_token (parser);
3566169689Skan      return;
3567169689Skan    }
3568169689Skan  if (c_parser_next_token_is_keyword (parser, RID_LABEL))
3569169689Skan    {
3570169689Skan      /* Read zero or more forward-declarations for labels that nested
3571169689Skan	 functions can jump to.  */
3572169689Skan      while (c_parser_next_token_is_keyword (parser, RID_LABEL))
3573261188Spfg		{
3574261188Spfg	c_parser_consume_token (parser);
3575261188Spfg	/* Any identifiers, including those declared as type names,
3576261188Spfg	 are OK here.  */
3577261188Spfg	while (true)
3578169689Skan	{
3579261188Spfg		tree label;
3580261188Spfg		if (c_parser_next_token_is_not (parser, CPP_NAME))
3581169689Skan		{
3582261188Spfg			c_parser_error (parser, "expected identifier");
3583261188Spfg			break;
3584169689Skan		}
3585261188Spfg		label
3586169689Skan		= declare_label (c_parser_peek_token (parser)->value);
3587261188Spfg		C_DECLARED_LABEL_FLAG (label) = 1;
3588261188Spfg		add_stmt (build_stmt (DECL_EXPR, label));
3589169689Skan		c_parser_consume_token (parser);
3590261188Spfg		if (c_parser_next_token_is (parser, CPP_COMMA))
3591261188Spfg			c_parser_consume_token (parser);
3592261188Spfg		else
3593261188Spfg			break;
3594169689Skan	}
3595261188Spfg	c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
3596261188Spfg		}
3597169689Skan      /* ??? Locating this diagnostic on the token after the
3598169689Skan	 declarations end follows the old parser, but it might be
3599169689Skan	 better to locate it where the declarations start instead.  */
3600169689Skan      if (pedantic)
3601169689Skan	pedwarn ("ISO C forbids label declarations");
3602169689Skan    }
3603169689Skan  /* We must now have at least one statement, label or declaration.  */
3604169689Skan  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3605169689Skan    {
3606169689Skan      c_parser_error (parser, "expected declaration or statement");
3607169689Skan      c_parser_consume_token (parser);
3608169689Skan      return;
3609169689Skan    }
3610169689Skan  while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
3611169689Skan    {
3612169689Skan      location_t loc = c_parser_peek_token (parser)->location;
3613169689Skan      if (c_parser_next_token_is_keyword (parser, RID_CASE)
3614261188Spfg	|| c_parser_next_token_is_keyword (parser, RID_DEFAULT)
3615261188Spfg	|| (c_parser_next_token_is (parser, CPP_NAME)
3616261188Spfg		&& c_parser_peek_2nd_token (parser)->type == CPP_COLON))
3617261188Spfg      {
3618261188Spfg	last_label = true;
3619261188Spfg	last_stmt = false;
3620261188Spfg	c_parser_label (parser);
3621261188Spfg      }
3622169689Skan      else if (!last_label
3623261188Spfg		 && c_parser_next_token_starts_declspecs (parser))
3624261188Spfg      {
3625261188Spfg	last_label = false;
3626261188Spfg	/* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
3627261188Spfg	c_parser_declaration_or_fndef (parser, true, true, true, true, NULL);
3628261188Spfg	if (last_stmt
3629261188Spfg		&& ((pedantic && !flag_isoc99)
3630261188Spfg			|| warn_declaration_after_statement))
3631261188Spfg		pedwarn_c90 ("%HISO C90 forbids mixed declarations and code",
3632261188Spfg					 &loc);
3633261188Spfg	last_stmt = false;
3634261188Spfg      }
3635169689Skan      else if (!last_label
3636261188Spfg		 && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3637261188Spfg      {
3638261188Spfg	/* __extension__ can start a declaration, but is also an
3639261188Spfg	 unary operator that can start an expression.  Consume all
3640261188Spfg	 but the last of a possible series of __extension__ to
3641261188Spfg	 determine which.  */
3642261188Spfg	while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
3643261188Spfg		   && (c_parser_peek_2nd_token (parser)->keyword
3644261188Spfg			   == RID_EXTENSION))
3645261188Spfg		c_parser_consume_token (parser);
3646261188Spfg	if (c_token_starts_declspecs (c_parser_peek_2nd_token (parser)))
3647169689Skan	{
3648261188Spfg		int ext;
3649261188Spfg		ext = disable_extension_diagnostics ();
3650261188Spfg		c_parser_consume_token (parser);
3651261188Spfg		last_label = false;
3652261188Spfg		/* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
3653261188Spfg		c_parser_declaration_or_fndef (parser, true, true, true, true, NULL);
3654261188Spfg		/* Following the old parser, __extension__ does not
3655169689Skan		 disable this diagnostic.  */
3656261188Spfg		restore_extension_diagnostics (ext);
3657261188Spfg		if (last_stmt
3658261188Spfg			&& ((pedantic && !flag_isoc99)
3659261188Spfg				|| warn_declaration_after_statement))
3660261188Spfg			pedwarn_c90 ("%HISO C90 forbids mixed declarations and code",
3661261188Spfg						 &loc);
3662261188Spfg		last_stmt = false;
3663169689Skan	}
3664261188Spfg	else
3665261188Spfg		goto statement;
3666261188Spfg      }
3667169689Skan      else if (c_parser_next_token_is (parser, CPP_PRAGMA))
3668261188Spfg      {
3669261188Spfg	/* External pragmas, and some omp pragmas, are not associated
3670261188Spfg	 with regular c code, and so are not to be considered statements
3671261188Spfg	 syntactically.  This ensures that the user doesn't put them
3672261188Spfg	 places that would turn into syntax errors if the directive
3673261188Spfg	 were ignored.  */
3674261188Spfg	if (c_parser_pragma (parser, pragma_compound))
3675261188Spfg		last_label = false, last_stmt = true;
3676261188Spfg      }
3677169689Skan      else if (c_parser_next_token_is (parser, CPP_EOF))
3678261188Spfg      {
3679261188Spfg	c_parser_error (parser, "expected declaration or statement");
3680261188Spfg	return;
3681261188Spfg      }
3682169689Skan      else
3683261188Spfg      {
3684261188Spfg      statement:
3685261188Spfg	last_label = false;
3686261188Spfg	last_stmt = true;
3687261188Spfg	c_parser_statement_after_labels (parser);
3688261188Spfg      }
3689261188Spfg
3690169689Skan      parser->error = false;
3691261188Spfg      /* APPLE LOCAL radar 5732232 - blocks (not in C++) */
3692261188Spfg      first_stmt = false;
3693169689Skan    }
3694169689Skan  if (last_label)
3695169689Skan    error ("label at end of compound statement");
3696169689Skan  c_parser_consume_token (parser);
3697169689Skan}
3698169689Skan
3699169689Skan/* Parse a label (C90 6.6.1, C99 6.8.1).
3700169689Skan
3701169689Skan   label:
3702169689Skan     identifier : attributes[opt]
3703169689Skan     case constant-expression :
3704169689Skan     default :
3705169689Skan
3706169689Skan   GNU extensions:
3707169689Skan
3708169689Skan   label:
3709169689Skan     case constant-expression ... constant-expression :
3710169689Skan
3711169689Skan   The use of attributes on labels is a GNU extension.  The syntax in
3712169689Skan   GNU C accepts any expressions without commas, non-constant
3713169689Skan   expressions being rejected later.  */
3714169689Skan
3715169689Skanstatic void
3716169689Skanc_parser_label (c_parser *parser)
3717169689Skan{
3718169689Skan  location_t loc1 = c_parser_peek_token (parser)->location;
3719169689Skan  tree label = NULL_TREE;
3720169689Skan  if (c_parser_next_token_is_keyword (parser, RID_CASE))
3721169689Skan    {
3722169689Skan      tree exp1, exp2;
3723169689Skan      c_parser_consume_token (parser);
3724169689Skan      exp1 = c_parser_expr_no_commas (parser, NULL).value;
3725169689Skan      if (c_parser_next_token_is (parser, CPP_COLON))
3726169689Skan	{
3727169689Skan	  c_parser_consume_token (parser);
3728169689Skan	  label = do_case (exp1, NULL_TREE);
3729169689Skan	}
3730169689Skan      else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3731169689Skan	{
3732169689Skan	  c_parser_consume_token (parser);
3733169689Skan	  exp2 = c_parser_expr_no_commas (parser, NULL).value;
3734169689Skan	  if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
3735169689Skan	    label = do_case (exp1, exp2);
3736169689Skan	}
3737169689Skan      else
3738169689Skan	c_parser_error (parser, "expected %<:%> or %<...%>");
3739169689Skan    }
3740169689Skan  else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
3741169689Skan    {
3742169689Skan      c_parser_consume_token (parser);
3743169689Skan      if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
3744169689Skan	label = do_case (NULL_TREE, NULL_TREE);
3745169689Skan    }
3746169689Skan  else
3747169689Skan    {
3748169689Skan      tree name = c_parser_peek_token (parser)->value;
3749169689Skan      tree tlab;
3750169689Skan      location_t loc2;
3751169689Skan      tree attrs;
3752169689Skan      gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
3753169689Skan      c_parser_consume_token (parser);
3754169689Skan      gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
3755169689Skan      loc2 = c_parser_peek_token (parser)->location;
3756169689Skan      c_parser_consume_token (parser);
3757169689Skan      attrs = c_parser_attributes (parser);
3758169689Skan      tlab = define_label (loc2, name);
3759169689Skan      if (tlab)
3760169689Skan	{
3761169689Skan	  decl_attributes (&tlab, attrs, 0);
3762169689Skan	  label = add_stmt (build_stmt (LABEL_EXPR, tlab));
3763169689Skan	}
3764169689Skan    }
3765169689Skan  if (label)
3766169689Skan    SET_EXPR_LOCATION (label, loc1);
3767169689Skan}
3768169689Skan
3769169689Skan/* Parse a statement (C90 6.6, C99 6.8).
3770169689Skan
3771169689Skan   statement:
3772169689Skan     labeled-statement
3773169689Skan     compound-statement
3774169689Skan     expression-statement
3775169689Skan     selection-statement
3776169689Skan     iteration-statement
3777169689Skan     jump-statement
3778169689Skan
3779169689Skan   labeled-statement:
3780169689Skan     label statement
3781169689Skan
3782169689Skan   expression-statement:
3783169689Skan     expression[opt] ;
3784169689Skan
3785169689Skan   selection-statement:
3786169689Skan     if-statement
3787169689Skan     switch-statement
3788169689Skan
3789169689Skan   iteration-statement:
3790169689Skan     while-statement
3791169689Skan     do-statement
3792169689Skan     for-statement
3793169689Skan
3794169689Skan   jump-statement:
3795169689Skan     goto identifier ;
3796169689Skan     continue ;
3797169689Skan     break ;
3798169689Skan     return expression[opt] ;
3799169689Skan
3800169689Skan   GNU extensions:
3801169689Skan
3802169689Skan   statement:
3803169689Skan     asm-statement
3804169689Skan
3805169689Skan   jump-statement:
3806169689Skan     goto * expression ;
3807169689Skan
3808169689Skan   Objective-C:
3809169689Skan
3810169689Skan   statement:
3811169689Skan     objc-throw-statement
3812169689Skan     objc-try-catch-statement
3813169689Skan     objc-synchronized-statement
3814169689Skan
3815169689Skan   objc-throw-statement:
3816169689Skan     @throw expression ;
3817169689Skan     @throw ;
3818169689Skan
3819169689Skan   OpenMP:
3820169689Skan
3821169689Skan   statement:
3822169689Skan     openmp-construct
3823169689Skan
3824169689Skan   openmp-construct:
3825169689Skan     parallel-construct
3826169689Skan     for-construct
3827169689Skan     sections-construct
3828169689Skan     single-construct
3829169689Skan     parallel-for-construct
3830169689Skan     parallel-sections-construct
3831169689Skan     master-construct
3832169689Skan     critical-construct
3833169689Skan     atomic-construct
3834169689Skan     ordered-construct
3835169689Skan
3836169689Skan   parallel-construct:
3837169689Skan     parallel-directive structured-block
3838169689Skan
3839169689Skan   for-construct:
3840169689Skan     for-directive iteration-statement
3841169689Skan
3842169689Skan   sections-construct:
3843169689Skan     sections-directive section-scope
3844169689Skan
3845169689Skan   single-construct:
3846169689Skan     single-directive structured-block
3847169689Skan
3848169689Skan   parallel-for-construct:
3849169689Skan     parallel-for-directive iteration-statement
3850169689Skan
3851169689Skan   parallel-sections-construct:
3852169689Skan     parallel-sections-directive section-scope
3853169689Skan
3854169689Skan   master-construct:
3855169689Skan     master-directive structured-block
3856169689Skan
3857169689Skan   critical-construct:
3858169689Skan     critical-directive structured-block
3859169689Skan
3860169689Skan   atomic-construct:
3861169689Skan     atomic-directive expression-statement
3862169689Skan
3863169689Skan   ordered-construct:
3864169689Skan     ordered-directive structured-block  */
3865169689Skan
3866169689Skanstatic void
3867169689Skanc_parser_statement (c_parser *parser)
3868169689Skan{
3869169689Skan  while (c_parser_next_token_is_keyword (parser, RID_CASE)
3870169689Skan	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
3871169689Skan	 || (c_parser_next_token_is (parser, CPP_NAME)
3872169689Skan	     && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
3873169689Skan    c_parser_label (parser);
3874169689Skan  c_parser_statement_after_labels (parser);
3875169689Skan}
3876169689Skan
3877169689Skan/* Parse a statement, other than a labeled statement.  */
3878169689Skan
3879169689Skanstatic void
3880169689Skanc_parser_statement_after_labels (c_parser *parser)
3881169689Skan{
3882169689Skan  location_t loc = c_parser_peek_token (parser)->location;
3883169689Skan  tree stmt = NULL_TREE;
3884169689Skan  switch (c_parser_peek_token (parser)->type)
3885169689Skan    {
3886169689Skan    case CPP_OPEN_BRACE:
3887169689Skan      add_stmt (c_parser_compound_statement (parser));
3888169689Skan      break;
3889169689Skan    case CPP_KEYWORD:
3890169689Skan      switch (c_parser_peek_token (parser)->keyword)
3891169689Skan	{
3892169689Skan	case RID_IF:
3893169689Skan	  c_parser_if_statement (parser);
3894169689Skan	  break;
3895169689Skan	case RID_SWITCH:
3896169689Skan	  c_parser_switch_statement (parser);
3897169689Skan	  break;
3898169689Skan	case RID_WHILE:
3899169689Skan	  c_parser_while_statement (parser);
3900169689Skan	  break;
3901169689Skan	case RID_DO:
3902169689Skan	  c_parser_do_statement (parser);
3903169689Skan	  break;
3904169689Skan	case RID_FOR:
3905169689Skan	  c_parser_for_statement (parser);
3906169689Skan	  break;
3907169689Skan	case RID_GOTO:
3908261188Spfg	   /* APPLE LOCAL begin radar 5732232 - blocks (C++ cb) */
3909261188Spfg	   if (cur_block)
3910261188Spfg	     error ("goto not allowed in block literal");
3911261188Spfg	   /* APPLE LOCAL end radar 5732232 - blocks (C++ cb) */
3912169689Skan	  c_parser_consume_token (parser);
3913169689Skan	  if (c_parser_next_token_is (parser, CPP_NAME))
3914169689Skan	    {
3915169689Skan	      stmt = c_finish_goto_label (c_parser_peek_token (parser)->value);
3916169689Skan	      c_parser_consume_token (parser);
3917169689Skan	    }
3918169689Skan	  else if (c_parser_next_token_is (parser, CPP_MULT))
3919169689Skan	    {
3920169689Skan	      c_parser_consume_token (parser);
3921169689Skan	      stmt = c_finish_goto_ptr (c_parser_expression (parser).value);
3922169689Skan	    }
3923169689Skan	  else
3924169689Skan	    c_parser_error (parser, "expected identifier or %<*%>");
3925169689Skan	  goto expect_semicolon;
3926169689Skan	case RID_CONTINUE:
3927169689Skan	  c_parser_consume_token (parser);
3928169689Skan	  stmt = c_finish_bc_stmt (&c_cont_label, false);
3929169689Skan	  goto expect_semicolon;
3930169689Skan	case RID_BREAK:
3931169689Skan	  c_parser_consume_token (parser);
3932169689Skan	  stmt = c_finish_bc_stmt (&c_break_label, true);
3933169689Skan	  goto expect_semicolon;
3934169689Skan	case RID_RETURN:
3935169689Skan	  c_parser_consume_token (parser);
3936169689Skan	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3937169689Skan	    {
3938169689Skan	      stmt = c_finish_return (NULL_TREE);
3939169689Skan	      c_parser_consume_token (parser);
3940169689Skan	    }
3941169689Skan	  else
3942169689Skan	    {
3943169689Skan	      stmt = c_finish_return (c_parser_expression_conv (parser).value);
3944169689Skan	      goto expect_semicolon;
3945169689Skan	    }
3946169689Skan	  break;
3947169689Skan	case RID_ASM:
3948169689Skan	  stmt = c_parser_asm_statement (parser);
3949169689Skan	  break;
3950169689Skan	case RID_AT_THROW:
3951169689Skan	  gcc_assert (c_dialect_objc ());
3952169689Skan	  c_parser_consume_token (parser);
3953169689Skan	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3954169689Skan	    {
3955169689Skan	      stmt = objc_build_throw_stmt (NULL_TREE);
3956169689Skan	      c_parser_consume_token (parser);
3957169689Skan	    }
3958169689Skan	  else
3959169689Skan	    {
3960169689Skan	      stmt
3961169689Skan		= objc_build_throw_stmt (c_parser_expression (parser).value);
3962169689Skan	      goto expect_semicolon;
3963169689Skan	    }
3964169689Skan	  break;
3965169689Skan	case RID_AT_TRY:
3966169689Skan	  gcc_assert (c_dialect_objc ());
3967169689Skan	  c_parser_objc_try_catch_statement (parser);
3968169689Skan	  break;
3969169689Skan	case RID_AT_SYNCHRONIZED:
3970169689Skan	  gcc_assert (c_dialect_objc ());
3971169689Skan	  c_parser_objc_synchronized_statement (parser);
3972169689Skan	  break;
3973169689Skan	default:
3974169689Skan	  goto expr_stmt;
3975169689Skan	}
3976169689Skan      break;
3977169689Skan    case CPP_SEMICOLON:
3978169689Skan      c_parser_consume_token (parser);
3979169689Skan      break;
3980169689Skan    case CPP_CLOSE_PAREN:
3981169689Skan    case CPP_CLOSE_SQUARE:
3982169689Skan      /* Avoid infinite loop in error recovery:
3983169689Skan	 c_parser_skip_until_found stops at a closing nesting
3984169689Skan	 delimiter without consuming it, but here we need to consume
3985169689Skan	 it to proceed further.  */
3986169689Skan      c_parser_error (parser, "expected statement");
3987169689Skan      c_parser_consume_token (parser);
3988169689Skan      break;
3989169689Skan    case CPP_PRAGMA:
3990169689Skan      c_parser_pragma (parser, pragma_stmt);
3991169689Skan      break;
3992169689Skan    default:
3993169689Skan    expr_stmt:
3994169689Skan      stmt = c_finish_expr_stmt (c_parser_expression_conv (parser).value);
3995169689Skan    expect_semicolon:
3996169689Skan      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
3997169689Skan      break;
3998169689Skan    }
3999169689Skan  /* Two cases cannot and do not have line numbers associated: If stmt
4000169689Skan     is degenerate, such as "2;", then stmt is an INTEGER_CST, which
4001169689Skan     cannot hold line numbers.  But that's OK because the statement
4002169689Skan     will either be changed to a MODIFY_EXPR during gimplification of
4003169689Skan     the statement expr, or discarded.  If stmt was compound, but
4004169689Skan     without new variables, we will have skipped the creation of a
4005169689Skan     BIND and will have a bare STATEMENT_LIST.  But that's OK because
4006169689Skan     (recursively) all of the component statements should already have
4007169689Skan     line numbers assigned.  ??? Can we discard no-op statements
4008169689Skan     earlier?  */
4009261188Spfg  /* APPLE LOCAL begin Radar 6144634  */
4010261188Spfg  /* Normal expr stmts, including modify exprs, get the location where
4011261188Spfg     the statement began, i.e. 'loc'.  Assignments of Blocks to Block
4012261188Spfg     pointer variables get the location of the end of the Block definition,
4013261188Spfg     i.e. 'input_location', which should already be set by this point.  */
4014169689Skan  if (stmt && EXPR_P (stmt))
4015261188Spfg    {
4016261188Spfg      if (TREE_CODE (stmt) == MODIFY_EXPR
4017261188Spfg	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (stmt, 0))) == BLOCK_POINTER_TYPE)
4018261188Spfg	SET_EXPR_LOCATION (stmt, input_location);
4019261188Spfg      else
4020261188Spfg	SET_EXPR_LOCATION (stmt, loc);
4021261188Spfg    }
4022261188Spfg  /* APPLE LOCAL end Radar 6144634  */
4023169689Skan}
4024169689Skan
4025169689Skan/* Parse a parenthesized condition from an if, do or while statement.
4026169689Skan
4027169689Skan   condition:
4028169689Skan     ( expression )
4029169689Skan*/
4030169689Skanstatic tree
4031169689Skanc_parser_paren_condition (c_parser *parser)
4032169689Skan{
4033169689Skan  location_t loc;
4034169689Skan  tree cond;
4035169689Skan  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4036169689Skan    return error_mark_node;
4037169689Skan  loc = c_parser_peek_token (parser)->location;
4038169689Skan  cond = c_objc_common_truthvalue_conversion
4039169689Skan    (c_parser_expression_conv (parser).value);
4040169689Skan  if (EXPR_P (cond))
4041169689Skan    SET_EXPR_LOCATION (cond, loc);
4042169689Skan  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
4043169689Skan  return cond;
4044169689Skan}
4045169689Skan
4046169689Skan/* Parse a statement which is a block in C99.  */
4047169689Skan
4048169689Skanstatic tree
4049169689Skanc_parser_c99_block_statement (c_parser *parser)
4050169689Skan{
4051169689Skan  tree block = c_begin_compound_stmt (flag_isoc99);
4052169689Skan  c_parser_statement (parser);
4053169689Skan  return c_end_compound_stmt (block, flag_isoc99);
4054169689Skan}
4055169689Skan
4056169689Skan/* Parse the body of an if statement or the else half thereof.  This
4057169689Skan   is just parsing a statement but (a) it is a block in C99, (b) we
4058169689Skan   track whether the body is an if statement for the sake of
4059169689Skan   -Wparentheses warnings, (c) we handle an empty body specially for
4060169689Skan   the sake of -Wextra warnings.  */
4061169689Skan
4062169689Skanstatic tree
4063169689Skanc_parser_if_body (c_parser *parser, bool *if_p)
4064169689Skan{
4065169689Skan  tree block = c_begin_compound_stmt (flag_isoc99);
4066169689Skan  while (c_parser_next_token_is_keyword (parser, RID_CASE)
4067169689Skan	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4068169689Skan	 || (c_parser_next_token_is (parser, CPP_NAME)
4069169689Skan	     && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4070169689Skan    c_parser_label (parser);
4071169689Skan  *if_p = c_parser_next_token_is_keyword (parser, RID_IF);
4072169689Skan  if (extra_warnings && c_parser_next_token_is (parser, CPP_SEMICOLON))
4073169689Skan    add_stmt (build_empty_stmt ());
4074169689Skan  c_parser_statement_after_labels (parser);
4075169689Skan  return c_end_compound_stmt (block, flag_isoc99);
4076169689Skan}
4077169689Skan
4078169689Skan/* Parse an if statement (C90 6.6.4, C99 6.8.4).
4079169689Skan
4080169689Skan   if-statement:
4081169689Skan     if ( expression ) statement
4082169689Skan     if ( expression ) statement else statement
4083169689Skan*/
4084169689Skan
4085169689Skanstatic void
4086169689Skanc_parser_if_statement (c_parser *parser)
4087169689Skan{
4088169689Skan  tree block;
4089169689Skan  location_t loc;
4090169689Skan  tree cond;
4091169689Skan  bool first_if = false, second_if = false;
4092169689Skan  tree first_body, second_body;
4093169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
4094169689Skan  c_parser_consume_token (parser);
4095169689Skan  block = c_begin_compound_stmt (flag_isoc99);
4096169689Skan  loc = c_parser_peek_token (parser)->location;
4097169689Skan  cond = c_parser_paren_condition (parser);
4098169689Skan  first_body = c_parser_if_body (parser, &first_if);
4099169689Skan  if (c_parser_next_token_is_keyword (parser, RID_ELSE))
4100169689Skan    {
4101169689Skan      c_parser_consume_token (parser);
4102169689Skan      second_body = c_parser_if_body (parser, &second_if);
4103169689Skan    }
4104169689Skan  else
4105169689Skan    second_body = NULL_TREE;
4106169689Skan  c_finish_if_stmt (loc, cond, first_body, second_body, first_if);
4107169689Skan  add_stmt (c_end_compound_stmt (block, flag_isoc99));
4108169689Skan}
4109169689Skan
4110169689Skan/* Parse a switch statement (C90 6.6.4, C99 6.8.4).
4111169689Skan
4112169689Skan   switch-statement:
4113169689Skan     switch (expression) statement
4114169689Skan*/
4115169689Skan
4116169689Skanstatic void
4117169689Skanc_parser_switch_statement (c_parser *parser)
4118169689Skan{
4119169689Skan  tree block, expr, body, save_break;
4120169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
4121169689Skan  c_parser_consume_token (parser);
4122169689Skan  block = c_begin_compound_stmt (flag_isoc99);
4123169689Skan  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4124169689Skan    {
4125169689Skan      expr = c_parser_expression (parser).value;
4126169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
4127169689Skan    }
4128169689Skan  else
4129169689Skan    expr = error_mark_node;
4130169689Skan  c_start_case (expr);
4131169689Skan  save_break = c_break_label;
4132169689Skan  c_break_label = NULL_TREE;
4133169689Skan  body = c_parser_c99_block_statement (parser);
4134169689Skan  c_finish_case (body);
4135169689Skan  if (c_break_label)
4136169689Skan    add_stmt (build1 (LABEL_EXPR, void_type_node, c_break_label));
4137169689Skan  c_break_label = save_break;
4138169689Skan  add_stmt (c_end_compound_stmt (block, flag_isoc99));
4139169689Skan}
4140169689Skan
4141169689Skan/* Parse a while statement (C90 6.6.5, C99 6.8.5).
4142169689Skan
4143169689Skan   while-statement:
4144260918Spfg   APPLE LOCAL begin for-fsf-4_4 3274130 5295549
4145260918Spfg      while attributes (expression) statement
4146260918Spfg
4147260918Spfg   The use of attributes is a GNU extension.
4148260918Spfg   APPLE LOCAL end for-fsf-4_4 3274130 5295549
4149169689Skan*/
4150169689Skan
4151169689Skanstatic void
4152169689Skanc_parser_while_statement (c_parser *parser)
4153169689Skan{
4154260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4155260918Spfg  tree block, cond, body, save_break, save_cont, attrs;
4156260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4157169689Skan  location_t loc;
4158169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
4159169689Skan  c_parser_consume_token (parser);
4160260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4161260918Spfg  attrs = c_parser_attributes (parser);
4162260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4163169689Skan  block = c_begin_compound_stmt (flag_isoc99);
4164169689Skan  loc = c_parser_peek_token (parser)->location;
4165169689Skan  cond = c_parser_paren_condition (parser);
4166169689Skan  save_break = c_break_label;
4167169689Skan  c_break_label = NULL_TREE;
4168169689Skan  save_cont = c_cont_label;
4169169689Skan  c_cont_label = NULL_TREE;
4170169689Skan  body = c_parser_c99_block_statement (parser);
4171260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4172260918Spfg  c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, attrs,
4173260918Spfg		 true);
4174260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4175169689Skan  add_stmt (c_end_compound_stmt (block, flag_isoc99));
4176169689Skan  c_break_label = save_break;
4177169689Skan  c_cont_label = save_cont;
4178169689Skan}
4179169689Skan
4180169689Skan/* Parse a do statement (C90 6.6.5, C99 6.8.5).
4181169689Skan
4182169689Skan   do-statement:
4183260918Spfg   APPLE LOCAL begin for-fsf-4_4 3274130 5295549
4184260918Spfg     do attributes statement while ( expression ) ;
4185260918Spfg
4186260918Spfg   The use of attributes is a GNU extension.
4187260918Spfg   APPLE LOCAL end for-fsf-4_4 3274130 5295549
4188169689Skan*/
4189169689Skan
4190169689Skanstatic void
4191169689Skanc_parser_do_statement (c_parser *parser)
4192169689Skan{
4193260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4194260918Spfg  tree block, cond, body, save_break, save_cont, new_break, new_cont, attrs;
4195260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4196169689Skan  location_t loc;
4197169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
4198169689Skan  c_parser_consume_token (parser);
4199260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4200260918Spfg  attrs = c_parser_attributes (parser);
4201260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4202169689Skan  block = c_begin_compound_stmt (flag_isoc99);
4203169689Skan  loc = c_parser_peek_token (parser)->location;
4204169689Skan  save_break = c_break_label;
4205169689Skan  c_break_label = NULL_TREE;
4206169689Skan  save_cont = c_cont_label;
4207169689Skan  c_cont_label = NULL_TREE;
4208169689Skan  body = c_parser_c99_block_statement (parser);
4209169689Skan  c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
4210169689Skan  new_break = c_break_label;
4211169689Skan  c_break_label = save_break;
4212169689Skan  new_cont = c_cont_label;
4213169689Skan  c_cont_label = save_cont;
4214169689Skan  cond = c_parser_paren_condition (parser);
4215169689Skan  if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
4216169689Skan    c_parser_skip_to_end_of_block_or_statement (parser);
4217260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4218260918Spfg  c_finish_loop (loc, cond, NULL, body, new_break, new_cont, attrs, false);
4219260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4220169689Skan  add_stmt (c_end_compound_stmt (block, flag_isoc99));
4221169689Skan}
4222169689Skan
4223169689Skan/* Parse a for statement (C90 6.6.5, C99 6.8.5).
4224169689Skan
4225169689Skan   for-statement:
4226260918Spfg   APPLE LOCAL begin for-fsf-4_4 3274130 5295549
4227260918Spfg     for attributes ( expression[opt] ; expression[opt] ; expression[opt] ) \
4228260918Spfg         statement
4229260918Spfg     for attributes ( nested-declaration expression[opt] ; expression[opt] ) \
4230260918Spfg         statement
4231169689Skan
4232169689Skan   The form with a declaration is new in C99.
4233169689Skan
4234260918Spfg   The use of attributes is a GNU extension.
4235260918Spfg
4236260918Spfg   APPLE LOCAL end for-fsf-4_4 3274130 5295549
4237169689Skan   ??? In accordance with the old parser, the declaration may be a
4238169689Skan   nested function, which is then rejected in check_for_loop_decls,
4239169689Skan   but does it make any sense for this to be included in the grammar?
4240169689Skan   Note in particular that the nested function does not include a
4241169689Skan   trailing ';', whereas the "declaration" production includes one.
4242169689Skan   Also, can we reject bad declarations earlier and cheaper than
4243169689Skan   check_for_loop_decls?  */
4244169689Skan
4245169689Skanstatic void
4246169689Skanc_parser_for_statement (c_parser *parser)
4247169689Skan{
4248260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4249260918Spfg  tree block, cond, incr, save_break, save_cont, body, attrs;
4250260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4251169689Skan  location_t loc;
4252261188Spfg  /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
4253261188Spfg  bool foreach_p = false;
4254169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
4255169689Skan  loc = c_parser_peek_token (parser)->location;
4256169689Skan  c_parser_consume_token (parser);
4257260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4258260918Spfg  attrs = c_parser_attributes (parser);
4259260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4260169689Skan  block = c_begin_compound_stmt (flag_isoc99);
4261169689Skan  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4262169689Skan    {
4263169689Skan      /* Parse the initialization declaration or expression.  */
4264169689Skan      if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4265169689Skan	{
4266169689Skan	  c_parser_consume_token (parser);
4267169689Skan	  c_finish_expr_stmt (NULL_TREE);
4268169689Skan	}
4269169689Skan      else if (c_parser_next_token_starts_declspecs (parser))
4270169689Skan	{
4271261188Spfg	  /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */
4272261188Spfg	  cond = NULL_TREE;
4273261188Spfg	  c_parser_declaration_or_fndef (parser, true, true, true, true, &cond);
4274261188Spfg	  /* APPLE LOCAL radar 5925639 */
4275261188Spfg	  if (c_parser_next_token_is_keyword (parser, RID_IN) && cond)
4276261188Spfg	    {
4277261188Spfg	      cond = finish_parse_foreach_header (parser, cond);
4278261188Spfg	      foreach_p = true;
4279261188Spfg	    }
4280261188Spfg	  else
4281261188Spfg	    check_for_loop_decls ();
4282261188Spfg	  /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */
4283169689Skan	}
4284169689Skan      else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
4285169689Skan	{
4286169689Skan	  /* __extension__ can start a declaration, but is also an
4287169689Skan	     unary operator that can start an expression.  Consume all
4288169689Skan	     but the last of a possible series of __extension__ to
4289169689Skan	     determine which.  */
4290169689Skan	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
4291169689Skan		 && (c_parser_peek_2nd_token (parser)->keyword
4292169689Skan		     == RID_EXTENSION))
4293169689Skan	    c_parser_consume_token (parser);
4294169689Skan	  if (c_token_starts_declspecs (c_parser_peek_2nd_token (parser)))
4295169689Skan	    {
4296169689Skan	      int ext;
4297169689Skan	      ext = disable_extension_diagnostics ();
4298169689Skan	      c_parser_consume_token (parser);
4299261188Spfg	      /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */
4300261188Spfg	      cond = NULL_TREE;
4301261188Spfg	      c_parser_declaration_or_fndef (parser, true, true, true, true, &cond);
4302169689Skan	      restore_extension_diagnostics (ext);
4303261188Spfg	      /* APPLE LOCAL radar 5925639 */
4304261188Spfg	      if (c_parser_next_token_is_keyword (parser, RID_IN) && cond)
4305261188Spfg	        {
4306261188Spfg		  cond = finish_parse_foreach_header (parser, cond);
4307261188Spfg	          foreach_p = true;
4308261188Spfg	        }
4309261188Spfg	      else
4310261188Spfg		check_for_loop_decls ();
4311261188Spfg	      /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */
4312169689Skan	    }
4313169689Skan	  else
4314169689Skan	    goto init_expr;
4315169689Skan	}
4316169689Skan      else
4317169689Skan	{
4318169689Skan	init_expr:
4319261188Spfg	  /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */
4320261188Spfg	  cond = c_parser_expression (parser).value;
4321261188Spfg	  if (c_parser_next_token_is_keyword (parser, RID_IN))
4322261188Spfg	    {
4323261188Spfg	      c_parser_consume_token (parser); /* IN */
4324261188Spfg	      cond = build_tree_list (cond, c_parser_initializer (parser).value);
4325261188Spfg	      foreach_p = true;
4326261188Spfg	    }
4327261188Spfg	  else
4328261188Spfg	    {
4329261188Spfg	      c_finish_expr_stmt (cond);
4330261188Spfg	      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4331261188Spfg	    }
4332169689Skan	}
4333261188Spfg	objc_foreach_context = 0;
4334261188Spfg	/* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */
4335169689Skan      /* Parse the loop condition.  */
4336169689Skan      loc = c_parser_peek_token (parser)->location;
4337169689Skan      if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4338169689Skan	{
4339169689Skan	  c_parser_consume_token (parser);
4340169689Skan	  cond = NULL_TREE;
4341169689Skan	}
4342261188Spfg      /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */
4343261188Spfg      else if (foreach_p)
4344261188Spfg	;
4345261188Spfg      /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */
4346169689Skan      else
4347169689Skan	{
4348169689Skan	  tree ocond = c_parser_expression_conv (parser).value;
4349169689Skan	  cond = c_objc_common_truthvalue_conversion (ocond);
4350169689Skan	  if (EXPR_P (cond))
4351169689Skan	    SET_EXPR_LOCATION (cond, loc);
4352169689Skan	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4353169689Skan	}
4354169689Skan      /* Parse the increment expression.  */
4355169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4356169689Skan	incr = c_process_expr_stmt (NULL_TREE);
4357169689Skan      else
4358169689Skan	incr = c_process_expr_stmt (c_parser_expression (parser).value);
4359169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
4360169689Skan    }
4361169689Skan  else
4362169689Skan    {
4363169689Skan      cond = error_mark_node;
4364169689Skan      incr = error_mark_node;
4365169689Skan    }
4366169689Skan  save_break = c_break_label;
4367169689Skan  c_break_label = NULL_TREE;
4368169689Skan  save_cont = c_cont_label;
4369169689Skan  c_cont_label = NULL_TREE;
4370169689Skan  body = c_parser_c99_block_statement (parser);
4371260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \
4372260918Spfg    c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, attrs,
4373260918Spfg		   true);
4374260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \
4375169689Skan  add_stmt (c_end_compound_stmt (block, flag_isoc99));
4376169689Skan  c_break_label = save_break;
4377169689Skan  c_cont_label = save_cont;
4378169689Skan}
4379169689Skan
4380169689Skan/* Parse an asm statement, a GNU extension.  This is a full-blown asm
4381169689Skan   statement with inputs, outputs, clobbers, and volatile tag
4382169689Skan   allowed.
4383169689Skan
4384169689Skan   asm-statement:
4385169689Skan     asm type-qualifier[opt] ( asm-argument ) ;
4386169689Skan
4387169689Skan   asm-argument:
4388169689Skan     asm-string-literal
4389169689Skan     asm-string-literal : asm-operands[opt]
4390169689Skan     asm-string-literal : asm-operands[opt] : asm-operands[opt]
4391169689Skan     asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers
4392169689Skan
4393169689Skan   Qualifiers other than volatile are accepted in the syntax but
4394169689Skan   warned for.  */
4395169689Skan
4396169689Skanstatic tree
4397169689Skanc_parser_asm_statement (c_parser *parser)
4398169689Skan{
4399169689Skan  tree quals, str, outputs, inputs, clobbers, ret;
4400169689Skan  bool simple;
4401169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4402169689Skan  c_parser_consume_token (parser);
4403169689Skan  if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
4404169689Skan    {
4405169689Skan      quals = c_parser_peek_token (parser)->value;
4406169689Skan      c_parser_consume_token (parser);
4407169689Skan    }
4408169689Skan  else if (c_parser_next_token_is_keyword (parser, RID_CONST)
4409169689Skan	   || c_parser_next_token_is_keyword (parser, RID_RESTRICT))
4410169689Skan    {
4411169689Skan      warning (0, "%E qualifier ignored on asm",
4412169689Skan	       c_parser_peek_token (parser)->value);
4413169689Skan      quals = NULL_TREE;
4414169689Skan      c_parser_consume_token (parser);
4415169689Skan    }
4416169689Skan  else
4417169689Skan    quals = NULL_TREE;
4418169689Skan  /* ??? Follow the C++ parser rather than using the
4419169689Skan     c_lex_string_translate kludge.  */
4420169689Skan  c_lex_string_translate = 0;
4421169689Skan  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4422169689Skan    {
4423169689Skan      c_lex_string_translate = 1;
4424169689Skan      return NULL_TREE;
4425169689Skan    }
4426169689Skan  str = c_parser_asm_string_literal (parser);
4427169689Skan  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4428169689Skan    {
4429169689Skan      simple = true;
4430169689Skan      outputs = NULL_TREE;
4431169689Skan      inputs = NULL_TREE;
4432169689Skan      clobbers = NULL_TREE;
4433169689Skan      goto done_asm;
4434169689Skan    }
4435169689Skan  if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
4436169689Skan    {
4437169689Skan      c_lex_string_translate = 1;
4438169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4439169689Skan      return NULL_TREE;
4440169689Skan    }
4441169689Skan  simple = false;
4442169689Skan  /* Parse outputs.  */
4443169689Skan  if (c_parser_next_token_is (parser, CPP_COLON)
4444169689Skan      || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4445169689Skan    outputs = NULL_TREE;
4446169689Skan  else
4447169689Skan    outputs = c_parser_asm_operands (parser, false);
4448169689Skan  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4449169689Skan    {
4450169689Skan      inputs = NULL_TREE;
4451169689Skan      clobbers = NULL_TREE;
4452169689Skan      goto done_asm;
4453169689Skan    }
4454169689Skan  if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
4455169689Skan    {
4456169689Skan      c_lex_string_translate = 1;
4457169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4458169689Skan      return NULL_TREE;
4459169689Skan    }
4460169689Skan  /* Parse inputs.  */
4461169689Skan  if (c_parser_next_token_is (parser, CPP_COLON)
4462169689Skan      || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4463169689Skan    inputs = NULL_TREE;
4464169689Skan  else
4465169689Skan    inputs = c_parser_asm_operands (parser, true);
4466169689Skan  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4467169689Skan    {
4468169689Skan      clobbers = NULL_TREE;
4469169689Skan      goto done_asm;
4470169689Skan    }
4471169689Skan  if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
4472169689Skan    {
4473169689Skan      c_lex_string_translate = 1;
4474169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4475169689Skan      return NULL_TREE;
4476169689Skan    }
4477169689Skan  /* Parse clobbers.  */
4478169689Skan  clobbers = c_parser_asm_clobbers (parser);
4479169689Skan done_asm:
4480169689Skan  c_lex_string_translate = 1;
4481169689Skan  if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
4482169689Skan    {
4483169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4484169689Skan      return NULL_TREE;
4485169689Skan    }
4486169689Skan  if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
4487169689Skan    c_parser_skip_to_end_of_block_or_statement (parser);
4488169689Skan  ret = build_asm_stmt (quals, build_asm_expr (str, outputs, inputs,
4489169689Skan					       clobbers, simple));
4490169689Skan  return ret;
4491169689Skan}
4492169689Skan
4493169689Skan/* Parse asm operands, a GNU extension.  If CONVERT_P (for inputs but
4494169689Skan   not outputs), apply the default conversion of functions and arrays
4495169689Skan   to pointers.
4496169689Skan
4497169689Skan   asm-operands:
4498169689Skan     asm-operand
4499169689Skan     asm-operands , asm-operand
4500169689Skan
4501169689Skan   asm-operand:
4502169689Skan     asm-string-literal ( expression )
4503169689Skan     [ identifier ] asm-string-literal ( expression )
4504169689Skan*/
4505169689Skan
4506169689Skanstatic tree
4507169689Skanc_parser_asm_operands (c_parser *parser, bool convert_p)
4508169689Skan{
4509169689Skan  tree list = NULL_TREE;
4510169689Skan  while (true)
4511169689Skan    {
4512169689Skan      tree name, str;
4513169689Skan      struct c_expr expr;
4514169689Skan      if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
4515169689Skan	{
4516169689Skan	  c_parser_consume_token (parser);
4517169689Skan	  if (c_parser_next_token_is (parser, CPP_NAME))
4518169689Skan	    {
4519169689Skan	      tree id = c_parser_peek_token (parser)->value;
4520169689Skan	      c_parser_consume_token (parser);
4521169689Skan	      name = build_string (IDENTIFIER_LENGTH (id),
4522169689Skan				   IDENTIFIER_POINTER (id));
4523169689Skan	    }
4524169689Skan	  else
4525169689Skan	    {
4526169689Skan	      c_parser_error (parser, "expected identifier");
4527169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
4528169689Skan	      return NULL_TREE;
4529169689Skan	    }
4530169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4531169689Skan				     "expected %<]%>");
4532169689Skan	}
4533169689Skan      else
4534169689Skan	name = NULL_TREE;
4535169689Skan      str = c_parser_asm_string_literal (parser);
4536169689Skan      if (str == NULL_TREE)
4537169689Skan	return NULL_TREE;
4538169689Skan      c_lex_string_translate = 1;
4539169689Skan      if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4540169689Skan	{
4541169689Skan	  c_lex_string_translate = 0;
4542169689Skan	  return NULL_TREE;
4543169689Skan	}
4544169689Skan      expr = c_parser_expression (parser);
4545169689Skan      if (convert_p)
4546169689Skan	expr = default_function_array_conversion (expr);
4547169689Skan      c_lex_string_translate = 0;
4548169689Skan      if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
4549169689Skan	{
4550169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4551169689Skan	  return NULL_TREE;
4552169689Skan	}
4553169689Skan      list = chainon (list, build_tree_list (build_tree_list (name, str),
4554169689Skan					     expr.value));
4555169689Skan      if (c_parser_next_token_is (parser, CPP_COMMA))
4556169689Skan	c_parser_consume_token (parser);
4557169689Skan      else
4558169689Skan	break;
4559169689Skan    }
4560169689Skan  return list;
4561169689Skan}
4562169689Skan
4563169689Skan/* Parse asm clobbers, a GNU extension.
4564169689Skan
4565169689Skan   asm-clobbers:
4566169689Skan     asm-string-literal
4567169689Skan     asm-clobbers , asm-string-literal
4568169689Skan*/
4569169689Skan
4570169689Skanstatic tree
4571169689Skanc_parser_asm_clobbers (c_parser *parser)
4572169689Skan{
4573169689Skan  tree list = NULL_TREE;
4574169689Skan  while (true)
4575169689Skan    {
4576169689Skan      tree str = c_parser_asm_string_literal (parser);
4577169689Skan      if (str)
4578169689Skan	list = tree_cons (NULL_TREE, str, list);
4579169689Skan      else
4580169689Skan	return NULL_TREE;
4581169689Skan      if (c_parser_next_token_is (parser, CPP_COMMA))
4582169689Skan	c_parser_consume_token (parser);
4583169689Skan      else
4584169689Skan	break;
4585169689Skan    }
4586169689Skan  return list;
4587169689Skan}
4588169689Skan
4589169689Skan/* Parse an expression other than a compound expression; that is, an
4590169689Skan   assignment expression (C90 6.3.16, C99 6.5.16).  If AFTER is not
4591169689Skan   NULL then it is an Objective-C message expression which is the
4592169689Skan   primary-expression starting the expression as an initializer.
4593169689Skan
4594169689Skan   assignment-expression:
4595169689Skan     conditional-expression
4596169689Skan     unary-expression assignment-operator assignment-expression
4597169689Skan
4598169689Skan   assignment-operator: one of
4599169689Skan     = *= /= %= += -= <<= >>= &= ^= |=
4600169689Skan
4601169689Skan   In GNU C we accept any conditional expression on the LHS and
4602169689Skan   diagnose the invalid lvalue rather than producing a syntax
4603169689Skan   error.  */
4604169689Skan
4605169689Skanstatic struct c_expr
4606169689Skanc_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
4607169689Skan{
4608169689Skan  struct c_expr lhs, rhs, ret;
4609169689Skan  enum tree_code code;
4610169689Skan  gcc_assert (!after || c_dialect_objc ());
4611169689Skan  lhs = c_parser_conditional_expression (parser, after);
4612169689Skan  switch (c_parser_peek_token (parser)->type)
4613169689Skan    {
4614169689Skan    case CPP_EQ:
4615169689Skan      code = NOP_EXPR;
4616169689Skan      break;
4617169689Skan    case CPP_MULT_EQ:
4618169689Skan      code = MULT_EXPR;
4619169689Skan      break;
4620169689Skan    case CPP_DIV_EQ:
4621169689Skan      code = TRUNC_DIV_EXPR;
4622169689Skan      break;
4623169689Skan    case CPP_MOD_EQ:
4624169689Skan      code = TRUNC_MOD_EXPR;
4625169689Skan      break;
4626169689Skan    case CPP_PLUS_EQ:
4627169689Skan      code = PLUS_EXPR;
4628169689Skan      break;
4629169689Skan    case CPP_MINUS_EQ:
4630169689Skan      code = MINUS_EXPR;
4631169689Skan      break;
4632169689Skan    case CPP_LSHIFT_EQ:
4633169689Skan      code = LSHIFT_EXPR;
4634169689Skan      break;
4635169689Skan    case CPP_RSHIFT_EQ:
4636169689Skan      code = RSHIFT_EXPR;
4637169689Skan      break;
4638169689Skan    case CPP_AND_EQ:
4639169689Skan      code = BIT_AND_EXPR;
4640169689Skan      break;
4641169689Skan    case CPP_XOR_EQ:
4642169689Skan      code = BIT_XOR_EXPR;
4643169689Skan      break;
4644169689Skan    case CPP_OR_EQ:
4645169689Skan      code = BIT_IOR_EXPR;
4646169689Skan      break;
4647169689Skan    default:
4648169689Skan      return lhs;
4649169689Skan    }
4650169689Skan  c_parser_consume_token (parser);
4651169689Skan  rhs = c_parser_expr_no_commas (parser, NULL);
4652169689Skan  rhs = default_function_array_conversion (rhs);
4653169689Skan  ret.value = build_modify_expr (lhs.value, code, rhs.value);
4654169689Skan  if (code == NOP_EXPR)
4655169689Skan    ret.original_code = MODIFY_EXPR;
4656169689Skan  else
4657169689Skan    {
4658169689Skan      TREE_NO_WARNING (ret.value) = 1;
4659169689Skan      ret.original_code = ERROR_MARK;
4660169689Skan    }
4661169689Skan  return ret;
4662169689Skan}
4663169689Skan
4664169689Skan/* Parse a conditional expression (C90 6.3.15, C99 6.5.15).  If AFTER
4665169689Skan   is not NULL then it is an Objective-C message expression which is
4666169689Skan   the primary-expression starting the expression as an initializer.
4667169689Skan
4668169689Skan   conditional-expression:
4669169689Skan     logical-OR-expression
4670169689Skan     logical-OR-expression ? expression : conditional-expression
4671169689Skan
4672169689Skan   GNU extensions:
4673169689Skan
4674169689Skan   conditional-expression:
4675169689Skan     logical-OR-expression ? : conditional-expression
4676169689Skan*/
4677169689Skan
4678169689Skanstatic struct c_expr
4679169689Skanc_parser_conditional_expression (c_parser *parser, struct c_expr *after)
4680169689Skan{
4681169689Skan  struct c_expr cond, exp1, exp2, ret;
4682169689Skan  gcc_assert (!after || c_dialect_objc ());
4683169689Skan  cond = c_parser_binary_expression (parser, after);
4684169689Skan  if (c_parser_next_token_is_not (parser, CPP_QUERY))
4685169689Skan    return cond;
4686169689Skan  cond = default_function_array_conversion (cond);
4687169689Skan  c_parser_consume_token (parser);
4688169689Skan  if (c_parser_next_token_is (parser, CPP_COLON))
4689169689Skan    {
4690169689Skan      if (pedantic)
4691169689Skan	pedwarn ("ISO C forbids omitting the middle term of a ?: expression");
4692169689Skan      /* Make sure first operand is calculated only once.  */
4693169689Skan      exp1.value = save_expr (default_conversion (cond.value));
4694169689Skan      cond.value = c_objc_common_truthvalue_conversion (exp1.value);
4695169689Skan      skip_evaluation += cond.value == truthvalue_true_node;
4696169689Skan    }
4697169689Skan  else
4698169689Skan    {
4699169689Skan      cond.value
4700169689Skan	= c_objc_common_truthvalue_conversion
4701169689Skan	(default_conversion (cond.value));
4702169689Skan      skip_evaluation += cond.value == truthvalue_false_node;
4703169689Skan      exp1 = c_parser_expression_conv (parser);
4704169689Skan      skip_evaluation += ((cond.value == truthvalue_true_node)
4705169689Skan			  - (cond.value == truthvalue_false_node));
4706169689Skan    }
4707169689Skan  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
4708169689Skan    {
4709169689Skan      skip_evaluation -= cond.value == truthvalue_true_node;
4710169689Skan      ret.value = error_mark_node;
4711169689Skan      ret.original_code = ERROR_MARK;
4712169689Skan      return ret;
4713169689Skan    }
4714169689Skan  exp2 = c_parser_conditional_expression (parser, NULL);
4715169689Skan  exp2 = default_function_array_conversion (exp2);
4716169689Skan  skip_evaluation -= cond.value == truthvalue_true_node;
4717169689Skan  ret.value = build_conditional_expr (cond.value, exp1.value, exp2.value);
4718169689Skan  ret.original_code = ERROR_MARK;
4719169689Skan  return ret;
4720169689Skan}
4721169689Skan
4722169689Skan/* Parse a binary expression; that is, a logical-OR-expression (C90
4723169689Skan   6.3.5-6.3.14, C99 6.5.5-6.5.14).  If AFTER is not NULL then it is
4724169689Skan   an Objective-C message expression which is the primary-expression
4725169689Skan   starting the expression as an initializer.
4726169689Skan
4727169689Skan   multiplicative-expression:
4728169689Skan     cast-expression
4729169689Skan     multiplicative-expression * cast-expression
4730169689Skan     multiplicative-expression / cast-expression
4731169689Skan     multiplicative-expression % cast-expression
4732169689Skan
4733169689Skan   additive-expression:
4734169689Skan     multiplicative-expression
4735169689Skan     additive-expression + multiplicative-expression
4736169689Skan     additive-expression - multiplicative-expression
4737169689Skan
4738169689Skan   shift-expression:
4739169689Skan     additive-expression
4740169689Skan     shift-expression << additive-expression
4741169689Skan     shift-expression >> additive-expression
4742169689Skan
4743169689Skan   relational-expression:
4744169689Skan     shift-expression
4745169689Skan     relational-expression < shift-expression
4746169689Skan     relational-expression > shift-expression
4747169689Skan     relational-expression <= shift-expression
4748169689Skan     relational-expression >= shift-expression
4749169689Skan
4750169689Skan   equality-expression:
4751169689Skan     relational-expression
4752169689Skan     equality-expression == relational-expression
4753169689Skan     equality-expression != relational-expression
4754169689Skan
4755169689Skan   AND-expression:
4756169689Skan     equality-expression
4757169689Skan     AND-expression & equality-expression
4758169689Skan
4759169689Skan   exclusive-OR-expression:
4760169689Skan     AND-expression
4761169689Skan     exclusive-OR-expression ^ AND-expression
4762169689Skan
4763169689Skan   inclusive-OR-expression:
4764169689Skan     exclusive-OR-expression
4765169689Skan     inclusive-OR-expression | exclusive-OR-expression
4766169689Skan
4767169689Skan   logical-AND-expression:
4768169689Skan     inclusive-OR-expression
4769169689Skan     logical-AND-expression && inclusive-OR-expression
4770169689Skan
4771169689Skan   logical-OR-expression:
4772169689Skan     logical-AND-expression
4773169689Skan     logical-OR-expression || logical-AND-expression
4774169689Skan*/
4775169689Skan
4776169689Skanstatic struct c_expr
4777169689Skanc_parser_binary_expression (c_parser *parser, struct c_expr *after)
4778169689Skan{
4779169689Skan  /* A binary expression is parsed using operator-precedence parsing,
4780169689Skan     with the operands being cast expressions.  All the binary
4781169689Skan     operators are left-associative.  Thus a binary expression is of
4782169689Skan     form:
4783169689Skan
4784169689Skan     E0 op1 E1 op2 E2 ...
4785169689Skan
4786169689Skan     which we represent on a stack.  On the stack, the precedence
4787169689Skan     levels are strictly increasing.  When a new operator is
4788169689Skan     encountered of higher precedence than that at the top of the
4789169689Skan     stack, it is pushed; its LHS is the top expression, and its RHS
4790169689Skan     is everything parsed until it is popped.  When a new operator is
4791169689Skan     encountered with precedence less than or equal to that at the top
4792169689Skan     of the stack, triples E[i-1] op[i] E[i] are popped and replaced
4793169689Skan     by the result of the operation until the operator at the top of
4794169689Skan     the stack has lower precedence than the new operator or there is
4795169689Skan     only one element on the stack; then the top expression is the LHS
4796169689Skan     of the new operator.  In the case of logical AND and OR
4797169689Skan     expressions, we also need to adjust skip_evaluation as
4798169689Skan     appropriate when the operators are pushed and popped.  */
4799169689Skan
4800169689Skan  /* The precedence levels, where 0 is a dummy lowest level used for
4801169689Skan     the bottom of the stack.  */
4802169689Skan  enum prec {
4803169689Skan    PREC_NONE,
4804169689Skan    PREC_LOGOR,
4805169689Skan    PREC_LOGAND,
4806169689Skan    PREC_BITOR,
4807169689Skan    PREC_BITXOR,
4808169689Skan    PREC_BITAND,
4809169689Skan    PREC_EQ,
4810169689Skan    PREC_REL,
4811169689Skan    PREC_SHIFT,
4812169689Skan    PREC_ADD,
4813169689Skan    PREC_MULT,
4814169689Skan    NUM_PRECS
4815169689Skan  };
4816169689Skan  struct {
4817169689Skan    /* The expression at this stack level.  */
4818169689Skan    struct c_expr expr;
4819169689Skan    /* The precedence of the operator on its left, PREC_NONE at the
4820169689Skan       bottom of the stack.  */
4821169689Skan    enum prec prec;
4822169689Skan    /* The operation on its left.  */
4823169689Skan    enum tree_code op;
4824169689Skan  } stack[NUM_PRECS];
4825169689Skan  int sp;
4826169689Skan#define POP								      \
4827169689Skan  do {									      \
4828169689Skan    switch (stack[sp].op)						      \
4829169689Skan      {									      \
4830169689Skan      case TRUTH_ANDIF_EXPR:						      \
4831169689Skan	skip_evaluation -= stack[sp - 1].expr.value == truthvalue_false_node; \
4832169689Skan	break;								      \
4833169689Skan      case TRUTH_ORIF_EXPR:						      \
4834169689Skan	skip_evaluation -= stack[sp - 1].expr.value == truthvalue_true_node;  \
4835169689Skan	break;								      \
4836169689Skan      default:								      \
4837169689Skan	break;								      \
4838169689Skan      }									      \
4839169689Skan    stack[sp - 1].expr							      \
4840169689Skan      = default_function_array_conversion (stack[sp - 1].expr);		      \
4841169689Skan    stack[sp].expr							      \
4842169689Skan      = default_function_array_conversion (stack[sp].expr);		      \
4843169689Skan    stack[sp - 1].expr = parser_build_binary_op (stack[sp].op,		      \
4844169689Skan						 stack[sp - 1].expr,	      \
4845169689Skan						 stack[sp].expr);	      \
4846169689Skan    sp--;								      \
4847169689Skan  } while (0)
4848169689Skan  gcc_assert (!after || c_dialect_objc ());
4849169689Skan  stack[0].expr = c_parser_cast_expression (parser, after);
4850261188Spfg  /* APPLE LOCAL begin radar 4426814 */
4851261188Spfg  if (c_dialect_objc() && flag_objc_gc)
4852261188Spfg    /* APPLE LOCAL radar 5276085 */
4853261188Spfg    stack[0].expr.value = objc_build_weak_reference_tree (stack[0].expr.value);
4854261188Spfg  /* APPLE LOCAL end radar 4426814 */
4855169689Skan  stack[0].prec = PREC_NONE;
4856169689Skan  sp = 0;
4857169689Skan  while (true)
4858169689Skan    {
4859169689Skan      enum prec oprec;
4860169689Skan      enum tree_code ocode;
4861169689Skan      if (parser->error)
4862169689Skan	goto out;
4863169689Skan      switch (c_parser_peek_token (parser)->type)
4864169689Skan	{
4865169689Skan	case CPP_MULT:
4866169689Skan	  oprec = PREC_MULT;
4867169689Skan	  ocode = MULT_EXPR;
4868169689Skan	  break;
4869169689Skan	case CPP_DIV:
4870169689Skan	  oprec = PREC_MULT;
4871169689Skan	  ocode = TRUNC_DIV_EXPR;
4872169689Skan	  break;
4873169689Skan	case CPP_MOD:
4874169689Skan	  oprec = PREC_MULT;
4875169689Skan	  ocode = TRUNC_MOD_EXPR;
4876169689Skan	  break;
4877169689Skan	case CPP_PLUS:
4878169689Skan	  oprec = PREC_ADD;
4879169689Skan	  ocode = PLUS_EXPR;
4880169689Skan	  break;
4881169689Skan	case CPP_MINUS:
4882169689Skan	  oprec = PREC_ADD;
4883169689Skan	  ocode = MINUS_EXPR;
4884169689Skan	  break;
4885169689Skan	case CPP_LSHIFT:
4886169689Skan	  oprec = PREC_SHIFT;
4887169689Skan	  ocode = LSHIFT_EXPR;
4888169689Skan	  break;
4889169689Skan	case CPP_RSHIFT:
4890169689Skan	  oprec = PREC_SHIFT;
4891169689Skan	  ocode = RSHIFT_EXPR;
4892169689Skan	  break;
4893169689Skan	case CPP_LESS:
4894169689Skan	  oprec = PREC_REL;
4895169689Skan	  ocode = LT_EXPR;
4896169689Skan	  break;
4897169689Skan	case CPP_GREATER:
4898169689Skan	  oprec = PREC_REL;
4899169689Skan	  ocode = GT_EXPR;
4900169689Skan	  break;
4901169689Skan	case CPP_LESS_EQ:
4902169689Skan	  oprec = PREC_REL;
4903169689Skan	  ocode = LE_EXPR;
4904169689Skan	  break;
4905169689Skan	case CPP_GREATER_EQ:
4906169689Skan	  oprec = PREC_REL;
4907169689Skan	  ocode = GE_EXPR;
4908169689Skan	  break;
4909169689Skan	case CPP_EQ_EQ:
4910169689Skan	  oprec = PREC_EQ;
4911169689Skan	  ocode = EQ_EXPR;
4912169689Skan	  break;
4913169689Skan	case CPP_NOT_EQ:
4914169689Skan	  oprec = PREC_EQ;
4915169689Skan	  ocode = NE_EXPR;
4916169689Skan	  break;
4917169689Skan	case CPP_AND:
4918169689Skan	  oprec = PREC_BITAND;
4919169689Skan	  ocode = BIT_AND_EXPR;
4920169689Skan	  break;
4921169689Skan	case CPP_XOR:
4922169689Skan	  oprec = PREC_BITXOR;
4923169689Skan	  ocode = BIT_XOR_EXPR;
4924169689Skan	  break;
4925169689Skan	case CPP_OR:
4926169689Skan	  oprec = PREC_BITOR;
4927169689Skan	  ocode = BIT_IOR_EXPR;
4928169689Skan	  break;
4929169689Skan	case CPP_AND_AND:
4930169689Skan	  oprec = PREC_LOGAND;
4931169689Skan	  ocode = TRUTH_ANDIF_EXPR;
4932169689Skan	  break;
4933169689Skan	case CPP_OR_OR:
4934169689Skan	  oprec = PREC_LOGOR;
4935169689Skan	  ocode = TRUTH_ORIF_EXPR;
4936169689Skan	  break;
4937169689Skan	default:
4938169689Skan	  /* Not a binary operator, so end of the binary
4939169689Skan	     expression.  */
4940169689Skan	  goto out;
4941169689Skan	}
4942169689Skan      c_parser_consume_token (parser);
4943169689Skan      while (oprec <= stack[sp].prec)
4944169689Skan	POP;
4945169689Skan      switch (ocode)
4946169689Skan	{
4947169689Skan	case TRUTH_ANDIF_EXPR:
4948169689Skan	  stack[sp].expr
4949169689Skan	    = default_function_array_conversion (stack[sp].expr);
4950169689Skan	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
4951169689Skan	    (default_conversion (stack[sp].expr.value));
4952169689Skan	  skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
4953169689Skan	  break;
4954169689Skan	case TRUTH_ORIF_EXPR:
4955169689Skan	  stack[sp].expr
4956169689Skan	    = default_function_array_conversion (stack[sp].expr);
4957169689Skan	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
4958169689Skan	    (default_conversion (stack[sp].expr.value));
4959169689Skan	  skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
4960169689Skan	  break;
4961169689Skan	default:
4962169689Skan	  break;
4963169689Skan	}
4964169689Skan      sp++;
4965169689Skan      stack[sp].expr = c_parser_cast_expression (parser, NULL);
4966261188Spfg      /* APPLE LOCAL begin radar 4426814 */
4967261188Spfg      if (c_dialect_objc() && flag_objc_gc)
4968261188Spfg	 /* APPLE LOCAL radar 5276085 */
4969261188Spfg	 stack[sp].expr.value = objc_build_weak_reference_tree (stack[sp].expr.value);
4970261188Spfg      /* APPLE LOCAL end radar 4426814 */
4971169689Skan      stack[sp].prec = oprec;
4972169689Skan      stack[sp].op = ocode;
4973169689Skan    }
4974169689Skan out:
4975169689Skan  while (sp > 0)
4976169689Skan    POP;
4977169689Skan  return stack[0].expr;
4978169689Skan#undef POP
4979169689Skan}
4980169689Skan
4981169689Skan/* Parse a cast expression (C90 6.3.4, C99 6.5.4).  If AFTER is not
4982169689Skan   NULL then it is an Objective-C message expression which is the
4983169689Skan   primary-expression starting the expression as an initializer.
4984169689Skan
4985169689Skan   cast-expression:
4986169689Skan     unary-expression
4987169689Skan     ( type-name ) unary-expression
4988169689Skan*/
4989169689Skan
4990169689Skanstatic struct c_expr
4991169689Skanc_parser_cast_expression (c_parser *parser, struct c_expr *after)
4992169689Skan{
4993169689Skan  gcc_assert (!after || c_dialect_objc ());
4994169689Skan  if (after)
4995169689Skan    return c_parser_postfix_expression_after_primary (parser, *after);
4996169689Skan  /* If the expression begins with a parenthesized type name, it may
4997169689Skan     be either a cast or a compound literal; we need to see whether
4998169689Skan     the next character is '{' to tell the difference.  If not, it is
4999169689Skan     an unary expression.  */
5000169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5001169689Skan      && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5002169689Skan    {
5003169689Skan      struct c_type_name *type_name;
5004169689Skan      struct c_expr ret;
5005169689Skan      struct c_expr expr;
5006169689Skan      c_parser_consume_token (parser);
5007169689Skan      type_name = c_parser_type_name (parser);
5008169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5009169689Skan      if (type_name == NULL)
5010169689Skan	{
5011169689Skan	  ret.value = error_mark_node;
5012169689Skan	  ret.original_code = ERROR_MARK;
5013169689Skan	  return ret;
5014169689Skan	}
5015169689Skan
5016169689Skan      /* Save casted types in the function's used types hash table.  */
5017169689Skan      used_types_insert (type_name->specs->type);
5018169689Skan
5019169689Skan      if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5020169689Skan	return c_parser_postfix_expression_after_paren_type (parser,
5021169689Skan							     type_name);
5022169689Skan      expr = c_parser_cast_expression (parser, NULL);
5023169689Skan      expr = default_function_array_conversion (expr);
5024169689Skan      ret.value = c_cast_expr (type_name, expr.value);
5025169689Skan      ret.original_code = ERROR_MARK;
5026169689Skan      return ret;
5027169689Skan    }
5028169689Skan  else
5029169689Skan    return c_parser_unary_expression (parser);
5030169689Skan}
5031169689Skan
5032169689Skan/* Parse an unary expression (C90 6.3.3, C99 6.5.3).
5033169689Skan
5034169689Skan   unary-expression:
5035169689Skan     postfix-expression
5036169689Skan     ++ unary-expression
5037169689Skan     -- unary-expression
5038169689Skan     unary-operator cast-expression
5039169689Skan     sizeof unary-expression
5040169689Skan     sizeof ( type-name )
5041169689Skan
5042169689Skan   unary-operator: one of
5043169689Skan     & * + - ~ !
5044169689Skan
5045169689Skan   GNU extensions:
5046169689Skan
5047169689Skan   unary-expression:
5048169689Skan     __alignof__ unary-expression
5049169689Skan     __alignof__ ( type-name )
5050169689Skan     && identifier
5051169689Skan
5052169689Skan   unary-operator: one of
5053169689Skan     __extension__ __real__ __imag__
5054169689Skan
5055169689Skan   In addition, the GNU syntax treats ++ and -- as unary operators, so
5056169689Skan   they may be applied to cast expressions with errors for non-lvalues
5057169689Skan   given later.  */
5058169689Skan
5059169689Skanstatic struct c_expr
5060169689Skanc_parser_unary_expression (c_parser *parser)
5061169689Skan{
5062169689Skan  int ext;
5063169689Skan  struct c_expr ret, op;
5064169689Skan  switch (c_parser_peek_token (parser)->type)
5065169689Skan    {
5066169689Skan    case CPP_PLUS_PLUS:
5067169689Skan      c_parser_consume_token (parser);
5068169689Skan      op = c_parser_cast_expression (parser, NULL);
5069169689Skan      op = default_function_array_conversion (op);
5070169689Skan      return parser_build_unary_op (PREINCREMENT_EXPR, op);
5071169689Skan    case CPP_MINUS_MINUS:
5072169689Skan      c_parser_consume_token (parser);
5073169689Skan      op = c_parser_cast_expression (parser, NULL);
5074169689Skan      op = default_function_array_conversion (op);
5075169689Skan      return parser_build_unary_op (PREDECREMENT_EXPR, op);
5076169689Skan    case CPP_AND:
5077169689Skan      c_parser_consume_token (parser);
5078169689Skan      return parser_build_unary_op (ADDR_EXPR,
5079169689Skan				    c_parser_cast_expression (parser, NULL));
5080169689Skan    case CPP_MULT:
5081169689Skan      c_parser_consume_token (parser);
5082169689Skan      op = c_parser_cast_expression (parser, NULL);
5083169689Skan      op = default_function_array_conversion (op);
5084169689Skan      ret.value = build_indirect_ref (op.value, "unary *");
5085169689Skan      ret.original_code = ERROR_MARK;
5086169689Skan      return ret;
5087169689Skan    case CPP_PLUS:
5088169689Skan      c_parser_consume_token (parser);
5089169689Skan      if (!c_dialect_objc () && !in_system_header)
5090169689Skan	warning (OPT_Wtraditional,
5091169689Skan		 "traditional C rejects the unary plus operator");
5092169689Skan      op = c_parser_cast_expression (parser, NULL);
5093169689Skan      op = default_function_array_conversion (op);
5094169689Skan      return parser_build_unary_op (CONVERT_EXPR, op);
5095169689Skan    case CPP_MINUS:
5096169689Skan      c_parser_consume_token (parser);
5097169689Skan      op = c_parser_cast_expression (parser, NULL);
5098169689Skan      op = default_function_array_conversion (op);
5099169689Skan      return parser_build_unary_op (NEGATE_EXPR, op);
5100169689Skan    case CPP_COMPL:
5101169689Skan      c_parser_consume_token (parser);
5102169689Skan      op = c_parser_cast_expression (parser, NULL);
5103169689Skan      op = default_function_array_conversion (op);
5104169689Skan      return parser_build_unary_op (BIT_NOT_EXPR, op);
5105169689Skan    case CPP_NOT:
5106169689Skan      c_parser_consume_token (parser);
5107169689Skan      op = c_parser_cast_expression (parser, NULL);
5108169689Skan      op = default_function_array_conversion (op);
5109169689Skan      return parser_build_unary_op (TRUTH_NOT_EXPR, op);
5110169689Skan    case CPP_AND_AND:
5111169689Skan      /* Refer to the address of a label as a pointer.  */
5112169689Skan      c_parser_consume_token (parser);
5113169689Skan      if (c_parser_next_token_is (parser, CPP_NAME))
5114169689Skan	{
5115169689Skan	  ret.value = finish_label_address_expr
5116169689Skan	    (c_parser_peek_token (parser)->value);
5117169689Skan	  c_parser_consume_token (parser);
5118169689Skan	}
5119169689Skan      else
5120169689Skan	{
5121169689Skan	  c_parser_error (parser, "expected identifier");
5122169689Skan	  ret.value = error_mark_node;
5123169689Skan	}
5124169689Skan	ret.original_code = ERROR_MARK;
5125169689Skan	return ret;
5126169689Skan    case CPP_KEYWORD:
5127169689Skan      switch (c_parser_peek_token (parser)->keyword)
5128169689Skan	{
5129169689Skan	case RID_SIZEOF:
5130169689Skan	  return c_parser_sizeof_expression (parser);
5131169689Skan	case RID_ALIGNOF:
5132169689Skan	  return c_parser_alignof_expression (parser);
5133169689Skan	case RID_EXTENSION:
5134169689Skan	  c_parser_consume_token (parser);
5135169689Skan	  ext = disable_extension_diagnostics ();
5136169689Skan	  ret = c_parser_cast_expression (parser, NULL);
5137169689Skan	  restore_extension_diagnostics (ext);
5138169689Skan	  return ret;
5139169689Skan	case RID_REALPART:
5140169689Skan	  c_parser_consume_token (parser);
5141169689Skan	  op = c_parser_cast_expression (parser, NULL);
5142169689Skan	  op = default_function_array_conversion (op);
5143169689Skan	  return parser_build_unary_op (REALPART_EXPR, op);
5144169689Skan	case RID_IMAGPART:
5145169689Skan	  c_parser_consume_token (parser);
5146169689Skan	  op = c_parser_cast_expression (parser, NULL);
5147169689Skan	  op = default_function_array_conversion (op);
5148169689Skan	  return parser_build_unary_op (IMAGPART_EXPR, op);
5149169689Skan	default:
5150169689Skan	  return c_parser_postfix_expression (parser);
5151169689Skan	}
5152169689Skan    default:
5153169689Skan      return c_parser_postfix_expression (parser);
5154169689Skan    }
5155169689Skan}
5156169689Skan
5157169689Skan/* Parse a sizeof expression.  */
5158169689Skan
5159169689Skanstatic struct c_expr
5160169689Skanc_parser_sizeof_expression (c_parser *parser)
5161169689Skan{
5162169689Skan  struct c_expr expr;
5163169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
5164169689Skan  c_parser_consume_token (parser);
5165169689Skan  skip_evaluation++;
5166169689Skan  in_sizeof++;
5167169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5168169689Skan      && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5169169689Skan    {
5170169689Skan      /* Either sizeof ( type-name ) or sizeof unary-expression
5171169689Skan	 starting with a compound literal.  */
5172169689Skan      struct c_type_name *type_name;
5173169689Skan      c_parser_consume_token (parser);
5174169689Skan      type_name = c_parser_type_name (parser);
5175169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5176169689Skan      if (type_name == NULL)
5177169689Skan	{
5178169689Skan	  struct c_expr ret;
5179169689Skan	  skip_evaluation--;
5180169689Skan	  in_sizeof--;
5181169689Skan	  ret.value = error_mark_node;
5182169689Skan	  ret.original_code = ERROR_MARK;
5183169689Skan	  return ret;
5184169689Skan	}
5185169689Skan      if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5186169689Skan	{
5187169689Skan	  expr = c_parser_postfix_expression_after_paren_type (parser,
5188169689Skan							       type_name);
5189169689Skan	  goto sizeof_expr;
5190169689Skan	}
5191169689Skan      /* sizeof ( type-name ).  */
5192169689Skan      skip_evaluation--;
5193169689Skan      in_sizeof--;
5194169689Skan      if (type_name->declarator->kind == cdk_array
5195169689Skan	  && type_name->declarator->u.array.vla_unspec_p)
5196169689Skan	{
5197169689Skan	  /* C99 6.7.5.2p4 */
5198169689Skan	  error ("%<[*]%> not allowed in other than a declaration");
5199169689Skan	}
5200169689Skan      return c_expr_sizeof_type (type_name);
5201169689Skan    }
5202169689Skan  else
5203169689Skan    {
5204169689Skan      expr = c_parser_unary_expression (parser);
5205169689Skan    sizeof_expr:
5206169689Skan      skip_evaluation--;
5207169689Skan      in_sizeof--;
5208169689Skan      if (TREE_CODE (expr.value) == COMPONENT_REF
5209169689Skan	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
5210169689Skan	error ("%<sizeof%> applied to a bit-field");
5211169689Skan      return c_expr_sizeof_expr (expr);
5212169689Skan    }
5213169689Skan}
5214169689Skan
5215169689Skan/* Parse an alignof expression.  */
5216169689Skan
5217169689Skanstatic struct c_expr
5218169689Skanc_parser_alignof_expression (c_parser *parser)
5219169689Skan{
5220169689Skan  struct c_expr expr;
5221169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
5222169689Skan  c_parser_consume_token (parser);
5223169689Skan  skip_evaluation++;
5224169689Skan  in_alignof++;
5225169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5226169689Skan      && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5227169689Skan    {
5228169689Skan      /* Either __alignof__ ( type-name ) or __alignof__
5229169689Skan	 unary-expression starting with a compound literal.  */
5230169689Skan      struct c_type_name *type_name;
5231169689Skan      struct c_expr ret;
5232169689Skan      c_parser_consume_token (parser);
5233169689Skan      type_name = c_parser_type_name (parser);
5234169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5235169689Skan      if (type_name == NULL)
5236169689Skan	{
5237169689Skan	  struct c_expr ret;
5238169689Skan	  skip_evaluation--;
5239169689Skan	  in_alignof--;
5240169689Skan	  ret.value = error_mark_node;
5241169689Skan	  ret.original_code = ERROR_MARK;
5242169689Skan	  return ret;
5243169689Skan	}
5244169689Skan      if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5245169689Skan	{
5246169689Skan	  expr = c_parser_postfix_expression_after_paren_type (parser,
5247169689Skan							       type_name);
5248169689Skan	  goto alignof_expr;
5249169689Skan	}
5250169689Skan      /* alignof ( type-name ).  */
5251169689Skan      skip_evaluation--;
5252169689Skan      in_alignof--;
5253169689Skan      ret.value = c_alignof (groktypename (type_name));
5254169689Skan      ret.original_code = ERROR_MARK;
5255169689Skan      return ret;
5256169689Skan    }
5257169689Skan  else
5258169689Skan    {
5259169689Skan      struct c_expr ret;
5260169689Skan      expr = c_parser_unary_expression (parser);
5261169689Skan    alignof_expr:
5262169689Skan      skip_evaluation--;
5263169689Skan      in_alignof--;
5264169689Skan      ret.value = c_alignof_expr (expr.value);
5265169689Skan      ret.original_code = ERROR_MARK;
5266169689Skan      return ret;
5267169689Skan    }
5268169689Skan}
5269169689Skan
5270169689Skan/* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2).
5271169689Skan
5272169689Skan   postfix-expression:
5273169689Skan     primary-expression
5274169689Skan     postfix-expression [ expression ]
5275169689Skan     postfix-expression ( argument-expression-list[opt] )
5276169689Skan     postfix-expression . identifier
5277169689Skan     postfix-expression -> identifier
5278169689Skan     postfix-expression ++
5279169689Skan     postfix-expression --
5280169689Skan     ( type-name ) { initializer-list }
5281169689Skan     ( type-name ) { initializer-list , }
5282169689Skan
5283169689Skan   argument-expression-list:
5284169689Skan     argument-expression
5285169689Skan     argument-expression-list , argument-expression
5286169689Skan
5287169689Skan   primary-expression:
5288169689Skan     identifier
5289169689Skan     constant
5290169689Skan     string-literal
5291169689Skan     ( expression )
5292169689Skan
5293169689Skan   GNU extensions:
5294169689Skan
5295169689Skan   primary-expression:
5296169689Skan     __func__
5297169689Skan       (treated as a keyword in GNU C)
5298169689Skan     __FUNCTION__
5299169689Skan     __PRETTY_FUNCTION__
5300169689Skan     ( compound-statement )
5301169689Skan     __builtin_va_arg ( assignment-expression , type-name )
5302169689Skan     __builtin_offsetof ( type-name , offsetof-member-designator )
5303169689Skan     __builtin_choose_expr ( assignment-expression ,
5304169689Skan			     assignment-expression ,
5305169689Skan			     assignment-expression )
5306169689Skan     __builtin_types_compatible_p ( type-name , type-name )
5307261188Spfg     APPLE LOCAL blocks (C++ cf)
5308261188Spfg     block-literal-expr
5309169689Skan
5310169689Skan   offsetof-member-designator:
5311169689Skan     identifier
5312169689Skan     offsetof-member-designator . identifier
5313169689Skan     offsetof-member-designator [ expression ]
5314169689Skan
5315169689Skan   Objective-C:
5316169689Skan
5317169689Skan   primary-expression:
5318169689Skan     [ objc-receiver objc-message-args ]
5319169689Skan     @selector ( objc-selector-arg )
5320169689Skan     @protocol ( identifier )
5321169689Skan     @encode ( type-name )
5322169689Skan     objc-string-literal
5323169689Skan*/
5324169689Skan
5325169689Skanstatic struct c_expr
5326169689Skanc_parser_postfix_expression (c_parser *parser)
5327169689Skan{
5328169689Skan  struct c_expr expr, e1, e2, e3;
5329169689Skan  struct c_type_name *t1, *t2;
5330169689Skan  switch (c_parser_peek_token (parser)->type)
5331169689Skan    {
5332169689Skan    case CPP_NUMBER:
5333169689Skan    case CPP_CHAR:
5334169689Skan    case CPP_WCHAR:
5335169689Skan      expr.value = c_parser_peek_token (parser)->value;
5336169689Skan      expr.original_code = ERROR_MARK;
5337169689Skan      c_parser_consume_token (parser);
5338169689Skan      break;
5339169689Skan    case CPP_STRING:
5340169689Skan    case CPP_WSTRING:
5341169689Skan      expr.value = c_parser_peek_token (parser)->value;
5342169689Skan      expr.original_code = STRING_CST;
5343169689Skan      c_parser_consume_token (parser);
5344169689Skan      break;
5345169689Skan    case CPP_OBJC_STRING:
5346169689Skan      gcc_assert (c_dialect_objc ());
5347169689Skan      expr.value
5348169689Skan	= objc_build_string_object (c_parser_peek_token (parser)->value);
5349169689Skan      expr.original_code = ERROR_MARK;
5350169689Skan      c_parser_consume_token (parser);
5351169689Skan      break;
5352169689Skan    case CPP_NAME:
5353261188Spfg      /* APPLE LOCAL begin radar 5277239 */
5354261188Spfg      if (c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME
5355261188Spfg	  && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
5356261188Spfg	{
5357261188Spfg	  /* CLASS.class_method expression. */
5358261188Spfg	  tree receiver, component;
5359261188Spfg	  receiver = c_parser_objc_receiver (parser);
5360261188Spfg	   /* consume '.' operator */
5361261188Spfg	  c_parser_consume_token (parser);
5362261188Spfg	  component = c_parser_objc_message_args (parser);
5363261188Spfg	  expr.value = objc_build_property_reference_expr (receiver, component);
5364261188Spfg	  expr.original_code = ERROR_MARK;
5365261188Spfg	  break;
5366261188Spfg	}
5367261188Spfg      /* APPLE LOCAL end radar 5277239 */
5368169689Skan      if (c_parser_peek_token (parser)->id_kind != C_ID_ID)
5369169689Skan	{
5370169689Skan	  c_parser_error (parser, "expected expression");
5371169689Skan	  expr.value = error_mark_node;
5372169689Skan	  expr.original_code = ERROR_MARK;
5373169689Skan	  break;
5374169689Skan	}
5375169689Skan      {
5376169689Skan	tree id = c_parser_peek_token (parser)->value;
5377169689Skan	location_t loc = c_parser_peek_token (parser)->location;
5378169689Skan	c_parser_consume_token (parser);
5379169689Skan	expr.value = build_external_ref (id,
5380169689Skan					 (c_parser_peek_token (parser)->type
5381169689Skan					  == CPP_OPEN_PAREN), loc);
5382261188Spfg	 /* APPLE LOCAL begin radar 5732232 - blocks (C++ cd) */
5383261188Spfg	 /* If a variabled declared as referenced variable, using |...| syntax,
5384261188Spfg	    is used in the block, it has to be derefrenced because this
5385261188Spfg	    variable holds address of the outside variable referenced in. */
5386261188Spfg
5387261188Spfg	 /* APPLE LOCAL begin radar 5932809 - copyable byref blocks (C++ cd) */
5388261188Spfg	 if (TREE_CODE (expr.value) == VAR_DECL)
5389261188Spfg	  {
5390261188Spfg	    if (BLOCK_DECL_BYREF (expr.value))
5391261188Spfg	      {
5392261188Spfg		tree orig_decl = expr.value;
5393261188Spfg		expr.value = build_indirect_ref (expr.value, "unary *");
5394261188Spfg		if (COPYABLE_BYREF_LOCAL_VAR (orig_decl)) {
5395261188Spfg		  /* What we have is an expression which is of type
5396261188Spfg		     struct __Block_byref_X. Must get to the value of the variable
5397261188Spfg		     embedded in this structure. It is at:
5398261188Spfg		     __Block_byref_X.__forwarding->x */
5399261188Spfg		  expr.value = build_byref_local_var_access (expr.value,
5400261188Spfg							     DECL_NAME (orig_decl));
5401261188Spfg		}
5402261188Spfg	      }
5403261188Spfg	    else if (COPYABLE_BYREF_LOCAL_VAR (expr.value))
5404261188Spfg	       expr.value = build_byref_local_var_access (expr.value,
5405261188Spfg			                                  DECL_NAME (expr.value));
5406261188Spfg	 }
5407261188Spfg	 /* APPLE LOCAL end radar 5932809 - copyable byref blocks */
5408261188Spfg
5409261188Spfg	 /* APPLE LOCAL end radar 5732232 - blocks (C++ cd) */
5410169689Skan	expr.original_code = ERROR_MARK;
5411169689Skan      }
5412169689Skan      break;
5413169689Skan    case CPP_OPEN_PAREN:
5414169689Skan      /* A parenthesized expression, statement expression or compound
5415169689Skan	 literal.  */
5416169689Skan      if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
5417169689Skan	{
5418169689Skan	  /* A statement expression.  */
5419169689Skan	  tree stmt;
5420169689Skan	  c_parser_consume_token (parser);
5421169689Skan	  c_parser_consume_token (parser);
5422169689Skan	  if (cur_stmt_list == NULL)
5423169689Skan	    {
5424169689Skan	      error ("braced-group within expression allowed "
5425169689Skan		     "only inside a function");
5426169689Skan	      parser->error = true;
5427169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
5428169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5429169689Skan	      expr.value = error_mark_node;
5430169689Skan	      expr.original_code = ERROR_MARK;
5431169689Skan	      break;
5432169689Skan	    }
5433169689Skan	  stmt = c_begin_stmt_expr ();
5434169689Skan	  c_parser_compound_statement_nostart (parser);
5435169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5436169689Skan				     "expected %<)%>");
5437169689Skan	  if (pedantic)
5438169689Skan	    pedwarn ("ISO C forbids braced-groups within expressions");
5439169689Skan	  expr.value = c_finish_stmt_expr (stmt);
5440169689Skan	  expr.original_code = ERROR_MARK;
5441169689Skan	}
5442169689Skan      else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5443169689Skan	{
5444169689Skan	  /* A compound literal.  ??? Can we actually get here rather
5445169689Skan	     than going directly to
5446169689Skan	     c_parser_postfix_expression_after_paren_type from
5447169689Skan	     elsewhere?  */
5448169689Skan	  struct c_type_name *type_name;
5449169689Skan	  c_parser_consume_token (parser);
5450169689Skan	  type_name = c_parser_type_name (parser);
5451169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5452169689Skan				     "expected %<)%>");
5453169689Skan	  if (type_name == NULL)
5454169689Skan	    {
5455169689Skan	      expr.value = error_mark_node;
5456169689Skan	      expr.original_code = ERROR_MARK;
5457169689Skan	    }
5458169689Skan	  else
5459169689Skan	    expr = c_parser_postfix_expression_after_paren_type (parser,
5460169689Skan								 type_name);
5461169689Skan	}
5462169689Skan      else
5463169689Skan	{
5464169689Skan	  /* A parenthesized expression.  */
5465169689Skan	  c_parser_consume_token (parser);
5466169689Skan	  expr = c_parser_expression (parser);
5467169689Skan	  if (TREE_CODE (expr.value) == MODIFY_EXPR)
5468169689Skan	    TREE_NO_WARNING (expr.value) = 1;
5469169689Skan	  expr.original_code = ERROR_MARK;
5470169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5471169689Skan				     "expected %<)%>");
5472169689Skan	}
5473169689Skan      break;
5474169689Skan    case CPP_KEYWORD:
5475169689Skan      switch (c_parser_peek_token (parser)->keyword)
5476169689Skan	{
5477169689Skan	case RID_FUNCTION_NAME:
5478169689Skan	case RID_PRETTY_FUNCTION_NAME:
5479169689Skan	case RID_C99_FUNCTION_NAME:
5480169689Skan	  expr.value = fname_decl (c_parser_peek_token (parser)->keyword,
5481169689Skan				   c_parser_peek_token (parser)->value);
5482169689Skan	  expr.original_code = ERROR_MARK;
5483169689Skan	  c_parser_consume_token (parser);
5484169689Skan	  break;
5485169689Skan	case RID_VA_ARG:
5486169689Skan	  c_parser_consume_token (parser);
5487169689Skan	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5488169689Skan	    {
5489169689Skan	      expr.value = error_mark_node;
5490169689Skan	      expr.original_code = ERROR_MARK;
5491169689Skan	      break;
5492169689Skan	    }
5493169689Skan	  e1 = c_parser_expr_no_commas (parser, NULL);
5494169689Skan	  if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
5495169689Skan	    {
5496169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5497169689Skan	      expr.value = error_mark_node;
5498169689Skan	      expr.original_code = ERROR_MARK;
5499169689Skan	      break;
5500169689Skan	    }
5501169689Skan	  t1 = c_parser_type_name (parser);
5502169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5503169689Skan				     "expected %<)%>");
5504169689Skan	  if (t1 == NULL)
5505169689Skan	    {
5506169689Skan	      expr.value = error_mark_node;
5507169689Skan	      expr.original_code = ERROR_MARK;
5508169689Skan	    }
5509169689Skan	  else
5510169689Skan	    {
5511169689Skan	      expr.value = build_va_arg (e1.value, groktypename (t1));
5512169689Skan	      expr.original_code = ERROR_MARK;
5513169689Skan	    }
5514169689Skan	  break;
5515169689Skan	case RID_OFFSETOF:
5516169689Skan	  c_parser_consume_token (parser);
5517169689Skan	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5518169689Skan	    {
5519169689Skan	      expr.value = error_mark_node;
5520169689Skan	      expr.original_code = ERROR_MARK;
5521169689Skan	      break;
5522169689Skan	    }
5523169689Skan	  t1 = c_parser_type_name (parser);
5524169689Skan	  if (t1 == NULL)
5525169689Skan	    {
5526169689Skan	      expr.value = error_mark_node;
5527169689Skan	      expr.original_code = ERROR_MARK;
5528169689Skan	      break;
5529169689Skan	    }
5530169689Skan	  if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
5531169689Skan	    {
5532169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5533169689Skan	      expr.value = error_mark_node;
5534169689Skan	      expr.original_code = ERROR_MARK;
5535169689Skan	      break;
5536169689Skan	    }
5537169689Skan	  {
5538169689Skan	    tree type = groktypename (t1);
5539169689Skan	    tree offsetof_ref;
5540169689Skan	    if (type == error_mark_node)
5541169689Skan	      offsetof_ref = error_mark_node;
5542169689Skan	    else
5543169689Skan	      offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
5544169689Skan	    /* Parse the second argument to __builtin_offsetof.  We
5545169689Skan	       must have one identifier, and beyond that we want to
5546169689Skan	       accept sub structure and sub array references.  */
5547169689Skan	    if (c_parser_next_token_is (parser, CPP_NAME))
5548169689Skan	      {
5549169689Skan		offsetof_ref = build_component_ref
5550169689Skan		  (offsetof_ref, c_parser_peek_token (parser)->value);
5551169689Skan		c_parser_consume_token (parser);
5552169689Skan		while (c_parser_next_token_is (parser, CPP_DOT)
5553169689Skan		       || c_parser_next_token_is (parser,
5554169689Skan						  CPP_OPEN_SQUARE))
5555169689Skan		  {
5556169689Skan		    if (c_parser_next_token_is (parser, CPP_DOT))
5557169689Skan		      {
5558169689Skan			c_parser_consume_token (parser);
5559169689Skan			if (c_parser_next_token_is_not (parser,
5560169689Skan							CPP_NAME))
5561169689Skan			  {
5562169689Skan			    c_parser_error (parser, "expected identifier");
5563169689Skan			    break;
5564169689Skan			  }
5565169689Skan			offsetof_ref = build_component_ref
5566169689Skan			  (offsetof_ref,
5567169689Skan			   c_parser_peek_token (parser)->value);
5568169689Skan			c_parser_consume_token (parser);
5569169689Skan		      }
5570169689Skan		    else
5571169689Skan		      {
5572169689Skan			tree idx;
5573169689Skan			c_parser_consume_token (parser);
5574169689Skan			idx = c_parser_expression (parser).value;
5575169689Skan			c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5576169689Skan						   "expected %<]%>");
5577169689Skan			offsetof_ref = build_array_ref (offsetof_ref, idx);
5578169689Skan		      }
5579169689Skan		  }
5580169689Skan	      }
5581169689Skan	    else
5582169689Skan	      c_parser_error (parser, "expected identifier");
5583169689Skan	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5584169689Skan				       "expected %<)%>");
5585169689Skan	    expr.value = fold_offsetof (offsetof_ref, NULL_TREE);
5586169689Skan	    expr.original_code = ERROR_MARK;
5587169689Skan	  }
5588169689Skan	  break;
5589169689Skan	case RID_CHOOSE_EXPR:
5590169689Skan	  c_parser_consume_token (parser);
5591169689Skan	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5592169689Skan	    {
5593169689Skan	      expr.value = error_mark_node;
5594169689Skan	      expr.original_code = ERROR_MARK;
5595169689Skan	      break;
5596169689Skan	    }
5597169689Skan	  e1 = c_parser_expr_no_commas (parser, NULL);
5598169689Skan	  if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
5599169689Skan	    {
5600169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5601169689Skan	      expr.value = error_mark_node;
5602169689Skan	      expr.original_code = ERROR_MARK;
5603169689Skan	      break;
5604169689Skan	    }
5605169689Skan	  e2 = c_parser_expr_no_commas (parser, NULL);
5606169689Skan	  if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
5607169689Skan	    {
5608169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5609169689Skan	      expr.value = error_mark_node;
5610169689Skan	      expr.original_code = ERROR_MARK;
5611169689Skan	      break;
5612169689Skan	    }
5613169689Skan	  e3 = c_parser_expr_no_commas (parser, NULL);
5614169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5615169689Skan				     "expected %<)%>");
5616169689Skan	  {
5617169689Skan	    tree c;
5618169689Skan
5619169689Skan	    c = fold (e1.value);
5620169689Skan	    if (TREE_CODE (c) != INTEGER_CST)
5621169689Skan	      error ("first argument to %<__builtin_choose_expr%> not"
5622169689Skan		     " a constant");
5623169689Skan	    expr = integer_zerop (c) ? e3 : e2;
5624169689Skan	  }
5625169689Skan	  break;
5626169689Skan	case RID_TYPES_COMPATIBLE_P:
5627169689Skan	  c_parser_consume_token (parser);
5628169689Skan	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5629169689Skan	    {
5630169689Skan	      expr.value = error_mark_node;
5631169689Skan	      expr.original_code = ERROR_MARK;
5632169689Skan	      break;
5633169689Skan	    }
5634169689Skan	  t1 = c_parser_type_name (parser);
5635169689Skan	  if (t1 == NULL)
5636169689Skan	    {
5637169689Skan	      expr.value = error_mark_node;
5638169689Skan	      expr.original_code = ERROR_MARK;
5639169689Skan	      break;
5640169689Skan	    }
5641169689Skan	  if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
5642169689Skan	    {
5643169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5644169689Skan	      expr.value = error_mark_node;
5645169689Skan	      expr.original_code = ERROR_MARK;
5646169689Skan	      break;
5647169689Skan	    }
5648169689Skan	  t2 = c_parser_type_name (parser);
5649169689Skan	  if (t2 == NULL)
5650169689Skan	    {
5651169689Skan	      expr.value = error_mark_node;
5652169689Skan	      expr.original_code = ERROR_MARK;
5653169689Skan	      break;
5654169689Skan	    }
5655169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5656169689Skan				     "expected %<)%>");
5657169689Skan	  {
5658169689Skan	    tree e1, e2;
5659169689Skan
5660169689Skan	    e1 = TYPE_MAIN_VARIANT (groktypename (t1));
5661169689Skan	    e2 = TYPE_MAIN_VARIANT (groktypename (t2));
5662169689Skan
5663169689Skan	    expr.value = comptypes (e1, e2)
5664169689Skan	      ? build_int_cst (NULL_TREE, 1)
5665169689Skan	      : build_int_cst (NULL_TREE, 0);
5666169689Skan	    expr.original_code = ERROR_MARK;
5667169689Skan	  }
5668169689Skan	  break;
5669169689Skan	case RID_AT_SELECTOR:
5670169689Skan	  gcc_assert (c_dialect_objc ());
5671169689Skan	  c_parser_consume_token (parser);
5672169689Skan	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5673169689Skan	    {
5674169689Skan	      expr.value = error_mark_node;
5675169689Skan	      expr.original_code = ERROR_MARK;
5676169689Skan	      break;
5677169689Skan	    }
5678169689Skan	  {
5679169689Skan	    tree sel = c_parser_objc_selector_arg (parser);
5680169689Skan	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5681169689Skan				       "expected %<)%>");
5682169689Skan	    expr.value = objc_build_selector_expr (sel);
5683169689Skan	    expr.original_code = ERROR_MARK;
5684169689Skan	  }
5685169689Skan	  break;
5686169689Skan	case RID_AT_PROTOCOL:
5687169689Skan	  gcc_assert (c_dialect_objc ());
5688169689Skan	  c_parser_consume_token (parser);
5689169689Skan	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5690169689Skan	    {
5691169689Skan	      expr.value = error_mark_node;
5692169689Skan	      expr.original_code = ERROR_MARK;
5693169689Skan	      break;
5694169689Skan	    }
5695169689Skan	  if (c_parser_next_token_is_not (parser, CPP_NAME))
5696169689Skan	    {
5697169689Skan	      c_parser_error (parser, "expected identifier");
5698169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5699169689Skan	      expr.value = error_mark_node;
5700169689Skan	      expr.original_code = ERROR_MARK;
5701169689Skan	      break;
5702169689Skan	    }
5703169689Skan	  {
5704169689Skan	    tree id = c_parser_peek_token (parser)->value;
5705169689Skan	    c_parser_consume_token (parser);
5706169689Skan	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5707169689Skan				       "expected %<)%>");
5708169689Skan	    expr.value = objc_build_protocol_expr (id);
5709169689Skan	    expr.original_code = ERROR_MARK;
5710169689Skan	  }
5711169689Skan	  break;
5712169689Skan	case RID_AT_ENCODE:
5713169689Skan	  /* Extension to support C-structures in the archiver.  */
5714169689Skan	  gcc_assert (c_dialect_objc ());
5715169689Skan	  c_parser_consume_token (parser);
5716169689Skan	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5717169689Skan	    {
5718169689Skan	      expr.value = error_mark_node;
5719169689Skan	      expr.original_code = ERROR_MARK;
5720169689Skan	      break;
5721169689Skan	    }
5722169689Skan	  t1 = c_parser_type_name (parser);
5723169689Skan	  if (t1 == NULL)
5724169689Skan	    {
5725169689Skan	      expr.value = error_mark_node;
5726169689Skan	      expr.original_code = ERROR_MARK;
5727169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5728169689Skan	      break;
5729169689Skan	    }
5730169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5731169689Skan				     "expected %<)%>");
5732169689Skan	  {
5733169689Skan	    tree type = groktypename (t1);
5734169689Skan	    expr.value = objc_build_encode_expr (type);
5735169689Skan	    expr.original_code = ERROR_MARK;
5736169689Skan	  }
5737169689Skan	  break;
5738169689Skan	default:
5739169689Skan	  c_parser_error (parser, "expected expression");
5740169689Skan	  expr.value = error_mark_node;
5741169689Skan	  expr.original_code = ERROR_MARK;
5742169689Skan	  break;
5743169689Skan	}
5744169689Skan      break;
5745261188Spfg    /* APPLE LOCAL begin radar 5732232 - blocks (C++ cf) */
5746261188Spfg    case CPP_XOR:
5747261188Spfg	 if (flag_blocks) {
5748261188Spfg	   expr.value = c_parser_block_literal_expr (parser);
5749261188Spfg	   expr.original_code = ERROR_MARK;
5750261188Spfg	   break;
5751261188Spfg	 }
5752261188Spfg	 c_parser_error (parser, "expected expression");
5753261188Spfg	 expr.value = error_mark_node;
5754261188Spfg	 expr.original_code = ERROR_MARK;
5755261188Spfg	 break;
5756261188Spfg    /* APPLE LOCAL end radar 5732232 - blocks (C++ cf) */
5757169689Skan    case CPP_OPEN_SQUARE:
5758169689Skan      if (c_dialect_objc ())
5759169689Skan	{
5760169689Skan	  tree receiver, args;
5761169689Skan	  c_parser_consume_token (parser);
5762169689Skan	  receiver = c_parser_objc_receiver (parser);
5763169689Skan	  args = c_parser_objc_message_args (parser);
5764169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5765169689Skan				     "expected %<]%>");
5766169689Skan	  expr.value = objc_build_message_expr (build_tree_list (receiver,
5767169689Skan								 args));
5768169689Skan	  expr.original_code = ERROR_MARK;
5769169689Skan	  break;
5770169689Skan	}
5771169689Skan      /* Else fall through to report error.  */
5772169689Skan    default:
5773169689Skan      c_parser_error (parser, "expected expression");
5774169689Skan      expr.value = error_mark_node;
5775169689Skan      expr.original_code = ERROR_MARK;
5776169689Skan      break;
5777169689Skan    }
5778169689Skan  return c_parser_postfix_expression_after_primary (parser, expr);
5779169689Skan}
5780169689Skan
5781169689Skan/* Parse a postfix expression after a parenthesized type name: the
5782169689Skan   brace-enclosed initializer of a compound literal, possibly followed
5783169689Skan   by some postfix operators.  This is separate because it is not
5784169689Skan   possible to tell until after the type name whether a cast
5785169689Skan   expression has a cast or a compound literal, or whether the operand
5786169689Skan   of sizeof is a parenthesized type name or starts with a compound
5787169689Skan   literal.  */
5788169689Skan
5789169689Skanstatic struct c_expr
5790169689Skanc_parser_postfix_expression_after_paren_type (c_parser *parser,
5791169689Skan					      struct c_type_name *type_name)
5792169689Skan{
5793169689Skan  tree type;
5794169689Skan  struct c_expr init;
5795169689Skan  struct c_expr expr;
5796169689Skan  start_init (NULL_TREE, NULL, 0);
5797169689Skan  type = groktypename (type_name);
5798169689Skan  if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
5799169689Skan    {
5800169689Skan      error ("compound literal has variable size");
5801169689Skan      type = error_mark_node;
5802169689Skan    }
5803169689Skan  init = c_parser_braced_init (parser, type, false);
5804169689Skan  finish_init ();
5805169689Skan  maybe_warn_string_init (type, init);
5806169689Skan
5807169689Skan  if (pedantic && !flag_isoc99)
5808169689Skan    pedwarn ("ISO C90 forbids compound literals");
5809169689Skan  expr.value = build_compound_literal (type, init.value);
5810169689Skan  expr.original_code = ERROR_MARK;
5811169689Skan  return c_parser_postfix_expression_after_primary (parser, expr);
5812169689Skan}
5813169689Skan
5814169689Skan/* Parse a postfix expression after the initial primary or compound
5815169689Skan   literal; that is, parse a series of postfix operators.  */
5816169689Skan
5817169689Skanstatic struct c_expr
5818169689Skanc_parser_postfix_expression_after_primary (c_parser *parser,
5819169689Skan					   struct c_expr expr)
5820169689Skan{
5821169689Skan  tree ident, idx, exprlist;
5822169689Skan  while (true)
5823169689Skan    {
5824169689Skan      switch (c_parser_peek_token (parser)->type)
5825169689Skan	{
5826169689Skan	case CPP_OPEN_SQUARE:
5827169689Skan	  /* Array reference.  */
5828169689Skan	  c_parser_consume_token (parser);
5829169689Skan	  idx = c_parser_expression (parser).value;
5830169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5831169689Skan				     "expected %<]%>");
5832169689Skan	  expr.value = build_array_ref (expr.value, idx);
5833169689Skan	  expr.original_code = ERROR_MARK;
5834169689Skan	  break;
5835169689Skan	case CPP_OPEN_PAREN:
5836169689Skan	  /* Function call.  */
5837169689Skan	  c_parser_consume_token (parser);
5838169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5839169689Skan	    exprlist = NULL_TREE;
5840169689Skan	  else
5841169689Skan	    exprlist = c_parser_expr_list (parser, true);
5842169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
5843169689Skan				     "expected %<)%>");
5844169689Skan	  expr.value = build_function_call (expr.value, exprlist);
5845169689Skan	  expr.original_code = ERROR_MARK;
5846169689Skan	  break;
5847169689Skan	case CPP_DOT:
5848169689Skan	  /* Structure element reference.  */
5849169689Skan	  c_parser_consume_token (parser);
5850169689Skan	  expr = default_function_array_conversion (expr);
5851169689Skan	  if (c_parser_next_token_is (parser, CPP_NAME))
5852169689Skan	    ident = c_parser_peek_token (parser)->value;
5853169689Skan	  else
5854169689Skan	    {
5855169689Skan	      c_parser_error (parser, "expected identifier");
5856169689Skan	      expr.value = error_mark_node;
5857169689Skan	      expr.original_code = ERROR_MARK;
5858169689Skan	      return expr;
5859169689Skan	    }
5860169689Skan	  c_parser_consume_token (parser);
5861169689Skan	  expr.value = build_component_ref (expr.value, ident);
5862169689Skan	  expr.original_code = ERROR_MARK;
5863169689Skan	  break;
5864169689Skan	case CPP_DEREF:
5865169689Skan	  /* Structure element reference.  */
5866169689Skan	  c_parser_consume_token (parser);
5867169689Skan	  expr = default_function_array_conversion (expr);
5868169689Skan	  if (c_parser_next_token_is (parser, CPP_NAME))
5869169689Skan	    ident = c_parser_peek_token (parser)->value;
5870169689Skan	  else
5871169689Skan	    {
5872169689Skan	      c_parser_error (parser, "expected identifier");
5873169689Skan	      expr.value = error_mark_node;
5874169689Skan	      expr.original_code = ERROR_MARK;
5875169689Skan	      return expr;
5876169689Skan	    }
5877169689Skan	  c_parser_consume_token (parser);
5878169689Skan	  expr.value = build_component_ref (build_indirect_ref (expr.value,
5879169689Skan								"->"), ident);
5880169689Skan	  expr.original_code = ERROR_MARK;
5881169689Skan	  break;
5882169689Skan	case CPP_PLUS_PLUS:
5883169689Skan	  /* Postincrement.  */
5884169689Skan	  c_parser_consume_token (parser);
5885169689Skan	  expr = default_function_array_conversion (expr);
5886169689Skan	  expr.value = build_unary_op (POSTINCREMENT_EXPR, expr.value, 0);
5887169689Skan	  expr.original_code = ERROR_MARK;
5888169689Skan	  break;
5889169689Skan	case CPP_MINUS_MINUS:
5890169689Skan	  /* Postdecrement.  */
5891169689Skan	  c_parser_consume_token (parser);
5892169689Skan	  expr = default_function_array_conversion (expr);
5893169689Skan	  expr.value = build_unary_op (POSTDECREMENT_EXPR, expr.value, 0);
5894169689Skan	  expr.original_code = ERROR_MARK;
5895169689Skan	  break;
5896169689Skan	default:
5897169689Skan	  return expr;
5898169689Skan	}
5899169689Skan    }
5900169689Skan}
5901169689Skan
5902169689Skan/* Parse an expression (C90 6.3.17, C99 6.5.17).
5903169689Skan
5904169689Skan   expression:
5905169689Skan     assignment-expression
5906169689Skan     expression , assignment-expression
5907169689Skan*/
5908169689Skan
5909169689Skanstatic struct c_expr
5910169689Skanc_parser_expression (c_parser *parser)
5911169689Skan{
5912169689Skan  struct c_expr expr;
5913169689Skan  expr = c_parser_expr_no_commas (parser, NULL);
5914169689Skan  while (c_parser_next_token_is (parser, CPP_COMMA))
5915169689Skan    {
5916169689Skan      struct c_expr next;
5917169689Skan      c_parser_consume_token (parser);
5918169689Skan      next = c_parser_expr_no_commas (parser, NULL);
5919169689Skan      next = default_function_array_conversion (next);
5920169689Skan      expr.value = build_compound_expr (expr.value, next.value);
5921169689Skan      expr.original_code = COMPOUND_EXPR;
5922169689Skan    }
5923169689Skan  return expr;
5924169689Skan}
5925169689Skan
5926169689Skan/* Parse an expression and convert functions or arrays to
5927169689Skan   pointers.  */
5928169689Skan
5929169689Skanstatic struct c_expr
5930169689Skanc_parser_expression_conv (c_parser *parser)
5931169689Skan{
5932169689Skan  struct c_expr expr;
5933169689Skan  expr = c_parser_expression (parser);
5934169689Skan  expr = default_function_array_conversion (expr);
5935169689Skan  return expr;
5936169689Skan}
5937169689Skan
5938169689Skan/* Parse a non-empty list of expressions.  If CONVERT_P, convert
5939169689Skan   functions and arrays to pointers.
5940169689Skan
5941169689Skan   nonempty-expr-list:
5942169689Skan     assignment-expression
5943169689Skan     nonempty-expr-list , assignment-expression
5944169689Skan*/
5945169689Skan
5946169689Skanstatic tree
5947169689Skanc_parser_expr_list (c_parser *parser, bool convert_p)
5948169689Skan{
5949169689Skan  struct c_expr expr;
5950169689Skan  tree ret, cur;
5951169689Skan  expr = c_parser_expr_no_commas (parser, NULL);
5952169689Skan  if (convert_p)
5953169689Skan    expr = default_function_array_conversion (expr);
5954169689Skan  ret = cur = build_tree_list (NULL_TREE, expr.value);
5955169689Skan  while (c_parser_next_token_is (parser, CPP_COMMA))
5956169689Skan    {
5957169689Skan      c_parser_consume_token (parser);
5958169689Skan      expr = c_parser_expr_no_commas (parser, NULL);
5959169689Skan      if (convert_p)
5960169689Skan	expr = default_function_array_conversion (expr);
5961169689Skan      cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value);
5962169689Skan    }
5963169689Skan  return ret;
5964169689Skan}
5965169689Skan
5966169689Skan
5967169689Skan/* Parse Objective-C-specific constructs.  */
5968169689Skan
5969169689Skan/* Parse an objc-class-definition.
5970169689Skan
5971169689Skan   objc-class-definition:
5972169689Skan     @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
5973169689Skan       objc-class-instance-variables[opt] objc-methodprotolist @end
5974169689Skan     @implementation identifier objc-superclass[opt]
5975169689Skan       objc-class-instance-variables[opt]
5976169689Skan     @interface identifier ( identifier ) objc-protocol-refs[opt]
5977169689Skan       objc-methodprotolist @end
5978169689Skan     @implementation identifier ( identifier )
5979169689Skan
5980169689Skan   objc-superclass:
5981169689Skan     : identifier
5982169689Skan
5983169689Skan   "@interface identifier (" must start "@interface identifier (
5984169689Skan   identifier ) ...": objc-methodprotolist in the first production may
5985169689Skan   not start with a parenthesized identifier as a declarator of a data
5986169689Skan   definition with no declaration specifiers if the objc-superclass,
5987169689Skan   objc-protocol-refs and objc-class-instance-variables are omitted.  */
5988169689Skan
5989169689Skanstatic void
5990261188Spfg/* APPLE LOCAL radar 4548636 - class attributes. */
5991261188Spfgc_parser_objc_class_definition (c_parser *parser, tree prefix_attrs)
5992169689Skan{
5993169689Skan  bool iface_p;
5994169689Skan  tree id1;
5995169689Skan  tree superclass;
5996169689Skan  if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
5997169689Skan    iface_p = true;
5998169689Skan  else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
5999261188Spfg    /* APPLE LOCAL begin radar 4548636 - class attributes. */
6000261188Spfg    {
6001261188Spfg      if (prefix_attrs)
6002261188Spfg	{
6003261188Spfg	  error ("attributes may not be specified on an implementation");
6004261188Spfg	  prefix_attrs = NULL_TREE;
6005261188Spfg	}
6006261188Spfg      iface_p = false;
6007261188Spfg    }
6008261188Spfg    /* APPLE LOCAL end radar 4548636 - class attributes. */
6009169689Skan  else
6010169689Skan    gcc_unreachable ();
6011169689Skan  c_parser_consume_token (parser);
6012169689Skan  if (c_parser_next_token_is_not (parser, CPP_NAME))
6013169689Skan    {
6014261188Spfg      /* APPLE LOCAL radar 4965989 */
6015261188Spfg      tree id2 = NULL_TREE;
6016169689Skan      tree proto = NULL_TREE;
6017169689Skan      c_parser_consume_token (parser);
6018261188Spfg      /* APPLE LOCAL begin radar 4965989 */
6019261188Spfg      if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
6020169689Skan	{
6021261188Spfg	   if (c_parser_next_token_is_not (parser, CPP_NAME))
6022261188Spfg	    {
6023261188Spfg	      c_parser_error (parser, "expected identifier");
6024261188Spfg	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6025261188Spfg	      return;
6026261188Spfg	    }
6027261188Spfg	   id2 = c_parser_peek_token (parser)->value;
6028261188Spfg	   c_parser_consume_token (parser);
6029169689Skan	}
6030261188Spfg      /* APPLE LOCAL end radar 4965989 */
6031169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
6032169689Skan      if (!iface_p)
6033169689Skan	{
6034261188Spfg	   /* APPLE LOCAL begin radar 4965989 */
6035261188Spfg	  if (id2 == NULL_TREE)
6036261188Spfg	    {
6037261188Spfg	      error ("cannot implement anonymous category");
6038261188Spfg	      return;
6039261188Spfg	    }
6040261188Spfg	   /* APPLE LOCAL end radar 4965989 */
6041169689Skan	  objc_start_category_implementation (id1, id2);
6042169689Skan	  return;
6043169689Skan	}
6044169689Skan      if (c_parser_next_token_is (parser, CPP_LESS))
6045169689Skan	proto = c_parser_objc_protocol_refs (parser);
6046261188Spfg      /* APPLE LOCAL begin radar 4548636 - class attributes. */
6047261188Spfg      if (prefix_attrs)
6048261188Spfg	error ("attributes may not be specified on a category");
6049261188Spfg      /* APPLE LOCAL end radar 4548636 - class attributes. */
6050169689Skan      objc_start_category_interface (id1, id2, proto);
6051261188Spfg      /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 q) */
6052261188Spfg      c_parser_objc_interfacedecllist (parser);
6053169689Skan      c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
6054169689Skan      objc_finish_interface ();
6055169689Skan      return;
6056169689Skan    }
6057169689Skan  if (c_parser_next_token_is (parser, CPP_COLON))
6058169689Skan    {
6059169689Skan      c_parser_consume_token (parser);
6060169689Skan      if (c_parser_next_token_is_not (parser, CPP_NAME))
6061169689Skan	{
6062169689Skan	  c_parser_error (parser, "expected identifier");
6063169689Skan	  return;
6064169689Skan	}
6065169689Skan      superclass = c_parser_peek_token (parser)->value;
6066169689Skan      c_parser_consume_token (parser);
6067169689Skan    }
6068169689Skan  else
6069169689Skan    superclass = NULL_TREE;
6070169689Skan  if (iface_p)
6071169689Skan    {
6072169689Skan      tree proto = NULL_TREE;
6073169689Skan      if (c_parser_next_token_is (parser, CPP_LESS))
6074169689Skan	proto = c_parser_objc_protocol_refs (parser);
6075261188Spfg      /* APPLE LOCAL radar 4548636 - class attributes. */
6076261188Spfg      objc_start_class_interface (id1, superclass, proto, prefix_attrs);
6077169689Skan    }
6078169689Skan  else
6079169689Skan    objc_start_class_implementation (id1, superclass);
6080169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6081169689Skan    c_parser_objc_class_instance_variables (parser);
6082169689Skan  if (iface_p)
6083169689Skan    {
6084169689Skan      objc_continue_interface ();
6085261188Spfg      /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 q) */
6086261188Spfg      c_parser_objc_interfacedecllist (parser);
6087169689Skan      c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
6088169689Skan      objc_finish_interface ();
6089169689Skan    }
6090169689Skan  else
6091169689Skan    {
6092169689Skan      objc_continue_implementation ();
6093169689Skan      return;
6094169689Skan    }
6095169689Skan}
6096169689Skan
6097261188Spfg/* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 s) */
6098261188Spfgstatic tree
6099261188Spfgc_parser_objc_eq_identifier (c_parser *parser)
6100261188Spfg{
6101261188Spfg  tree id;
6102261188Spfg  if (c_parser_next_token_is_not (parser, CPP_EQ))
6103261188Spfg    {
6104261188Spfg      c_parser_error (parser, "expected %<=%>");
6105261188Spfg      return NULL_TREE;
6106261188Spfg    }
6107261188Spfg  /* Consume '=' */
6108261188Spfg  c_parser_consume_token (parser);
6109261188Spfg  if (c_parser_next_token_is_not (parser, CPP_NAME))
6110261188Spfg    {
6111261188Spfg      c_parser_error (parser, "expected identifier");
6112261188Spfg      return NULL_TREE;
6113261188Spfg    }
6114261188Spfg  id = c_parser_peek_token (parser)->value;
6115261188Spfg  c_parser_consume_token (parser);
6116261188Spfg  return id;
6117261188Spfg}
6118261188Spfg
6119261188Spfg/* Parse obj-property-attribute.
6120261188Spfg*/
6121261188Spfgstatic void
6122261188Spfgc_parser_objc_property_attribute (c_parser *parser)
6123261188Spfg{
6124261188Spfg  tree id;
6125261188Spfg  if (c_parser_peek_token (parser)->type != CPP_KEYWORD)
6126261188Spfg    {
6127261188Spfg      c_parser_error (parser, "expected a property attribute");
6128261188Spfg      c_parser_consume_token (parser);
6129261188Spfg      return;
6130261188Spfg    }
6131261188Spfg  switch (c_parser_peek_token (parser)->keyword)
6132261188Spfg    {
6133261188Spfg    case RID_READONLY:
6134261188Spfg      c_parser_consume_token (parser);
6135261188Spfg      objc_set_property_attr (1, NULL_TREE);
6136261188Spfg      break;
6137261188Spfg    case RID_GETTER:
6138261188Spfg      c_parser_consume_token (parser);
6139261188Spfg      id = c_parser_objc_eq_identifier (parser);
6140261188Spfg      if (id)
6141261188Spfg	objc_set_property_attr (2, id);
6142261188Spfg      break;
6143261188Spfg    case RID_SETTER:
6144261188Spfg      c_parser_consume_token (parser);
6145261188Spfg      id = c_parser_objc_eq_identifier (parser);
6146261188Spfg      if (id)
6147261188Spfg	objc_set_property_attr (3, id);
6148261188Spfg      /* Consume the ':' which must always follow the setter name. */
6149261188Spfg      if (c_parser_next_token_is (parser, CPP_COLON))
6150261188Spfg	c_parser_consume_token (parser);
6151261188Spfg      break;
6152261188Spfg   /* APPLE LOCAL begin radar 4947014 - objc atomic property */
6153261188Spfg    case RID_NONATOMIC:
6154261188Spfg      c_parser_consume_token (parser);
6155261188Spfg      objc_set_property_attr (13, NULL_TREE);
6156261188Spfg      break;
6157261188Spfg    /* APPLE LOCAL end radar 4947014 - objc atomic property */
6158261188Spfg    default:
6159261188Spfg      c_parser_error (parser, "expected a property attribute");
6160261188Spfg      c_parser_consume_token (parser);
6161261188Spfg    }
6162261188Spfg}
6163261188Spfg
6164261188Spfgstatic void
6165261188Spfgc_parser_objc_property_attrlist (c_parser *parser)
6166261188Spfg{
6167261188Spfg  while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)
6168261188Spfg	 && c_parser_next_token_is_not (parser, CPP_EOF))
6169261188Spfg    {
6170261188Spfg      c_parser_objc_property_attribute (parser);
6171261188Spfg      /* APPLE LOCAL begin radar 6302949 */
6172261188Spfg      if (c_parser_next_token_is_not (parser, CPP_COMMA)
6173261188Spfg	  && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)
6174261188Spfg	  && c_parser_next_token_is_not (parser, CPP_EOF))
6175261188Spfg	warning (0, "property attributes must be separated by a comma");
6176261188Spfg      /* APPLE LOCAL end radar 6302949 */
6177261188Spfg      if (c_parser_next_token_is (parser, CPP_COMMA)
6178261188Spfg	  || c_parser_next_token_is (parser, CPP_NAME) /* error */)
6179261188Spfg	c_parser_consume_token (parser);
6180261188Spfg    }
6181261188Spfg}
6182261188Spfg
6183261188Spfgstatic void
6184261188Spfgc_parser_objc_property_attr_decl (c_parser *parser)
6185261188Spfg{
6186261188Spfg  if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
6187261188Spfg    return;
6188261188Spfg  c_parser_consume_token (parser);
6189261188Spfg  c_parser_objc_property_attrlist (parser);
6190261188Spfg  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
6191261188Spfg}
6192261188Spfg
6193261188Spfgstatic tree
6194261188Spfgc_parser_component_decl (c_parser *parser)
6195261188Spfg{
6196261188Spfg  tree decl = c_parser_struct_declaration (parser);
6197261188Spfg  return decl;
6198261188Spfg}
6199261188Spfg
6200261188Spfgstatic void
6201261188Spfgc_parser_objc_property_declaration (c_parser *parser)
6202261188Spfg{
6203261188Spfg  tree prop;
6204261188Spfg  c_parser_require_keyword (parser, RID_AT_PROPERTY, "expected %<@property%>");
6205261188Spfg  objc_property_attr_context = 1;
6206261188Spfg  objc_set_property_attr (0, NULL_TREE);
6207261188Spfg  c_parser_objc_property_attr_decl (parser);
6208261188Spfg  objc_property_attr_context = 0;
6209261188Spfg  prop = c_parser_component_decl (parser);
6210261188Spfg  /* Comma-separated properties are chained together in
6211261188Spfg     reverse order; add them one by one.  */
6212261188Spfg  prop = nreverse (prop);
6213261188Spfg
6214261188Spfg  for (; prop; prop = TREE_CHAIN (prop))
6215261188Spfg    objc_add_property_variable (copy_node (prop));
6216261188Spfg  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6217261188Spfg}
6218261188Spfg/* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 s) */
6219261188Spfg
6220169689Skan/* Parse objc-class-instance-variables.
6221169689Skan
6222169689Skan   objc-class-instance-variables:
6223169689Skan     { objc-instance-variable-decl-list[opt] }
6224169689Skan
6225169689Skan   objc-instance-variable-decl-list:
6226169689Skan     objc-visibility-spec
6227169689Skan     objc-instance-variable-decl ;
6228169689Skan     ;
6229169689Skan     objc-instance-variable-decl-list objc-visibility-spec
6230169689Skan     objc-instance-variable-decl-list objc-instance-variable-decl ;
6231169689Skan     objc-instance-variable-decl-list ;
6232169689Skan
6233169689Skan   objc-visibility-spec:
6234169689Skan     @private
6235169689Skan     @protected
6236169689Skan     @public
6237169689Skan
6238169689Skan   objc-instance-variable-decl:
6239169689Skan     struct-declaration
6240169689Skan*/
6241169689Skan
6242169689Skanstatic void
6243169689Skanc_parser_objc_class_instance_variables (c_parser *parser)
6244169689Skan{
6245169689Skan  gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
6246169689Skan  c_parser_consume_token (parser);
6247169689Skan  while (c_parser_next_token_is_not (parser, CPP_EOF))
6248169689Skan    {
6249169689Skan      tree decls;
6250169689Skan      /* Parse any stray semicolon.  */
6251169689Skan      if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6252169689Skan	{
6253169689Skan	  if (pedantic)
6254169689Skan	    pedwarn ("extra semicolon in struct or union specified");
6255169689Skan	  c_parser_consume_token (parser);
6256169689Skan	  continue;
6257169689Skan	}
6258169689Skan      /* Stop if at the end of the instance variables.  */
6259169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
6260169689Skan	{
6261169689Skan	  c_parser_consume_token (parser);
6262169689Skan	  break;
6263169689Skan	}
6264169689Skan      /* Parse any objc-visibility-spec.  */
6265169689Skan      if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
6266169689Skan	{
6267169689Skan	  c_parser_consume_token (parser);
6268169689Skan	  objc_set_visibility (2);
6269169689Skan	  continue;
6270169689Skan	}
6271169689Skan      else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
6272169689Skan	{
6273169689Skan	  c_parser_consume_token (parser);
6274169689Skan	  objc_set_visibility (0);
6275169689Skan	  continue;
6276169689Skan	}
6277169689Skan      else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
6278169689Skan	{
6279169689Skan	  c_parser_consume_token (parser);
6280169689Skan	  objc_set_visibility (1);
6281169689Skan	  continue;
6282169689Skan	}
6283261188Spfg      /* APPLE LOCAL begin radar 4564694 */
6284261188Spfg      else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
6285261188Spfg	{
6286261188Spfg	  c_parser_consume_token (parser);
6287261188Spfg	  objc_set_visibility (3);
6288261188Spfg	  continue;
6289261188Spfg	}
6290261188Spfg      /* APPLE LOCAL end radar 4564694 */
6291169689Skan      else if (c_parser_next_token_is (parser, CPP_PRAGMA))
6292169689Skan	{
6293169689Skan	  c_parser_pragma (parser, pragma_external);
6294169689Skan	  continue;
6295169689Skan	}
6296169689Skan
6297169689Skan      /* Parse some comma-separated declarations.  */
6298169689Skan      decls = c_parser_struct_declaration (parser);
6299169689Skan      {
6300169689Skan	/* Comma-separated instance variables are chained together in
6301169689Skan	   reverse order; add them one by one.  */
6302169689Skan	tree ivar = nreverse (decls);
6303169689Skan	for (; ivar; ivar = TREE_CHAIN (ivar))
6304169689Skan	  objc_add_instance_variable (copy_node (ivar));
6305169689Skan      }
6306169689Skan      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6307169689Skan    }
6308169689Skan}
6309169689Skan
6310169689Skan/* Parse an objc-class-declaration.
6311169689Skan
6312169689Skan   objc-class-declaration:
6313169689Skan     @class identifier-list ;
6314169689Skan*/
6315169689Skan
6316169689Skanstatic void
6317169689Skanc_parser_objc_class_declaration (c_parser *parser)
6318169689Skan{
6319169689Skan  tree list = NULL_TREE;
6320169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
6321169689Skan  c_parser_consume_token (parser);
6322169689Skan  /* Any identifiers, including those declared as type names, are OK
6323169689Skan     here.  */
6324169689Skan  while (true)
6325169689Skan    {
6326169689Skan      tree id;
6327169689Skan      if (c_parser_next_token_is_not (parser, CPP_NAME))
6328169689Skan	{
6329169689Skan	  c_parser_error (parser, "expected identifier");
6330169689Skan	  break;
6331169689Skan	}
6332169689Skan      id = c_parser_peek_token (parser)->value;
6333169689Skan      list = chainon (list, build_tree_list (NULL_TREE, id));
6334169689Skan      c_parser_consume_token (parser);
6335169689Skan      if (c_parser_next_token_is (parser, CPP_COMMA))
6336169689Skan	c_parser_consume_token (parser);
6337169689Skan      else
6338169689Skan	break;
6339169689Skan    }
6340169689Skan  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6341169689Skan  objc_declare_class (list);
6342169689Skan}
6343169689Skan
6344169689Skan/* Parse an objc-alias-declaration.
6345169689Skan
6346169689Skan   objc-alias-declaration:
6347169689Skan     @compatibility_alias identifier identifier ;
6348169689Skan*/
6349169689Skan
6350169689Skanstatic void
6351169689Skanc_parser_objc_alias_declaration (c_parser *parser)
6352169689Skan{
6353169689Skan  tree id1, id2;
6354169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
6355169689Skan  c_parser_consume_token (parser);
6356169689Skan  if (c_parser_next_token_is_not (parser, CPP_NAME))
6357169689Skan    {
6358169689Skan      c_parser_error (parser, "expected identifier");
6359169689Skan      c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
6360169689Skan      return;
6361169689Skan    }
6362169689Skan  id1 = c_parser_peek_token (parser)->value;
6363169689Skan  c_parser_consume_token (parser);
6364169689Skan  if (c_parser_next_token_is_not (parser, CPP_NAME))
6365169689Skan    {
6366169689Skan      c_parser_error (parser, "expected identifier");
6367169689Skan      c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
6368169689Skan      return;
6369169689Skan    }
6370169689Skan  id2 = c_parser_peek_token (parser)->value;
6371169689Skan  c_parser_consume_token (parser);
6372169689Skan  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6373169689Skan  objc_declare_alias (id1, id2);
6374169689Skan}
6375169689Skan
6376169689Skan/* Parse an objc-protocol-definition.
6377169689Skan
6378169689Skan   objc-protocol-definition:
6379169689Skan     @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
6380169689Skan     @protocol identifier-list ;
6381169689Skan
6382169689Skan   "@protocol identifier ;" should be resolved as "@protocol
6383169689Skan   identifier-list ;": objc-methodprotolist may not start with a
6384169689Skan   semicolon in the first alternative if objc-protocol-refs are
6385169689Skan   omitted.  */
6386169689Skan
6387169689Skanstatic void
6388261188Spfg/* APPLE LOCAL radar 4947311 - protocol attributes */
6389261188Spfgc_parser_objc_protocol_definition (c_parser *parser, tree attributes)
6390169689Skan{
6391169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
6392169689Skan  c_parser_consume_token (parser);
6393169689Skan  if (c_parser_next_token_is_not (parser, CPP_NAME))
6394169689Skan    {
6395169689Skan      c_parser_error (parser, "expected identifier");
6396169689Skan      return;
6397169689Skan    }
6398169689Skan  if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
6399169689Skan      || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
6400169689Skan    {
6401169689Skan      tree list = NULL_TREE;
6402169689Skan      /* Any identifiers, including those declared as type names, are
6403169689Skan	 OK here.  */
6404169689Skan      while (true)
6405169689Skan	{
6406169689Skan	  tree id;
6407169689Skan	  if (c_parser_next_token_is_not (parser, CPP_NAME))
6408169689Skan	    {
6409169689Skan	      c_parser_error (parser, "expected identifier");
6410169689Skan	      break;
6411169689Skan	    }
6412169689Skan	  id = c_parser_peek_token (parser)->value;
6413169689Skan	  list = chainon (list, build_tree_list (NULL_TREE, id));
6414169689Skan	  c_parser_consume_token (parser);
6415169689Skan	  if (c_parser_next_token_is (parser, CPP_COMMA))
6416169689Skan	    c_parser_consume_token (parser);
6417169689Skan	  else
6418169689Skan	    break;
6419169689Skan	}
6420169689Skan      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6421261188Spfg      /* APPLE LOCAL radar 4947311 - protocol attributes */
6422261188Spfg      objc_declare_protocols (list, attributes);
6423169689Skan    }
6424169689Skan  else
6425169689Skan    {
6426169689Skan      tree id = c_parser_peek_token (parser)->value;
6427169689Skan      tree proto = NULL_TREE;
6428169689Skan      c_parser_consume_token (parser);
6429169689Skan      if (c_parser_next_token_is (parser, CPP_LESS))
6430169689Skan	proto = c_parser_objc_protocol_refs (parser);
6431169689Skan      objc_pq_context = 1;
6432261188Spfg      /* APPLE LOCAL radar 4947311 - protocol attributes */
6433261188Spfg      objc_start_protocol (id, proto, attributes);
6434261188Spfg      /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 r) */
6435261188Spfg      c_parser_objc_interfacedecllist (parser);
6436169689Skan      c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
6437169689Skan      objc_pq_context = 0;
6438169689Skan      objc_finish_interface ();
6439169689Skan    }
6440169689Skan}
6441169689Skan
6442169689Skan/* Parse an objc-method-type.
6443169689Skan
6444169689Skan   objc-method-type:
6445169689Skan     +
6446169689Skan     -
6447169689Skan*/
6448169689Skan
6449169689Skanstatic enum tree_code
6450169689Skanc_parser_objc_method_type (c_parser *parser)
6451169689Skan{
6452169689Skan  switch (c_parser_peek_token (parser)->type)
6453169689Skan    {
6454169689Skan    case CPP_PLUS:
6455169689Skan      c_parser_consume_token (parser);
6456169689Skan      return PLUS_EXPR;
6457169689Skan    case CPP_MINUS:
6458169689Skan      c_parser_consume_token (parser);
6459169689Skan      return MINUS_EXPR;
6460169689Skan    default:
6461169689Skan      gcc_unreachable ();
6462169689Skan    }
6463169689Skan}
6464169689Skan
6465169689Skan/* Parse an objc-method-definition.
6466169689Skan
6467169689Skan   objc-method-definition:
6468169689Skan     objc-method-type objc-method-decl ;[opt] compound-statement
6469169689Skan*/
6470169689Skan
6471169689Skanstatic void
6472169689Skanc_parser_objc_method_definition (c_parser *parser)
6473169689Skan{
6474169689Skan  enum tree_code type = c_parser_objc_method_type (parser);
6475169689Skan  tree decl;
6476169689Skan  objc_set_method_type (type);
6477169689Skan  objc_pq_context = 1;
6478169689Skan  decl = c_parser_objc_method_decl (parser);
6479169689Skan  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6480169689Skan    {
6481169689Skan      c_parser_consume_token (parser);
6482169689Skan      if (pedantic)
6483169689Skan	pedwarn ("extra semicolon in method definition specified");
6484169689Skan    }
6485169689Skan  if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6486169689Skan    {
6487169689Skan      c_parser_error (parser, "expected %<{%>");
6488169689Skan      return;
6489169689Skan    }
6490169689Skan  objc_pq_context = 0;
6491261188Spfg  /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 a) */
6492261188Spfg  objc_start_method_definition (decl, objc_method_attributes);
6493261188Spfg  objc_method_attributes = NULL_TREE;
6494261188Spfg  /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 a) */
6495169689Skan  add_stmt (c_parser_compound_statement (parser));
6496169689Skan  objc_finish_method_definition (current_function_decl);
6497169689Skan}
6498169689Skan
6499261188Spfg/* APPLE LOCAL begin C* language (in 4.2 w) */
6500261188Spfg/* True iff the gioven TOKEN starts a methodproto.  */
6501261188Spfg
6502261188Spfgstatic bool
6503261188Spfgc_token_starts_methodproto (c_token *token)
6504261188Spfg{
6505261188Spfg  return token->type == CPP_PLUS
6506261188Spfg    || token->type == CPP_MINUS
6507261188Spfg    || (token->type == CPP_KEYWORD
6508261188Spfg	&& (token->keyword == RID_AT_REQUIRED
6509261188Spfg	    || token->keyword == RID_AT_OPTIONAL));
6510261188Spfg}
6511261188Spfg/* APPLE LOCAL end C* language (in 4.2 w) */
6512261188Spfg
6513169689Skan/* Parse an objc-methodprotolist.
6514169689Skan
6515169689Skan   objc-methodprotolist:
6516169689Skan     empty
6517169689Skan     objc-methodprotolist objc-methodproto
6518169689Skan     objc-methodprotolist declaration
6519169689Skan     objc-methodprotolist ;
6520169689Skan
6521169689Skan   The declaration is a data definition, which may be missing
6522169689Skan   declaration specifiers under the same rules and diagnostics as
6523169689Skan   other data definitions outside functions, and the stray semicolon
6524169689Skan   is diagnosed the same way as a stray semicolon outside a
6525169689Skan   function.  */
6526169689Skan
6527169689Skanstatic void
6528261188Spfg/* APPLE LOCAL C* property (Radar 4436866) (in 4.2 b) */
6529261188Spfgc_parser_objc_interfacedecllist (c_parser *parser)
6530169689Skan{
6531169689Skan  while (true)
6532169689Skan    {
6533261188Spfg      /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 b) */
6534261188Spfg      c_token *token;
6535261188Spfg      token = c_parser_peek_token (parser);
6536261188Spfg      if (token->type == CPP_KEYWORD
6537261188Spfg	  && token->keyword == RID_AT_PROPERTY)
6538261188Spfg	{
6539261188Spfg	  c_parser_objc_property_declaration (parser);
6540261188Spfg	  continue;
6541261188Spfg	}
6542261188Spfg      /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 b) */
6543261188Spfg      /* APPLE LOCAL begin C* language (in 4.2 w) */
6544261188Spfg      if (c_token_starts_methodproto (token))
6545261188Spfg	{
6546261188Spfg	  c_parser_objc_methodproto (parser);
6547261188Spfg	  continue;
6548261188Spfg	}
6549261188Spfg      /* APPLE LOCAL end C* language (in 4.2 w) */
6550261188Spfg
6551169689Skan      /* The list is terminated by @end.  */
6552169689Skan      switch (c_parser_peek_token (parser)->type)
6553169689Skan	{
6554169689Skan	case CPP_SEMICOLON:
6555169689Skan	  if (pedantic)
6556169689Skan	    pedwarn ("ISO C does not allow extra %<;%> outside of a function");
6557169689Skan	  c_parser_consume_token (parser);
6558169689Skan	  break;
6559261188Spfg      /* APPLE LOCAL begin C* language (in 4.2 w) */
6560261188Spfg	  /* CPP_PLUS and CPP_MINUS deleted */
6561261188Spfg      /* APPLE LOCAL end C* language (in 4.2 w) */
6562169689Skan	case CPP_PRAGMA:
6563169689Skan	  c_parser_pragma (parser, pragma_external);
6564169689Skan	  break;
6565169689Skan	case CPP_EOF:
6566169689Skan	  return;
6567169689Skan	default:
6568169689Skan	  if (c_parser_next_token_is_keyword (parser, RID_AT_END))
6569169689Skan	    return;
6570261188Spfg	  /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
6571261188Spfg	  c_parser_declaration_or_fndef (parser, false, true, false, true, NULL);
6572169689Skan	  break;
6573169689Skan	}
6574169689Skan    }
6575169689Skan}
6576169689Skan
6577169689Skan/* Parse an objc-methodproto.
6578169689Skan
6579169689Skan   objc-methodproto:
6580169689Skan     objc-method-type objc-method-decl ;
6581169689Skan*/
6582169689Skan
6583169689Skanstatic void
6584169689Skanc_parser_objc_methodproto (c_parser *parser)
6585169689Skan{
6586261188Spfg  /* APPLE LOCAL C* language */
6587261188Spfg  enum tree_code type;
6588169689Skan  tree decl;
6589261188Spfg  /* APPLE LOCAL begin C* language */
6590261188Spfg  if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
6591261188Spfg    {
6592261188Spfg      objc_set_method_opt (0);
6593261188Spfg      c_parser_consume_token (parser);
6594261188Spfg      return;
6595261188Spfg    }
6596261188Spfg  if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
6597261188Spfg    {
6598261188Spfg      objc_set_method_opt (1);
6599261188Spfg      c_parser_consume_token (parser);
6600261188Spfg      return;
6601261188Spfg    }
6602261188Spfg  /* APPLE LOCAL begin C* language */
6603261188Spfg  /* APPLE LOCAL C* language */
6604261188Spfg  type = c_parser_objc_method_type (parser);
6605169689Skan  objc_set_method_type (type);
6606169689Skan  /* Remember protocol qualifiers in prototypes.  */
6607169689Skan  objc_pq_context = 1;
6608169689Skan  decl = c_parser_objc_method_decl (parser);
6609169689Skan  /* Forget protocol qualifiers here.  */
6610169689Skan  objc_pq_context = 0;
6611261188Spfg  /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 c) */
6612261188Spfg  objc_add_method_declaration (decl, objc_method_attributes);
6613261188Spfg  objc_method_attributes = NULL_TREE;
6614261188Spfg  /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 c) */
6615169689Skan  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6616169689Skan}
6617169689Skan
6618169689Skan/* Parse an objc-method-decl.
6619169689Skan
6620169689Skan   objc-method-decl:
6621169689Skan     ( objc-type-name ) objc-selector
6622169689Skan     objc-selector
6623169689Skan     ( objc-type-name ) objc-keyword-selector objc-optparmlist
6624169689Skan     objc-keyword-selector objc-optparmlist
6625169689Skan
6626169689Skan   objc-keyword-selector:
6627169689Skan     objc-keyword-decl
6628169689Skan     objc-keyword-selector objc-keyword-decl
6629169689Skan
6630169689Skan   objc-keyword-decl:
6631169689Skan     objc-selector : ( objc-type-name ) identifier
6632169689Skan     objc-selector : identifier
6633169689Skan     : ( objc-type-name ) identifier
6634169689Skan     : identifier
6635169689Skan
6636169689Skan   objc-optparmlist:
6637169689Skan     objc-optparms objc-optellipsis
6638169689Skan
6639169689Skan   objc-optparms:
6640169689Skan     empty
6641169689Skan     objc-opt-parms , parameter-declaration
6642169689Skan
6643169689Skan   objc-optellipsis:
6644169689Skan     empty
6645169689Skan     , ...
6646169689Skan*/
6647169689Skan
6648169689Skanstatic tree
6649169689Skanc_parser_objc_method_decl (c_parser *parser)
6650169689Skan{
6651169689Skan  tree type = NULL_TREE;
6652169689Skan  tree sel;
6653169689Skan  tree parms = NULL_TREE;
6654169689Skan  bool ellipsis = false;
6655169689Skan
6656169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
6657169689Skan    {
6658169689Skan      c_parser_consume_token (parser);
6659169689Skan      type = c_parser_objc_type_name (parser);
6660169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
6661169689Skan    }
6662169689Skan  sel = c_parser_objc_selector (parser);
6663169689Skan  /* If there is no selector, or a colon follows, we have an
6664169689Skan     objc-keyword-selector.  If there is a selector, and a colon does
6665169689Skan     not follow, that selector ends the objc-method-decl.  */
6666169689Skan  if (!sel || c_parser_next_token_is (parser, CPP_COLON))
6667169689Skan    {
6668169689Skan      tree tsel = sel;
6669169689Skan      tree list = NULL_TREE;
6670169689Skan      while (true)
6671169689Skan	{
6672261188Spfg	  /* APPLE LOCAL radar 4157812 */
6673261188Spfg	  tree attr = NULL_TREE;
6674169689Skan	  tree atype = NULL_TREE, id, keyworddecl;
6675169689Skan	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
6676169689Skan	    break;
6677169689Skan	  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
6678169689Skan	    {
6679169689Skan	      c_parser_consume_token (parser);
6680169689Skan	      atype = c_parser_objc_type_name (parser);
6681169689Skan	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6682169689Skan					 "expected %<)%>");
6683169689Skan	    }
6684261188Spfg	  /* APPLE LOCAL begin radar 4157812 */
6685261188Spfg	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
6686261188Spfg	    attr = c_parser_attributes (parser);
6687261188Spfg	  /* APPLE LOCAL end radar 4157812 */
6688169689Skan	  if (c_parser_next_token_is_not (parser, CPP_NAME))
6689169689Skan	    {
6690169689Skan	      c_parser_error (parser, "expected identifier");
6691169689Skan	      return error_mark_node;
6692169689Skan	    }
6693169689Skan	  id = c_parser_peek_token (parser)->value;
6694169689Skan	  c_parser_consume_token (parser);
6695261188Spfg	  /* APPLE LOCAL radar 4157812 */
6696261188Spfg	  keyworddecl = objc_build_keyword_decl (tsel, atype, id, attr);
6697169689Skan	  list = chainon (list, keyworddecl);
6698169689Skan	  tsel = c_parser_objc_selector (parser);
6699169689Skan	  if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
6700169689Skan	    break;
6701169689Skan	}
6702261188Spfg      /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 y) */
6703261188Spfg      if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
6704261188Spfg	objc_method_attributes = c_parser_attributes (parser);
6705261188Spfg      /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */
6706169689Skan      /* Parse the optional parameter list.  Optional Objective-C
6707169689Skan	 method parameters follow the C syntax, and may include '...'
6708169689Skan	 to denote a variable number of arguments.  */
6709169689Skan      parms = make_node (TREE_LIST);
6710169689Skan      while (c_parser_next_token_is (parser, CPP_COMMA))
6711169689Skan	{
6712169689Skan	  struct c_parm *parm;
6713169689Skan	  c_parser_consume_token (parser);
6714169689Skan	  if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
6715169689Skan	    {
6716169689Skan	      ellipsis = true;
6717169689Skan	      c_parser_consume_token (parser);
6718261188Spfg	      /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */
6719261188Spfg	      if (objc_method_attributes)
6720261188Spfg		error ("method attributes must be specified at the end only");
6721261188Spfg	      if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
6722261188Spfg		objc_method_attributes = c_parser_attributes (parser);
6723261188Spfg	      /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */
6724169689Skan	      break;
6725169689Skan	    }
6726169689Skan	  parm = c_parser_parameter_declaration (parser, NULL_TREE);
6727169689Skan	  if (parm == NULL)
6728169689Skan	    break;
6729169689Skan	  parms = chainon (parms,
6730169689Skan			   build_tree_list (NULL_TREE, grokparm (parm)));
6731169689Skan	}
6732169689Skan      sel = list;
6733169689Skan    }
6734261188Spfg  /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 y) */
6735261188Spfg  else
6736261188Spfg    {
6737261188Spfg      gcc_assert (objc_method_attributes == NULL_TREE);
6738261188Spfg      if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
6739261188Spfg	objc_method_attributes = c_parser_attributes (parser);
6740261188Spfg    }
6741261188Spfg  /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */
6742261188Spfg  /* APPLE LOCAL begin radar 4157812 */
6743261188Spfg  if (sel == NULL)
6744261188Spfg    {
6745261188Spfg      c_parser_error (parser, "objective-c method declaration is expected");
6746261188Spfg      return error_mark_node;
6747261188Spfg    }
6748261188Spfg  /* APPLE LOCAL end radar 4157812 */
6749169689Skan  return objc_build_method_signature (type, sel, parms, ellipsis);
6750169689Skan}
6751169689Skan
6752169689Skan/* Parse an objc-type-name.
6753169689Skan
6754169689Skan   objc-type-name:
6755169689Skan     objc-type-qualifiers[opt] type-name
6756169689Skan     objc-type-qualifiers[opt]
6757169689Skan
6758169689Skan   objc-type-qualifiers:
6759169689Skan     objc-type-qualifier
6760169689Skan     objc-type-qualifiers objc-type-qualifier
6761169689Skan
6762169689Skan   objc-type-qualifier: one of
6763169689Skan     in out inout bycopy byref oneway
6764169689Skan*/
6765169689Skan
6766169689Skanstatic tree
6767169689Skanc_parser_objc_type_name (c_parser *parser)
6768169689Skan{
6769169689Skan  tree quals = NULL_TREE;
6770169689Skan  struct c_type_name *typename = NULL;
6771169689Skan  tree type = NULL_TREE;
6772169689Skan  while (true)
6773169689Skan    {
6774169689Skan      c_token *token = c_parser_peek_token (parser);
6775169689Skan      if (token->type == CPP_KEYWORD
6776169689Skan	  && (token->keyword == RID_IN
6777169689Skan	      || token->keyword == RID_OUT
6778169689Skan	      || token->keyword == RID_INOUT
6779169689Skan	      || token->keyword == RID_BYCOPY
6780169689Skan	      || token->keyword == RID_BYREF
6781169689Skan	      || token->keyword == RID_ONEWAY))
6782169689Skan	{
6783261188Spfg	  /* APPLE LOCAL radar 4301047 (in 4.2 z) */
6784261188Spfg	  quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
6785169689Skan	  c_parser_consume_token (parser);
6786169689Skan	}
6787169689Skan      else
6788169689Skan	break;
6789169689Skan    }
6790169689Skan  if (c_parser_next_token_starts_typename (parser))
6791169689Skan    typename = c_parser_type_name (parser);
6792169689Skan  if (typename)
6793169689Skan    type = groktypename (typename);
6794169689Skan  return build_tree_list (quals, type);
6795169689Skan}
6796169689Skan
6797169689Skan/* Parse objc-protocol-refs.
6798169689Skan
6799169689Skan   objc-protocol-refs:
6800169689Skan     < identifier-list >
6801169689Skan*/
6802169689Skan
6803169689Skanstatic tree
6804169689Skanc_parser_objc_protocol_refs (c_parser *parser)
6805169689Skan{
6806169689Skan  tree list = NULL_TREE;
6807169689Skan  gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
6808169689Skan  c_parser_consume_token (parser);
6809169689Skan  /* Any identifiers, including those declared as type names, are OK
6810169689Skan     here.  */
6811169689Skan  while (true)
6812169689Skan    {
6813169689Skan      tree id;
6814169689Skan      if (c_parser_next_token_is_not (parser, CPP_NAME))
6815169689Skan	{
6816169689Skan	  c_parser_error (parser, "expected identifier");
6817169689Skan	  break;
6818169689Skan	}
6819169689Skan      id = c_parser_peek_token (parser)->value;
6820169689Skan      list = chainon (list, build_tree_list (NULL_TREE, id));
6821169689Skan      c_parser_consume_token (parser);
6822169689Skan      if (c_parser_next_token_is (parser, CPP_COMMA))
6823169689Skan	c_parser_consume_token (parser);
6824169689Skan      else
6825169689Skan	break;
6826169689Skan    }
6827169689Skan  c_parser_require (parser, CPP_GREATER, "expected %<>%>");
6828169689Skan  return list;
6829169689Skan}
6830169689Skan
6831169689Skan/* Parse an objc-try-catch-statement.
6832169689Skan
6833169689Skan   objc-try-catch-statement:
6834169689Skan     @try compound-statement objc-catch-list[opt]
6835169689Skan     @try compound-statement objc-catch-list[opt] @finally compound-statement
6836169689Skan
6837169689Skan   objc-catch-list:
6838169689Skan     @catch ( parameter-declaration ) compound-statement
6839169689Skan     objc-catch-list @catch ( parameter-declaration ) compound-statement
6840169689Skan*/
6841169689Skan
6842169689Skanstatic void
6843169689Skanc_parser_objc_try_catch_statement (c_parser *parser)
6844169689Skan{
6845169689Skan  location_t loc;
6846169689Skan  tree stmt;
6847169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
6848169689Skan  c_parser_consume_token (parser);
6849169689Skan  loc = c_parser_peek_token (parser)->location;
6850169689Skan  stmt = c_parser_compound_statement (parser);
6851169689Skan  objc_begin_try_stmt (loc, stmt);
6852169689Skan  while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
6853169689Skan    {
6854169689Skan      struct c_parm *parm;
6855169689Skan      c_parser_consume_token (parser);
6856169689Skan      if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6857169689Skan	break;
6858261188Spfg      /* APPLE LOCAL begin radar 2848255 */
6859261188Spfg      if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
6860169689Skan	{
6861261188Spfg	  /* @catch (...) */
6862261188Spfg	  c_parser_consume_token (parser);
6863261188Spfg	   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
6864261188Spfg	   objc_begin_catch_clause (NULL_TREE);
6865169689Skan	}
6866261188Spfg      else
6867261188Spfg	{
6868261188Spfg	   parm = c_parser_parameter_declaration (parser, NULL_TREE);
6869261188Spfg	   if (parm == NULL)
6870261188Spfg	    {
6871261188Spfg	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6872261188Spfg	      break;
6873261188Spfg	    }
6874261188Spfg	   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
6875261188Spfg	   objc_begin_catch_clause (grokparm (parm));
6876261188Spfg	}
6877261188Spfg      /* APPLE LOCAL end radar 2848255 */
6878169689Skan      if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
6879169689Skan	c_parser_compound_statement_nostart (parser);
6880169689Skan      objc_finish_catch_clause ();
6881169689Skan    }
6882169689Skan  if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
6883169689Skan    {
6884169689Skan      location_t finloc;
6885169689Skan      tree finstmt;
6886169689Skan      c_parser_consume_token (parser);
6887169689Skan      finloc = c_parser_peek_token (parser)->location;
6888169689Skan      finstmt = c_parser_compound_statement (parser);
6889169689Skan      objc_build_finally_clause (finloc, finstmt);
6890169689Skan    }
6891169689Skan  objc_finish_try_stmt ();
6892169689Skan}
6893169689Skan
6894261188Spfg/* APPLE LOCAL begin radar 5982990 */
6895261188Spfg/* This routine is called from c_parser_objc_synchronized_statement
6896261188Spfg   and is identical to c_parser_compound_statement with
6897261188Spfg   the addition of volatizing local variables seen in the scope
6898261188Spfg   of @synchroniz block.
6899261188Spfg*/
6900261188Spfgstatic tree
6901261188Spfgc_parser_objc_synch_compound_statement (c_parser *parser)
6902261188Spfg{
6903261188Spfg  tree stmt;
6904261188Spfg  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
6905261188Spfg    return error_mark_node;
6906261188Spfg  stmt = c_begin_compound_stmt (true);
6907261188Spfg  c_parser_compound_statement_nostart (parser);
6908261188Spfg  if (flag_objc_sjlj_exceptions)
6909261188Spfg    objc_mark_locals_volatile (NULL);
6910261188Spfg  return c_end_compound_stmt (stmt, true);
6911261188Spfg}
6912261188Spfg/* APPLE LOCAL end radar 5982990 */
6913261188Spfg
6914169689Skan/* Parse an objc-synchronized-statement.
6915169689Skan
6916169689Skan   objc-synchronized-statement:
6917169689Skan     @synchronized ( expression ) compound-statement
6918169689Skan*/
6919169689Skan
6920169689Skanstatic void
6921169689Skanc_parser_objc_synchronized_statement (c_parser *parser)
6922169689Skan{
6923169689Skan  location_t loc;
6924169689Skan  tree expr, stmt;
6925169689Skan  gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
6926169689Skan  c_parser_consume_token (parser);
6927169689Skan  loc = c_parser_peek_token (parser)->location;
6928169689Skan  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6929169689Skan    {
6930169689Skan      expr = c_parser_expression (parser).value;
6931169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
6932169689Skan    }
6933169689Skan  else
6934169689Skan    expr = error_mark_node;
6935261188Spfg  /* APPLE LOCAL radar 5982990 */
6936261188Spfg  stmt = c_parser_objc_synch_compound_statement (parser);
6937169689Skan  objc_build_synchronized (loc, expr, stmt);
6938169689Skan}
6939169689Skan
6940169689Skan/* Parse an objc-selector; return NULL_TREE without an error if the
6941169689Skan   next token is not an objc-selector.
6942169689Skan
6943169689Skan   objc-selector:
6944169689Skan     identifier
6945169689Skan     one of
6946169689Skan       enum struct union if else while do for switch case default
6947169689Skan       break continue return goto asm sizeof typeof __alignof
6948169689Skan       unsigned long const short volatile signed restrict _Complex
6949169689Skan       in out inout bycopy byref oneway int char float double void _Bool
6950169689Skan
6951169689Skan   ??? Why this selection of keywords but not, for example, storage
6952169689Skan   class specifiers?  */
6953169689Skan
6954169689Skanstatic tree
6955169689Skanc_parser_objc_selector (c_parser *parser)
6956169689Skan{
6957169689Skan  c_token *token = c_parser_peek_token (parser);
6958169689Skan  tree value = token->value;
6959169689Skan  if (token->type == CPP_NAME)
6960169689Skan    {
6961169689Skan      c_parser_consume_token (parser);
6962169689Skan      return value;
6963169689Skan    }
6964169689Skan  if (token->type != CPP_KEYWORD)
6965169689Skan    return NULL_TREE;
6966169689Skan  switch (token->keyword)
6967169689Skan    {
6968169689Skan    case RID_ENUM:
6969169689Skan    case RID_STRUCT:
6970169689Skan    case RID_UNION:
6971169689Skan    case RID_IF:
6972169689Skan    case RID_ELSE:
6973169689Skan    case RID_WHILE:
6974169689Skan    case RID_DO:
6975169689Skan    case RID_FOR:
6976169689Skan    case RID_SWITCH:
6977169689Skan    case RID_CASE:
6978169689Skan    case RID_DEFAULT:
6979169689Skan    case RID_BREAK:
6980169689Skan    case RID_CONTINUE:
6981169689Skan    case RID_RETURN:
6982169689Skan    case RID_GOTO:
6983169689Skan    case RID_ASM:
6984169689Skan    case RID_SIZEOF:
6985169689Skan    case RID_TYPEOF:
6986169689Skan    case RID_ALIGNOF:
6987169689Skan    case RID_UNSIGNED:
6988169689Skan    case RID_LONG:
6989169689Skan    case RID_CONST:
6990169689Skan    case RID_SHORT:
6991169689Skan    case RID_VOLATILE:
6992169689Skan    case RID_SIGNED:
6993169689Skan    case RID_RESTRICT:
6994169689Skan    case RID_COMPLEX:
6995169689Skan    case RID_IN:
6996169689Skan    case RID_OUT:
6997169689Skan    case RID_INOUT:
6998169689Skan    case RID_BYCOPY:
6999169689Skan    case RID_BYREF:
7000169689Skan    case RID_ONEWAY:
7001169689Skan    case RID_INT:
7002169689Skan    case RID_CHAR:
7003169689Skan    case RID_FLOAT:
7004169689Skan    case RID_DOUBLE:
7005169689Skan    case RID_VOID:
7006169689Skan    case RID_BOOL:
7007169689Skan      c_parser_consume_token (parser);
7008169689Skan      return value;
7009169689Skan    default:
7010169689Skan      return NULL_TREE;
7011169689Skan    }
7012169689Skan}
7013169689Skan
7014169689Skan/* Parse an objc-selector-arg.
7015169689Skan
7016169689Skan   objc-selector-arg:
7017169689Skan     objc-selector
7018169689Skan     objc-keywordname-list
7019169689Skan
7020169689Skan   objc-keywordname-list:
7021169689Skan     objc-keywordname
7022169689Skan     objc-keywordname-list objc-keywordname
7023169689Skan
7024169689Skan   objc-keywordname:
7025169689Skan     objc-selector :
7026169689Skan     :
7027169689Skan*/
7028169689Skan
7029169689Skanstatic tree
7030169689Skanc_parser_objc_selector_arg (c_parser *parser)
7031169689Skan{
7032169689Skan  tree sel = c_parser_objc_selector (parser);
7033169689Skan  tree list = NULL_TREE;
7034169689Skan  if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
7035169689Skan    return sel;
7036169689Skan  while (true)
7037169689Skan    {
7038169689Skan      if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7039169689Skan	return list;
7040169689Skan      list = chainon (list, build_tree_list (sel, NULL_TREE));
7041169689Skan      sel = c_parser_objc_selector (parser);
7042169689Skan      if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
7043169689Skan	break;
7044169689Skan    }
7045169689Skan  return list;
7046169689Skan}
7047169689Skan
7048169689Skan/* Parse an objc-receiver.
7049169689Skan
7050169689Skan   objc-receiver:
7051169689Skan     expression
7052169689Skan     class-name
7053169689Skan     type-name
7054169689Skan*/
7055169689Skan
7056169689Skanstatic tree
7057169689Skanc_parser_objc_receiver (c_parser *parser)
7058169689Skan{
7059169689Skan  if (c_parser_peek_token (parser)->type == CPP_NAME
7060169689Skan      && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
7061169689Skan	  || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
7062169689Skan    {
7063169689Skan      tree id = c_parser_peek_token (parser)->value;
7064169689Skan      c_parser_consume_token (parser);
7065169689Skan      return objc_get_class_reference (id);
7066169689Skan    }
7067169689Skan  return c_parser_expression (parser).value;
7068169689Skan}
7069169689Skan
7070169689Skan/* Parse objc-message-args.
7071169689Skan
7072169689Skan   objc-message-args:
7073169689Skan     objc-selector
7074169689Skan     objc-keywordarg-list
7075169689Skan
7076169689Skan   objc-keywordarg-list:
7077169689Skan     objc-keywordarg
7078169689Skan     objc-keywordarg-list objc-keywordarg
7079169689Skan
7080169689Skan   objc-keywordarg:
7081169689Skan     objc-selector : objc-keywordexpr
7082169689Skan     : objc-keywordexpr
7083169689Skan*/
7084169689Skan
7085169689Skanstatic tree
7086169689Skanc_parser_objc_message_args (c_parser *parser)
7087169689Skan{
7088169689Skan  tree sel = c_parser_objc_selector (parser);
7089169689Skan  tree list = NULL_TREE;
7090169689Skan  if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
7091169689Skan    return sel;
7092169689Skan  while (true)
7093169689Skan    {
7094169689Skan      tree keywordexpr;
7095169689Skan      if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7096169689Skan	return list;
7097169689Skan      keywordexpr = c_parser_objc_keywordexpr (parser);
7098169689Skan      list = chainon (list, build_tree_list (sel, keywordexpr));
7099169689Skan      sel = c_parser_objc_selector (parser);
7100169689Skan      if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
7101169689Skan	break;
7102169689Skan    }
7103169689Skan  return list;
7104169689Skan}
7105169689Skan
7106169689Skan/* Parse an objc-keywordexpr.
7107169689Skan
7108169689Skan   objc-keywordexpr:
7109169689Skan     nonempty-expr-list
7110169689Skan*/
7111169689Skan
7112169689Skanstatic tree
7113169689Skanc_parser_objc_keywordexpr (c_parser *parser)
7114169689Skan{
7115169689Skan  tree list = c_parser_expr_list (parser, true);
7116169689Skan  if (TREE_CHAIN (list) == NULL_TREE)
7117169689Skan    {
7118169689Skan      /* Just return the expression, remove a level of
7119169689Skan	 indirection.  */
7120169689Skan      return TREE_VALUE (list);
7121169689Skan    }
7122169689Skan  else
7123169689Skan    {
7124169689Skan      /* We have a comma expression, we will collapse later.  */
7125169689Skan      return list;
7126169689Skan    }
7127169689Skan}
7128169689Skan
7129169689Skan
7130169689Skan/* Handle pragmas.  Some OpenMP pragmas are associated with, and therefore
7131169689Skan   should be considered, statements.  ALLOW_STMT is true if we're within
7132169689Skan   the context of a function and such pragmas are to be allowed.  Returns
7133169689Skan   true if we actually parsed such a pragma.  */
7134169689Skan
7135169689Skanstatic bool
7136169689Skanc_parser_pragma (c_parser *parser, enum pragma_context context)
7137169689Skan{
7138169689Skan  unsigned int id;
7139169689Skan
7140169689Skan  id = c_parser_peek_token (parser)->pragma_kind;
7141169689Skan  gcc_assert (id != PRAGMA_NONE);
7142169689Skan
7143169689Skan  switch (id)
7144169689Skan    {
7145169689Skan    case PRAGMA_OMP_BARRIER:
7146169689Skan      if (context != pragma_compound)
7147169689Skan	{
7148169689Skan	  if (context == pragma_stmt)
7149169689Skan	    c_parser_error (parser, "%<#pragma omp barrier%> may only be "
7150169689Skan			    "used in compound statements");
7151169689Skan	  goto bad_stmt;
7152169689Skan	}
7153169689Skan      c_parser_omp_barrier (parser);
7154169689Skan      return false;
7155169689Skan
7156169689Skan    case PRAGMA_OMP_FLUSH:
7157169689Skan      if (context != pragma_compound)
7158169689Skan	{
7159169689Skan	  if (context == pragma_stmt)
7160169689Skan	    c_parser_error (parser, "%<#pragma omp flush%> may only be "
7161169689Skan			    "used in compound statements");
7162169689Skan	  goto bad_stmt;
7163169689Skan	}
7164169689Skan      c_parser_omp_flush (parser);
7165169689Skan      return false;
7166169689Skan
7167169689Skan    case PRAGMA_OMP_THREADPRIVATE:
7168169689Skan      c_parser_omp_threadprivate (parser);
7169169689Skan      return false;
7170169689Skan
7171169689Skan    case PRAGMA_OMP_SECTION:
7172169689Skan      error ("%<#pragma omp section%> may only be used in "
7173169689Skan	     "%<#pragma omp sections%> construct");
7174169689Skan      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
7175169689Skan      return false;
7176169689Skan
7177169689Skan    case PRAGMA_GCC_PCH_PREPROCESS:
7178169689Skan      c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
7179169689Skan      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
7180169689Skan      return false;
7181169689Skan
7182169689Skan    default:
7183169689Skan      if (id < PRAGMA_FIRST_EXTERNAL)
7184169689Skan	{
7185169689Skan	  if (context == pragma_external)
7186169689Skan	    {
7187169689Skan	    bad_stmt:
7188169689Skan	      c_parser_error (parser, "expected declaration specifiers");
7189169689Skan	      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
7190169689Skan	      return false;
7191169689Skan	    }
7192169689Skan	  c_parser_omp_construct (parser);
7193169689Skan	  return true;
7194169689Skan	}
7195169689Skan      break;
7196169689Skan    }
7197169689Skan
7198169689Skan  c_parser_consume_pragma (parser);
7199169689Skan  c_invoke_pragma_handler (id);
7200169689Skan
7201169689Skan  /* Skip to EOL, but suppress any error message.  Those will have been
7202169689Skan     generated by the handler routine through calling error, as opposed
7203169689Skan     to calling c_parser_error.  */
7204169689Skan  parser->error = true;
7205169689Skan  c_parser_skip_to_pragma_eol (parser);
7206169689Skan
7207169689Skan  return false;
7208169689Skan}
7209169689Skan
7210169689Skan/* The interface the pragma parsers have to the lexer.  */
7211169689Skan
7212169689Skanenum cpp_ttype
7213169689Skanpragma_lex (tree *value)
7214169689Skan{
7215169689Skan  c_token *tok = c_parser_peek_token (the_parser);
7216169689Skan  enum cpp_ttype ret = tok->type;
7217169689Skan
7218169689Skan  *value = tok->value;
7219169689Skan  if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
7220169689Skan    ret = CPP_EOF;
7221169689Skan  else
7222169689Skan    {
7223169689Skan      if (ret == CPP_KEYWORD)
7224169689Skan	ret = CPP_NAME;
7225169689Skan      c_parser_consume_token (the_parser);
7226169689Skan    }
7227169689Skan
7228169689Skan  return ret;
7229169689Skan}
7230169689Skan
7231169689Skanstatic void
7232169689Skanc_parser_pragma_pch_preprocess (c_parser *parser)
7233169689Skan{
7234169689Skan  tree name = NULL;
7235169689Skan
7236169689Skan  c_parser_consume_pragma (parser);
7237169689Skan  if (c_parser_next_token_is (parser, CPP_STRING))
7238169689Skan    {
7239169689Skan      name = c_parser_peek_token (parser)->value;
7240169689Skan      c_parser_consume_token (parser);
7241169689Skan    }
7242169689Skan  else
7243169689Skan    c_parser_error (parser, "expected string literal");
7244169689Skan  c_parser_skip_to_pragma_eol (parser);
7245169689Skan
7246169689Skan  if (name)
7247169689Skan    c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
7248169689Skan}
7249169689Skan
7250169689Skan/* OpenMP 2.5 parsing routines.  */
7251169689Skan
7252169689Skan/* Returns name of the next clause.
7253169689Skan   If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
7254169689Skan   the token is not consumed.  Otherwise appropriate pragma_omp_clause is
7255169689Skan   returned and the token is consumed.  */
7256169689Skan
7257169689Skanstatic pragma_omp_clause
7258169689Skanc_parser_omp_clause_name (c_parser *parser)
7259169689Skan{
7260169689Skan  pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
7261169689Skan
7262169689Skan  if (c_parser_next_token_is_keyword (parser, RID_IF))
7263169689Skan    result = PRAGMA_OMP_CLAUSE_IF;
7264169689Skan  else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
7265169689Skan    result = PRAGMA_OMP_CLAUSE_DEFAULT;
7266169689Skan  else if (c_parser_next_token_is (parser, CPP_NAME))
7267169689Skan    {
7268169689Skan      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
7269169689Skan
7270169689Skan      switch (p[0])
7271169689Skan	{
7272169689Skan	case 'c':
7273169689Skan	  if (!strcmp ("copyin", p))
7274169689Skan	    result = PRAGMA_OMP_CLAUSE_COPYIN;
7275169689Skan          else if (!strcmp ("copyprivate", p))
7276169689Skan	    result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
7277169689Skan	  break;
7278169689Skan	case 'f':
7279169689Skan	  if (!strcmp ("firstprivate", p))
7280169689Skan	    result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
7281169689Skan	  break;
7282169689Skan	case 'l':
7283169689Skan	  if (!strcmp ("lastprivate", p))
7284169689Skan	    result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
7285169689Skan	  break;
7286169689Skan	case 'n':
7287169689Skan	  if (!strcmp ("nowait", p))
7288169689Skan	    result = PRAGMA_OMP_CLAUSE_NOWAIT;
7289169689Skan	  else if (!strcmp ("num_threads", p))
7290169689Skan	    result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
7291169689Skan	  break;
7292169689Skan	case 'o':
7293169689Skan	  if (!strcmp ("ordered", p))
7294169689Skan	    result = PRAGMA_OMP_CLAUSE_ORDERED;
7295169689Skan	  break;
7296169689Skan	case 'p':
7297169689Skan	  if (!strcmp ("private", p))
7298169689Skan	    result = PRAGMA_OMP_CLAUSE_PRIVATE;
7299169689Skan	  break;
7300169689Skan	case 'r':
7301169689Skan	  if (!strcmp ("reduction", p))
7302169689Skan	    result = PRAGMA_OMP_CLAUSE_REDUCTION;
7303169689Skan	  break;
7304169689Skan	case 's':
7305169689Skan	  if (!strcmp ("schedule", p))
7306169689Skan	    result = PRAGMA_OMP_CLAUSE_SCHEDULE;
7307169689Skan	  else if (!strcmp ("shared", p))
7308169689Skan	    result = PRAGMA_OMP_CLAUSE_SHARED;
7309169689Skan	  break;
7310169689Skan	}
7311169689Skan    }
7312169689Skan
7313169689Skan  if (result != PRAGMA_OMP_CLAUSE_NONE)
7314169689Skan    c_parser_consume_token (parser);
7315169689Skan
7316169689Skan  return result;
7317169689Skan}
7318169689Skan
7319169689Skan/* Validate that a clause of the given type does not already exist.  */
7320169689Skan
7321169689Skanstatic void
7322169689Skancheck_no_duplicate_clause (tree clauses, enum tree_code code, const char *name)
7323169689Skan{
7324169689Skan  tree c;
7325169689Skan
7326169689Skan  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
7327169689Skan    if (OMP_CLAUSE_CODE (c) == code)
7328169689Skan      {
7329169689Skan	error ("too many %qs clauses", name);
7330169689Skan	break;
7331169689Skan      }
7332169689Skan}
7333169689Skan
7334169689Skan/* OpenMP 2.5:
7335169689Skan   variable-list:
7336169689Skan     identifier
7337169689Skan     variable-list , identifier
7338169689Skan
7339169689Skan   If KIND is nonzero, create the appropriate node and install the decl
7340169689Skan   in OMP_CLAUSE_DECL and add the node to the head of the list.
7341169689Skan
7342169689Skan   If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
7343169689Skan   return the list created.  */
7344169689Skan
7345169689Skanstatic tree
7346169689Skanc_parser_omp_variable_list (c_parser *parser, enum omp_clause_code kind,
7347169689Skan                            tree list)
7348169689Skan{
7349169689Skan  if (c_parser_next_token_is_not (parser, CPP_NAME)
7350169689Skan      || c_parser_peek_token (parser)->id_kind != C_ID_ID)
7351169689Skan    c_parser_error (parser, "expected identifier");
7352169689Skan
7353169689Skan  while (c_parser_next_token_is (parser, CPP_NAME)
7354169689Skan	 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
7355169689Skan    {
7356169689Skan      tree t = lookup_name (c_parser_peek_token (parser)->value);
7357169689Skan
7358169689Skan      if (t == NULL_TREE)
7359169689Skan	undeclared_variable (c_parser_peek_token (parser)->value,
7360169689Skan			     c_parser_peek_token (parser)->location);
7361169689Skan      else if (t == error_mark_node)
7362169689Skan	;
7363169689Skan      else if (kind != 0)
7364169689Skan	{
7365169689Skan	  tree u = build_omp_clause (kind);
7366169689Skan	  OMP_CLAUSE_DECL (u) = t;
7367169689Skan	  OMP_CLAUSE_CHAIN (u) = list;
7368169689Skan	  list = u;
7369169689Skan	}
7370169689Skan      else
7371169689Skan	list = tree_cons (t, NULL_TREE, list);
7372169689Skan
7373169689Skan      c_parser_consume_token (parser);
7374169689Skan
7375169689Skan      if (c_parser_next_token_is_not (parser, CPP_COMMA))
7376169689Skan	break;
7377169689Skan
7378169689Skan      c_parser_consume_token (parser);
7379169689Skan    }
7380169689Skan
7381169689Skan  return list;
7382169689Skan}
7383169689Skan
7384169689Skan/* Similarly, but expect leading and trailing parenthesis.  This is a very
7385169689Skan   common case for omp clauses.  */
7386169689Skan
7387169689Skanstatic tree
7388169689Skanc_parser_omp_var_list_parens (c_parser *parser, enum tree_code kind, tree list)
7389169689Skan{
7390169689Skan  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7391169689Skan    {
7392169689Skan      list = c_parser_omp_variable_list (parser, kind, list);
7393169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7394169689Skan    }
7395169689Skan  return list;
7396169689Skan}
7397169689Skan
7398169689Skan/* OpenMP 2.5:
7399169689Skan   copyin ( variable-list ) */
7400169689Skan
7401169689Skanstatic tree
7402169689Skanc_parser_omp_clause_copyin (c_parser *parser, tree list)
7403169689Skan{
7404169689Skan  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
7405169689Skan}
7406169689Skan
7407169689Skan/* OpenMP 2.5:
7408169689Skan   copyprivate ( variable-list ) */
7409169689Skan
7410169689Skanstatic tree
7411169689Skanc_parser_omp_clause_copyprivate (c_parser *parser, tree list)
7412169689Skan{
7413169689Skan  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
7414169689Skan}
7415169689Skan
7416169689Skan/* OpenMP 2.5:
7417169689Skan   default ( shared | none ) */
7418169689Skan
7419169689Skanstatic tree
7420169689Skanc_parser_omp_clause_default (c_parser *parser, tree list)
7421169689Skan{
7422169689Skan  enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
7423169689Skan  tree c;
7424169689Skan
7425169689Skan  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7426169689Skan    return list;
7427169689Skan  if (c_parser_next_token_is (parser, CPP_NAME))
7428169689Skan    {
7429169689Skan      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
7430169689Skan
7431169689Skan      switch (p[0])
7432169689Skan	{
7433169689Skan	case 'n':
7434169689Skan	  if (strcmp ("none", p) != 0)
7435169689Skan	    goto invalid_kind;
7436169689Skan	  kind = OMP_CLAUSE_DEFAULT_NONE;
7437169689Skan	  break;
7438169689Skan
7439169689Skan	case 's':
7440169689Skan	  if (strcmp ("shared", p) != 0)
7441169689Skan	    goto invalid_kind;
7442169689Skan	  kind = OMP_CLAUSE_DEFAULT_SHARED;
7443169689Skan	  break;
7444169689Skan
7445169689Skan	default:
7446169689Skan	  goto invalid_kind;
7447169689Skan	}
7448169689Skan
7449169689Skan      c_parser_consume_token (parser);
7450169689Skan    }
7451169689Skan  else
7452169689Skan    {
7453169689Skan    invalid_kind:
7454169689Skan      c_parser_error (parser, "expected %<none%> or %<shared%>");
7455169689Skan    }
7456169689Skan  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7457169689Skan
7458169689Skan  if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7459169689Skan    return list;
7460169689Skan
7461169689Skan  check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
7462169689Skan  c = build_omp_clause (OMP_CLAUSE_DEFAULT);
7463169689Skan  OMP_CLAUSE_CHAIN (c) = list;
7464169689Skan  OMP_CLAUSE_DEFAULT_KIND (c) = kind;
7465169689Skan
7466169689Skan  return c;
7467169689Skan}
7468169689Skan
7469169689Skan/* OpenMP 2.5:
7470169689Skan   firstprivate ( variable-list ) */
7471169689Skan
7472169689Skanstatic tree
7473169689Skanc_parser_omp_clause_firstprivate (c_parser *parser, tree list)
7474169689Skan{
7475169689Skan  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
7476169689Skan}
7477169689Skan
7478169689Skan/* OpenMP 2.5:
7479169689Skan   if ( expression ) */
7480169689Skan
7481169689Skanstatic tree
7482169689Skanc_parser_omp_clause_if (c_parser *parser, tree list)
7483169689Skan{
7484169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7485169689Skan    {
7486169689Skan      tree t = c_parser_paren_condition (parser);
7487169689Skan      tree c;
7488169689Skan
7489169689Skan      check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
7490169689Skan
7491169689Skan      c = build_omp_clause (OMP_CLAUSE_IF);
7492169689Skan      OMP_CLAUSE_IF_EXPR (c) = t;
7493169689Skan      OMP_CLAUSE_CHAIN (c) = list;
7494169689Skan      list = c;
7495169689Skan    }
7496169689Skan  else
7497169689Skan    c_parser_error (parser, "expected %<(%>");
7498169689Skan
7499169689Skan  return list;
7500169689Skan}
7501169689Skan
7502169689Skan/* OpenMP 2.5:
7503169689Skan   lastprivate ( variable-list ) */
7504169689Skan
7505169689Skanstatic tree
7506169689Skanc_parser_omp_clause_lastprivate (c_parser *parser, tree list)
7507169689Skan{
7508169689Skan  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LASTPRIVATE, list);
7509169689Skan}
7510169689Skan
7511169689Skan/* OpenMP 2.5:
7512169689Skan   nowait */
7513169689Skan
7514169689Skanstatic tree
7515169689Skanc_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
7516169689Skan{
7517169689Skan  tree c;
7518169689Skan
7519169689Skan  check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
7520169689Skan
7521169689Skan  c = build_omp_clause (OMP_CLAUSE_NOWAIT);
7522169689Skan  OMP_CLAUSE_CHAIN (c) = list;
7523169689Skan  return c;
7524169689Skan}
7525169689Skan
7526169689Skan/* OpenMP 2.5:
7527169689Skan   num_threads ( expression ) */
7528169689Skan
7529169689Skanstatic tree
7530169689Skanc_parser_omp_clause_num_threads (c_parser *parser, tree list)
7531169689Skan{
7532169689Skan  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7533169689Skan    {
7534169689Skan      tree c, t = c_parser_expression (parser).value;
7535169689Skan
7536169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7537169689Skan
7538169689Skan      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
7539169689Skan	{
7540169689Skan	  c_parser_error (parser, "expected integer expression");
7541169689Skan	  return list;
7542169689Skan	}
7543169689Skan
7544169689Skan      /* Attempt to statically determine when the number isn't positive.  */
7545169689Skan      c = fold_build2 (LE_EXPR, boolean_type_node, t,
7546169689Skan		       build_int_cst (TREE_TYPE (t), 0));
7547169689Skan      if (c == boolean_true_node)
7548169689Skan	{
7549169689Skan	  warning (0, "%<num_threads%> value must be positive");
7550169689Skan	  t = integer_one_node;
7551169689Skan	}
7552169689Skan
7553169689Skan      check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
7554169689Skan
7555169689Skan      c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
7556169689Skan      OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
7557169689Skan      OMP_CLAUSE_CHAIN (c) = list;
7558169689Skan      list = c;
7559169689Skan    }
7560169689Skan
7561169689Skan  return list;
7562169689Skan}
7563169689Skan
7564169689Skan/* OpenMP 2.5:
7565169689Skan   ordered */
7566169689Skan
7567169689Skanstatic tree
7568169689Skanc_parser_omp_clause_ordered (c_parser *parser ATTRIBUTE_UNUSED, tree list)
7569169689Skan{
7570169689Skan  tree c;
7571169689Skan
7572169689Skan  check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
7573169689Skan
7574169689Skan  c = build_omp_clause (OMP_CLAUSE_ORDERED);
7575169689Skan  OMP_CLAUSE_CHAIN (c) = list;
7576169689Skan  return c;
7577169689Skan}
7578169689Skan
7579169689Skan/* OpenMP 2.5:
7580169689Skan   private ( variable-list ) */
7581169689Skan
7582169689Skanstatic tree
7583169689Skanc_parser_omp_clause_private (c_parser *parser, tree list)
7584169689Skan{
7585169689Skan  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
7586169689Skan}
7587169689Skan
7588169689Skan/* OpenMP 2.5:
7589169689Skan   reduction ( reduction-operator : variable-list )
7590169689Skan
7591169689Skan   reduction-operator:
7592169689Skan     One of: + * - & ^ | && || */
7593169689Skan
7594169689Skanstatic tree
7595169689Skanc_parser_omp_clause_reduction (c_parser *parser, tree list)
7596169689Skan{
7597169689Skan  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7598169689Skan    {
7599169689Skan      enum tree_code code;
7600169689Skan
7601169689Skan      switch (c_parser_peek_token (parser)->type)
7602169689Skan	{
7603169689Skan	case CPP_PLUS:
7604169689Skan	  code = PLUS_EXPR;
7605169689Skan	  break;
7606169689Skan	case CPP_MULT:
7607169689Skan	  code = MULT_EXPR;
7608169689Skan	  break;
7609169689Skan	case CPP_MINUS:
7610169689Skan	  code = MINUS_EXPR;
7611169689Skan	  break;
7612169689Skan	case CPP_AND:
7613169689Skan	  code = BIT_AND_EXPR;
7614169689Skan	  break;
7615169689Skan	case CPP_XOR:
7616169689Skan	  code = BIT_XOR_EXPR;
7617169689Skan	  break;
7618169689Skan	case CPP_OR:
7619169689Skan	  code = BIT_IOR_EXPR;
7620169689Skan	  break;
7621169689Skan	case CPP_AND_AND:
7622169689Skan	  code = TRUTH_ANDIF_EXPR;
7623169689Skan	  break;
7624169689Skan	case CPP_OR_OR:
7625169689Skan	  code = TRUTH_ORIF_EXPR;
7626169689Skan	  break;
7627169689Skan	default:
7628169689Skan	  c_parser_error (parser,
7629169689Skan			  "expected %<+%>, %<*%>, %<-%>, %<&%>, "
7630169689Skan			  "%<^%>, %<|%>, %<&&%>, or %<||%>");
7631169689Skan	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
7632169689Skan	  return list;
7633169689Skan	}
7634169689Skan      c_parser_consume_token (parser);
7635169689Skan      if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7636169689Skan	{
7637169689Skan	  tree nl, c;
7638169689Skan
7639169689Skan	  nl = c_parser_omp_variable_list (parser, OMP_CLAUSE_REDUCTION, list);
7640169689Skan	  for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
7641169689Skan	    OMP_CLAUSE_REDUCTION_CODE (c) = code;
7642169689Skan
7643169689Skan	  list = nl;
7644169689Skan	}
7645169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7646169689Skan    }
7647169689Skan  return list;
7648169689Skan}
7649169689Skan
7650169689Skan/* OpenMP 2.5:
7651169689Skan   schedule ( schedule-kind )
7652169689Skan   schedule ( schedule-kind , expression )
7653169689Skan
7654169689Skan   schedule-kind:
7655169689Skan     static | dynamic | guided | runtime
7656169689Skan*/
7657169689Skan
7658169689Skanstatic tree
7659169689Skanc_parser_omp_clause_schedule (c_parser *parser, tree list)
7660169689Skan{
7661169689Skan  tree c, t;
7662169689Skan
7663169689Skan  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7664169689Skan    return list;
7665169689Skan
7666169689Skan  c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
7667169689Skan
7668169689Skan  if (c_parser_next_token_is (parser, CPP_NAME))
7669169689Skan    {
7670169689Skan      tree kind = c_parser_peek_token (parser)->value;
7671169689Skan      const char *p = IDENTIFIER_POINTER (kind);
7672169689Skan
7673169689Skan      switch (p[0])
7674169689Skan	{
7675169689Skan	case 'd':
7676169689Skan	  if (strcmp ("dynamic", p) != 0)
7677169689Skan	    goto invalid_kind;
7678169689Skan	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
7679169689Skan	  break;
7680169689Skan
7681169689Skan        case 'g':
7682169689Skan	  if (strcmp ("guided", p) != 0)
7683169689Skan	    goto invalid_kind;
7684169689Skan	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
7685169689Skan	  break;
7686169689Skan
7687169689Skan	case 'r':
7688169689Skan	  if (strcmp ("runtime", p) != 0)
7689169689Skan	    goto invalid_kind;
7690169689Skan	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
7691169689Skan	  break;
7692169689Skan
7693169689Skan	default:
7694169689Skan	  goto invalid_kind;
7695169689Skan	}
7696169689Skan    }
7697169689Skan  else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
7698169689Skan    OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
7699169689Skan  else
7700169689Skan    goto invalid_kind;
7701169689Skan
7702169689Skan  c_parser_consume_token (parser);
7703169689Skan  if (c_parser_next_token_is (parser, CPP_COMMA))
7704169689Skan    {
7705169689Skan      c_parser_consume_token (parser);
7706169689Skan
7707169689Skan      t = c_parser_expr_no_commas (parser, NULL).value;
7708169689Skan
7709169689Skan      if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
7710169689Skan	error ("schedule %<runtime%> does not take "
7711169689Skan	       "a %<chunk_size%> parameter");
7712169689Skan      else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
7713169689Skan	OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
7714169689Skan      else
7715169689Skan	c_parser_error (parser, "expected integer expression");
7716169689Skan
7717169689Skan      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7718169689Skan    }
7719169689Skan  else
7720169689Skan    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
7721169689Skan			       "expected %<,%> or %<)%>");
7722169689Skan
7723169689Skan  check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
7724169689Skan  OMP_CLAUSE_CHAIN (c) = list;
7725169689Skan  return c;
7726169689Skan
7727169689Skan invalid_kind:
7728169689Skan  c_parser_error (parser, "invalid schedule kind");
7729169689Skan  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
7730169689Skan  return list;
7731169689Skan}
7732169689Skan
7733169689Skan/* OpenMP 2.5:
7734169689Skan   shared ( variable-list ) */
7735169689Skan
7736169689Skanstatic tree
7737169689Skanc_parser_omp_clause_shared (c_parser *parser, tree list)
7738169689Skan{
7739169689Skan  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
7740169689Skan}
7741169689Skan
7742169689Skan/* Parse all OpenMP clauses.  The set clauses allowed by the directive
7743169689Skan   is a bitmask in MASK.  Return the list of clauses found; the result
7744169689Skan   of clause default goes in *pdefault.  */
7745169689Skan
7746169689Skanstatic tree
7747169689Skanc_parser_omp_all_clauses (c_parser *parser, unsigned int mask,
7748169689Skan			  const char *where)
7749169689Skan{
7750169689Skan  tree clauses = NULL;
7751169689Skan
7752169689Skan  while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
7753169689Skan    {
7754169689Skan      const pragma_omp_clause c_kind = c_parser_omp_clause_name (parser);
7755169689Skan      const char *c_name;
7756169689Skan      tree prev = clauses;
7757169689Skan
7758169689Skan      switch (c_kind)
7759169689Skan	{
7760169689Skan	case PRAGMA_OMP_CLAUSE_COPYIN:
7761169689Skan	  clauses = c_parser_omp_clause_copyin (parser, clauses);
7762169689Skan	  c_name = "copyin";
7763169689Skan	  break;
7764169689Skan	case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
7765169689Skan	  clauses = c_parser_omp_clause_copyprivate (parser, clauses);
7766169689Skan	  c_name = "copyprivate";
7767169689Skan	  break;
7768169689Skan	case PRAGMA_OMP_CLAUSE_DEFAULT:
7769169689Skan	  clauses = c_parser_omp_clause_default (parser, clauses);
7770169689Skan	  c_name = "default";
7771169689Skan	  break;
7772169689Skan	case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
7773169689Skan	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
7774169689Skan	  c_name = "firstprivate";
7775169689Skan	  break;
7776169689Skan	case PRAGMA_OMP_CLAUSE_IF:
7777169689Skan	  clauses = c_parser_omp_clause_if (parser, clauses);
7778169689Skan	  c_name = "if";
7779169689Skan	  break;
7780169689Skan	case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
7781169689Skan	  clauses = c_parser_omp_clause_lastprivate (parser, clauses);
7782169689Skan	  c_name = "lastprivate";
7783169689Skan	  break;
7784169689Skan	case PRAGMA_OMP_CLAUSE_NOWAIT:
7785169689Skan	  clauses = c_parser_omp_clause_nowait (parser, clauses);
7786169689Skan	  c_name = "nowait";
7787169689Skan	  break;
7788169689Skan	case PRAGMA_OMP_CLAUSE_NUM_THREADS:
7789169689Skan	  clauses = c_parser_omp_clause_num_threads (parser, clauses);
7790169689Skan	  c_name = "num_threads";
7791169689Skan	  break;
7792169689Skan	case PRAGMA_OMP_CLAUSE_ORDERED:
7793169689Skan	  clauses = c_parser_omp_clause_ordered (parser, clauses);
7794169689Skan	  c_name = "ordered";
7795169689Skan	  break;
7796169689Skan	case PRAGMA_OMP_CLAUSE_PRIVATE:
7797169689Skan	  clauses = c_parser_omp_clause_private (parser, clauses);
7798169689Skan	  c_name = "private";
7799169689Skan	  break;
7800169689Skan	case PRAGMA_OMP_CLAUSE_REDUCTION:
7801169689Skan	  clauses = c_parser_omp_clause_reduction (parser, clauses);
7802169689Skan	  c_name = "reduction";
7803169689Skan	  break;
7804169689Skan	case PRAGMA_OMP_CLAUSE_SCHEDULE:
7805169689Skan	  clauses = c_parser_omp_clause_schedule (parser, clauses);
7806169689Skan	  c_name = "schedule";
7807169689Skan	  break;
7808169689Skan	case PRAGMA_OMP_CLAUSE_SHARED:
7809169689Skan	  clauses = c_parser_omp_clause_shared (parser, clauses);
7810169689Skan	  c_name = "shared";
7811169689Skan	  break;
7812169689Skan	default:
7813169689Skan	  c_parser_error (parser, "expected %<#pragma omp%> clause");
7814169689Skan	  goto saw_error;
7815169689Skan	}
7816169689Skan
7817169689Skan      if (((mask >> c_kind) & 1) == 0 && !parser->error)
7818169689Skan	{
7819169689Skan	  /* Remove the invalid clause(s) from the list to avoid
7820169689Skan	     confusing the rest of the compiler.  */
7821169689Skan	  clauses = prev;
7822169689Skan	  error ("%qs is not valid for %qs", c_name, where);
7823169689Skan	}
7824169689Skan    }
7825169689Skan
7826169689Skan saw_error:
7827169689Skan  c_parser_skip_to_pragma_eol (parser);
7828169689Skan
7829169689Skan  return c_finish_omp_clauses (clauses);
7830169689Skan}
7831169689Skan
7832169689Skan/* OpenMP 2.5:
7833169689Skan   structured-block:
7834169689Skan     statement
7835169689Skan
7836169689Skan   In practice, we're also interested in adding the statement to an
7837169689Skan   outer node.  So it is convenient if we work around the fact that
7838169689Skan   c_parser_statement calls add_stmt.  */
7839169689Skan
7840169689Skanstatic tree
7841169689Skanc_parser_omp_structured_block (c_parser *parser)
7842169689Skan{
7843169689Skan  tree stmt = push_stmt_list ();
7844169689Skan  c_parser_statement (parser);
7845169689Skan  return pop_stmt_list (stmt);
7846169689Skan}
7847169689Skan
7848169689Skan/* OpenMP 2.5:
7849169689Skan   # pragma omp atomic new-line
7850169689Skan     expression-stmt
7851169689Skan
7852169689Skan   expression-stmt:
7853169689Skan     x binop= expr | x++ | ++x | x-- | --x
7854169689Skan   binop:
7855169689Skan     +, *, -, /, &, ^, |, <<, >>
7856169689Skan
7857169689Skan  where x is an lvalue expression with scalar type.  */
7858169689Skan
7859169689Skanstatic void
7860169689Skanc_parser_omp_atomic (c_parser *parser)
7861169689Skan{
7862169689Skan  tree lhs, rhs;
7863169689Skan  tree stmt;
7864169689Skan  enum tree_code code;
7865169689Skan
7866169689Skan  c_parser_skip_to_pragma_eol (parser);
7867169689Skan
7868169689Skan  lhs = c_parser_unary_expression (parser).value;
7869169689Skan  switch (TREE_CODE (lhs))
7870169689Skan    {
7871169689Skan    case ERROR_MARK:
7872169689Skan    saw_error:
7873169689Skan      c_parser_skip_to_end_of_block_or_statement (parser);
7874169689Skan      return;
7875169689Skan
7876169689Skan    case PREINCREMENT_EXPR:
7877169689Skan    case POSTINCREMENT_EXPR:
7878169689Skan      lhs = TREE_OPERAND (lhs, 0);
7879169689Skan      code = PLUS_EXPR;
7880169689Skan      rhs = integer_one_node;
7881169689Skan      break;
7882169689Skan
7883169689Skan    case PREDECREMENT_EXPR:
7884169689Skan    case POSTDECREMENT_EXPR:
7885169689Skan      lhs = TREE_OPERAND (lhs, 0);
7886169689Skan      code = MINUS_EXPR;
7887169689Skan      rhs = integer_one_node;
7888169689Skan      break;
7889169689Skan
7890169689Skan    default:
7891169689Skan      switch (c_parser_peek_token (parser)->type)
7892169689Skan	{
7893169689Skan	case CPP_MULT_EQ:
7894169689Skan	  code = MULT_EXPR;
7895169689Skan	  break;
7896169689Skan	case CPP_DIV_EQ:
7897169689Skan	  code = TRUNC_DIV_EXPR;
7898169689Skan	  break;
7899169689Skan	case CPP_PLUS_EQ:
7900169689Skan	  code = PLUS_EXPR;
7901169689Skan	  break;
7902169689Skan	case CPP_MINUS_EQ:
7903169689Skan	  code = MINUS_EXPR;
7904169689Skan	  break;
7905169689Skan	case CPP_LSHIFT_EQ:
7906169689Skan	  code = LSHIFT_EXPR;
7907169689Skan	  break;
7908169689Skan	case CPP_RSHIFT_EQ:
7909169689Skan	  code = RSHIFT_EXPR;
7910169689Skan	  break;
7911169689Skan	case CPP_AND_EQ:
7912169689Skan	  code = BIT_AND_EXPR;
7913169689Skan	  break;
7914169689Skan	case CPP_OR_EQ:
7915169689Skan	  code = BIT_IOR_EXPR;
7916169689Skan	  break;
7917169689Skan	case CPP_XOR_EQ:
7918169689Skan	  code = BIT_XOR_EXPR;
7919169689Skan	  break;
7920169689Skan	default:
7921169689Skan	  c_parser_error (parser,
7922169689Skan			  "invalid operator for %<#pragma omp atomic%>");
7923169689Skan	  goto saw_error;
7924169689Skan	}
7925169689Skan
7926169689Skan      c_parser_consume_token (parser);
7927169689Skan      rhs = c_parser_expression (parser).value;
7928169689Skan      break;
7929169689Skan    }
7930169689Skan  stmt = c_finish_omp_atomic (code, lhs, rhs);
7931169689Skan  if (stmt != error_mark_node)
7932169689Skan    add_stmt (stmt);
7933169689Skan  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7934169689Skan}
7935169689Skan
7936169689Skan
7937169689Skan/* OpenMP 2.5:
7938169689Skan   # pragma omp barrier new-line
7939169689Skan*/
7940169689Skan
7941169689Skanstatic void
7942169689Skanc_parser_omp_barrier (c_parser *parser)
7943169689Skan{
7944169689Skan  c_parser_consume_pragma (parser);
7945169689Skan  c_parser_skip_to_pragma_eol (parser);
7946169689Skan
7947169689Skan  c_finish_omp_barrier ();
7948169689Skan}
7949169689Skan
7950169689Skan/* OpenMP 2.5:
7951169689Skan   # pragma omp critical [(name)] new-line
7952169689Skan     structured-block
7953169689Skan*/
7954169689Skan
7955169689Skanstatic tree
7956169689Skanc_parser_omp_critical (c_parser *parser)
7957169689Skan{
7958169689Skan  tree stmt, name = NULL;
7959169689Skan
7960169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7961169689Skan    {
7962169689Skan      c_parser_consume_token (parser);
7963169689Skan      if (c_parser_next_token_is (parser, CPP_NAME))
7964169689Skan	{
7965169689Skan	  name = c_parser_peek_token (parser)->value;
7966169689Skan	  c_parser_consume_token (parser);
7967169689Skan	  c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7968169689Skan	}
7969169689Skan      else
7970169689Skan	c_parser_error (parser, "expected identifier");
7971169689Skan    }
7972169689Skan  else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
7973169689Skan    c_parser_error (parser, "expected %<(%> or end of line");
7974169689Skan  c_parser_skip_to_pragma_eol (parser);
7975169689Skan
7976169689Skan  stmt = c_parser_omp_structured_block (parser);
7977169689Skan  return c_finish_omp_critical (stmt, name);
7978169689Skan}
7979169689Skan
7980169689Skan/* OpenMP 2.5:
7981169689Skan   # pragma omp flush flush-vars[opt] new-line
7982169689Skan
7983169689Skan   flush-vars:
7984169689Skan     ( variable-list ) */
7985169689Skan
7986169689Skanstatic void
7987169689Skanc_parser_omp_flush (c_parser *parser)
7988169689Skan{
7989169689Skan  c_parser_consume_pragma (parser);
7990169689Skan  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7991169689Skan    c_parser_omp_var_list_parens (parser, 0, NULL);
7992169689Skan  else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
7993169689Skan    c_parser_error (parser, "expected %<(%> or end of line");
7994169689Skan  c_parser_skip_to_pragma_eol (parser);
7995169689Skan
7996169689Skan  c_finish_omp_flush ();
7997169689Skan}
7998169689Skan
7999169689Skan/* Parse the restricted form of the for statment allowed by OpenMP.
8000169689Skan   The real trick here is to determine the loop control variable early
8001169689Skan   so that we can push a new decl if necessary to make it private.  */
8002169689Skan
8003169689Skanstatic tree
8004169689Skanc_parser_omp_for_loop (c_parser *parser)
8005169689Skan{
8006169689Skan  tree decl, cond, incr, save_break, save_cont, body, init;
8007169689Skan  location_t loc;
8008169689Skan
8009169689Skan  if (!c_parser_next_token_is_keyword (parser, RID_FOR))
8010169689Skan    {
8011169689Skan      c_parser_error (parser, "for statement expected");
8012169689Skan      return NULL;
8013169689Skan    }
8014169689Skan  loc = c_parser_peek_token (parser)->location;
8015169689Skan  c_parser_consume_token (parser);
8016169689Skan
8017169689Skan  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
8018169689Skan    return NULL;
8019169689Skan
8020169689Skan  /* Parse the initialization declaration or expression.  */
8021169689Skan  if (c_parser_next_token_starts_declspecs (parser))
8022169689Skan    {
8023261188Spfg      /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */
8024261188Spfg      c_parser_declaration_or_fndef (parser, true, true, true, true, NULL);
8025169689Skan      decl = check_for_loop_decls ();
8026169689Skan      if (decl == NULL)
8027169689Skan	goto error_init;
8028169689Skan      init = decl;
8029169689Skan    }
8030169689Skan  else if (c_parser_next_token_is (parser, CPP_NAME)
8031169689Skan	   && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
8032169689Skan    {
8033169689Skan      decl = c_parser_postfix_expression (parser).value;
8034169689Skan
8035169689Skan      c_parser_require (parser, CPP_EQ, "expected %<=%>");
8036169689Skan
8037169689Skan      init = c_parser_expr_no_commas (parser, NULL).value;
8038169689Skan      init = build_modify_expr (decl, NOP_EXPR, init);
8039169689Skan      init = c_process_expr_stmt (init);
8040169689Skan
8041169689Skan      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
8042169689Skan    }
8043169689Skan  else
8044169689Skan    goto error_init;
8045169689Skan
8046169689Skan  /* Parse the loop condition.  */
8047169689Skan  cond = NULL_TREE;
8048169689Skan  if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
8049169689Skan    {
8050169689Skan      cond = c_parser_expression_conv (parser).value;
8051169689Skan      cond = c_objc_common_truthvalue_conversion (cond);
8052169689Skan      if (EXPR_P (cond))
8053169689Skan	SET_EXPR_LOCATION (cond, input_location);
8054169689Skan    }
8055169689Skan  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
8056169689Skan
8057169689Skan  /* Parse the increment expression.  */
8058169689Skan  incr = NULL_TREE;
8059169689Skan  if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
8060169689Skan    incr = c_process_expr_stmt (c_parser_expression (parser).value);
8061169689Skan  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8062169689Skan
8063169689Skan parse_body:
8064169689Skan  save_break = c_break_label;
8065169689Skan  c_break_label = size_one_node;
8066169689Skan  save_cont = c_cont_label;
8067169689Skan  c_cont_label = NULL_TREE;
8068169689Skan  body = push_stmt_list ();
8069169689Skan
8070169689Skan  add_stmt (c_parser_c99_block_statement (parser));
8071169689Skan  if (c_cont_label)
8072169689Skan    add_stmt (build1 (LABEL_EXPR, void_type_node, c_cont_label));
8073169689Skan
8074169689Skan  body = pop_stmt_list (body);
8075169689Skan  c_break_label = save_break;
8076169689Skan  c_cont_label = save_cont;
8077169689Skan
8078169689Skan  /* Only bother calling c_finish_omp_for if we havn't already generated
8079169689Skan     an error from the initialization parsing.  */
8080169689Skan  if (decl != NULL && decl != error_mark_node && init != error_mark_node)
8081169689Skan    return c_finish_omp_for (loc, decl, init, cond, incr, body, NULL);
8082169689Skan  return NULL;
8083169689Skan
8084169689Skan error_init:
8085169689Skan  c_parser_error (parser, "expected iteration declaration or initialization");
8086169689Skan  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8087169689Skan  decl = init = cond = incr = NULL_TREE;
8088169689Skan  goto parse_body;
8089169689Skan}
8090169689Skan
8091169689Skan/* OpenMP 2.5:
8092169689Skan   #pragma omp for for-clause[optseq] new-line
8093169689Skan     for-loop
8094169689Skan*/
8095169689Skan
8096169689Skan#define OMP_FOR_CLAUSE_MASK				\
8097169689Skan	( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
8098169689Skan	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
8099169689Skan	| (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE)		\
8100169689Skan	| (1u << PRAGMA_OMP_CLAUSE_REDUCTION)		\
8101169689Skan	| (1u << PRAGMA_OMP_CLAUSE_ORDERED)		\
8102169689Skan	| (1u << PRAGMA_OMP_CLAUSE_SCHEDULE)		\
8103169689Skan	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
8104169689Skan
8105169689Skanstatic tree
8106169689Skanc_parser_omp_for (c_parser *parser)
8107169689Skan{
8108169689Skan  tree block, clauses, ret;
8109169689Skan
8110169689Skan  clauses = c_parser_omp_all_clauses (parser, OMP_FOR_CLAUSE_MASK,
8111169689Skan				      "#pragma omp for");
8112169689Skan
8113169689Skan  block = c_begin_compound_stmt (true);
8114169689Skan  ret = c_parser_omp_for_loop (parser);
8115169689Skan  if (ret)
8116169689Skan    OMP_FOR_CLAUSES (ret) = clauses;
8117169689Skan  block = c_end_compound_stmt (block, true);
8118169689Skan  add_stmt (block);
8119169689Skan
8120169689Skan  return ret;
8121169689Skan}
8122169689Skan
8123169689Skan/* OpenMP 2.5:
8124169689Skan   # pragma omp master new-line
8125169689Skan     structured-block
8126169689Skan*/
8127169689Skan
8128169689Skanstatic tree
8129169689Skanc_parser_omp_master (c_parser *parser)
8130169689Skan{
8131169689Skan  c_parser_skip_to_pragma_eol (parser);
8132169689Skan  return c_finish_omp_master (c_parser_omp_structured_block (parser));
8133169689Skan}
8134169689Skan
8135169689Skan/* OpenMP 2.5:
8136169689Skan   # pragma omp ordered new-line
8137169689Skan     structured-block
8138169689Skan*/
8139169689Skan
8140169689Skanstatic tree
8141169689Skanc_parser_omp_ordered (c_parser *parser)
8142169689Skan{
8143169689Skan  c_parser_skip_to_pragma_eol (parser);
8144169689Skan  return c_finish_omp_ordered (c_parser_omp_structured_block (parser));
8145169689Skan}
8146169689Skan
8147169689Skan/* OpenMP 2.5:
8148169689Skan
8149169689Skan   section-scope:
8150169689Skan     { section-sequence }
8151169689Skan
8152169689Skan   section-sequence:
8153169689Skan     section-directive[opt] structured-block
8154169689Skan     section-sequence section-directive structured-block  */
8155169689Skan
8156169689Skanstatic tree
8157169689Skanc_parser_omp_sections_scope (c_parser *parser)
8158169689Skan{
8159169689Skan  tree stmt, substmt;
8160169689Skan  bool error_suppress = false;
8161169689Skan  location_t loc;
8162169689Skan
8163169689Skan  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
8164169689Skan    {
8165169689Skan      /* Avoid skipping until the end of the block.  */
8166169689Skan      parser->error = false;
8167169689Skan      return NULL_TREE;
8168169689Skan    }
8169169689Skan
8170169689Skan  stmt = push_stmt_list ();
8171169689Skan
8172169689Skan  loc = c_parser_peek_token (parser)->location;
8173169689Skan  if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
8174169689Skan    {
8175169689Skan      substmt = push_stmt_list ();
8176169689Skan
8177169689Skan      while (1)
8178169689Skan	{
8179169689Skan          c_parser_statement (parser);
8180169689Skan
8181169689Skan	  if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
8182169689Skan	    break;
8183169689Skan	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
8184169689Skan	    break;
8185169689Skan	  if (c_parser_next_token_is (parser, CPP_EOF))
8186169689Skan	    break;
8187169689Skan	}
8188169689Skan
8189169689Skan      substmt = pop_stmt_list (substmt);
8190169689Skan      substmt = build1 (OMP_SECTION, void_type_node, substmt);
8191169689Skan      SET_EXPR_LOCATION (substmt, loc);
8192169689Skan      add_stmt (substmt);
8193169689Skan    }
8194169689Skan
8195169689Skan  while (1)
8196169689Skan    {
8197169689Skan      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
8198169689Skan	break;
8199169689Skan      if (c_parser_next_token_is (parser, CPP_EOF))
8200169689Skan	break;
8201169689Skan
8202169689Skan      loc = c_parser_peek_token (parser)->location;
8203169689Skan      if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
8204169689Skan	{
8205169689Skan	  c_parser_consume_pragma (parser);
8206169689Skan	  c_parser_skip_to_pragma_eol (parser);
8207169689Skan	  error_suppress = false;
8208169689Skan	}
8209169689Skan      else if (!error_suppress)
8210169689Skan	{
8211169689Skan	  error ("expected %<#pragma omp section%> or %<}%>");
8212169689Skan	  error_suppress = true;
8213169689Skan	}
8214169689Skan
8215169689Skan      substmt = c_parser_omp_structured_block (parser);
8216169689Skan      substmt = build1 (OMP_SECTION, void_type_node, substmt);
8217169689Skan      SET_EXPR_LOCATION (substmt, loc);
8218169689Skan      add_stmt (substmt);
8219169689Skan    }
8220169689Skan  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
8221169689Skan			     "expected %<#pragma omp section%> or %<}%>");
8222169689Skan
8223169689Skan  substmt = pop_stmt_list (stmt);
8224169689Skan
8225169689Skan  stmt = make_node (OMP_SECTIONS);
8226169689Skan  TREE_TYPE (stmt) = void_type_node;
8227169689Skan  OMP_SECTIONS_BODY (stmt) = substmt;
8228169689Skan
8229169689Skan  return add_stmt (stmt);
8230169689Skan}
8231169689Skan
8232169689Skan/* OpenMP 2.5:
8233169689Skan   # pragma omp sections sections-clause[optseq] newline
8234169689Skan     sections-scope
8235169689Skan*/
8236169689Skan
8237169689Skan#define OMP_SECTIONS_CLAUSE_MASK			\
8238169689Skan	( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
8239169689Skan	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
8240169689Skan	| (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE)		\
8241169689Skan	| (1u << PRAGMA_OMP_CLAUSE_REDUCTION)		\
8242169689Skan	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
8243169689Skan
8244169689Skanstatic tree
8245169689Skanc_parser_omp_sections (c_parser *parser)
8246169689Skan{
8247169689Skan  tree block, clauses, ret;
8248169689Skan
8249169689Skan  clauses = c_parser_omp_all_clauses (parser, OMP_SECTIONS_CLAUSE_MASK,
8250169689Skan				      "#pragma omp sections");
8251169689Skan
8252169689Skan  block = c_begin_compound_stmt (true);
8253169689Skan  ret = c_parser_omp_sections_scope (parser);
8254169689Skan  if (ret)
8255169689Skan    OMP_SECTIONS_CLAUSES (ret) = clauses;
8256169689Skan  block = c_end_compound_stmt (block, true);
8257169689Skan  add_stmt (block);
8258169689Skan
8259169689Skan  return ret;
8260169689Skan}
8261169689Skan
8262169689Skan/* OpenMP 2.5:
8263169689Skan   # pragma parallel parallel-clause new-line
8264169689Skan   # pragma parallel for parallel-for-clause new-line
8265169689Skan   # pragma parallel sections parallel-sections-clause new-line
8266169689Skan*/
8267169689Skan
8268169689Skan#define OMP_PARALLEL_CLAUSE_MASK			\
8269169689Skan	( (1u << PRAGMA_OMP_CLAUSE_IF)			\
8270169689Skan	| (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
8271169689Skan	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
8272169689Skan	| (1u << PRAGMA_OMP_CLAUSE_DEFAULT)		\
8273169689Skan	| (1u << PRAGMA_OMP_CLAUSE_SHARED)		\
8274169689Skan	| (1u << PRAGMA_OMP_CLAUSE_COPYIN)		\
8275169689Skan	| (1u << PRAGMA_OMP_CLAUSE_REDUCTION)		\
8276169689Skan	| (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS))
8277169689Skan
8278169689Skanstatic tree
8279169689Skanc_parser_omp_parallel (c_parser *parser)
8280169689Skan{
8281169689Skan  enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL;
8282169689Skan  const char *p_name = "#pragma omp parallel";
8283169689Skan  tree stmt, clauses, par_clause, ws_clause, block;
8284169689Skan  unsigned int mask = OMP_PARALLEL_CLAUSE_MASK;
8285169689Skan
8286169689Skan  if (c_parser_next_token_is_keyword (parser, RID_FOR))
8287169689Skan    {
8288169689Skan      c_parser_consume_token (parser);
8289169689Skan      p_kind = PRAGMA_OMP_PARALLEL_FOR;
8290169689Skan      p_name = "#pragma omp parallel for";
8291169689Skan      mask |= OMP_FOR_CLAUSE_MASK;
8292169689Skan      mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT);
8293169689Skan    }
8294169689Skan  else if (c_parser_next_token_is (parser, CPP_NAME))
8295169689Skan    {
8296169689Skan      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
8297169689Skan      if (strcmp (p, "sections") == 0)
8298169689Skan	{
8299169689Skan	  c_parser_consume_token (parser);
8300169689Skan	  p_kind = PRAGMA_OMP_PARALLEL_SECTIONS;
8301169689Skan	  p_name = "#pragma omp parallel sections";
8302169689Skan	  mask |= OMP_SECTIONS_CLAUSE_MASK;
8303169689Skan	  mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT);
8304169689Skan	}
8305169689Skan    }
8306169689Skan
8307169689Skan  clauses = c_parser_omp_all_clauses (parser, mask, p_name);
8308169689Skan
8309169689Skan  switch (p_kind)
8310169689Skan    {
8311169689Skan    case PRAGMA_OMP_PARALLEL:
8312169689Skan      block = c_begin_omp_parallel ();
8313169689Skan      c_parser_statement (parser);
8314169689Skan      stmt = c_finish_omp_parallel (clauses, block);
8315169689Skan      break;
8316169689Skan
8317169689Skan    case PRAGMA_OMP_PARALLEL_FOR:
8318169689Skan      block = c_begin_omp_parallel ();
8319169689Skan      c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
8320169689Skan      stmt = c_parser_omp_for_loop (parser);
8321169689Skan      if (stmt)
8322169689Skan	OMP_FOR_CLAUSES (stmt) = ws_clause;
8323169689Skan      stmt = c_finish_omp_parallel (par_clause, block);
8324169689Skan      OMP_PARALLEL_COMBINED (stmt) = 1;
8325169689Skan      break;
8326169689Skan
8327169689Skan    case PRAGMA_OMP_PARALLEL_SECTIONS:
8328169689Skan      block = c_begin_omp_parallel ();
8329169689Skan      c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
8330169689Skan      stmt = c_parser_omp_sections_scope (parser);
8331169689Skan      if (stmt)
8332169689Skan	OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
8333169689Skan      stmt = c_finish_omp_parallel (par_clause, block);
8334169689Skan      OMP_PARALLEL_COMBINED (stmt) = 1;
8335169689Skan      break;
8336169689Skan
8337169689Skan    default:
8338169689Skan      gcc_unreachable ();
8339169689Skan    }
8340169689Skan
8341169689Skan  return stmt;
8342169689Skan}
8343169689Skan
8344169689Skan/* OpenMP 2.5:
8345169689Skan   # pragma omp single single-clause[optseq] new-line
8346169689Skan     structured-block
8347169689Skan*/
8348169689Skan
8349169689Skan#define OMP_SINGLE_CLAUSE_MASK				\
8350169689Skan	( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)		\
8351169689Skan	| (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
8352169689Skan	| (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE)		\
8353169689Skan	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
8354169689Skan
8355169689Skanstatic tree
8356169689Skanc_parser_omp_single (c_parser *parser)
8357169689Skan{
8358169689Skan  tree stmt = make_node (OMP_SINGLE);
8359169689Skan  TREE_TYPE (stmt) = void_type_node;
8360169689Skan
8361169689Skan  OMP_SINGLE_CLAUSES (stmt)
8362169689Skan    = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
8363169689Skan				"#pragma omp single");
8364169689Skan  OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser);
8365169689Skan
8366169689Skan  return add_stmt (stmt);
8367169689Skan}
8368169689Skan
8369169689Skan
8370169689Skan/* Main entry point to parsing most OpenMP pragmas.  */
8371169689Skan
8372169689Skanstatic void
8373169689Skanc_parser_omp_construct (c_parser *parser)
8374169689Skan{
8375169689Skan  enum pragma_kind p_kind;
8376169689Skan  location_t loc;
8377169689Skan  tree stmt;
8378169689Skan
8379169689Skan  loc = c_parser_peek_token (parser)->location;
8380169689Skan  p_kind = c_parser_peek_token (parser)->pragma_kind;
8381169689Skan  c_parser_consume_pragma (parser);
8382169689Skan
8383169689Skan  /* For all constructs below except #pragma omp atomic
8384169689Skan     MUST_NOT_THROW catch handlers are needed when exceptions
8385169689Skan     are enabled.  */
8386169689Skan  if (p_kind != PRAGMA_OMP_ATOMIC)
8387169689Skan    c_maybe_initialize_eh ();
8388169689Skan
8389169689Skan  switch (p_kind)
8390169689Skan    {
8391169689Skan    case PRAGMA_OMP_ATOMIC:
8392169689Skan      c_parser_omp_atomic (parser);
8393169689Skan      return;
8394169689Skan    case PRAGMA_OMP_CRITICAL:
8395169689Skan      stmt = c_parser_omp_critical (parser);
8396169689Skan      break;
8397169689Skan    case PRAGMA_OMP_FOR:
8398169689Skan      stmt = c_parser_omp_for (parser);
8399169689Skan      break;
8400169689Skan    case PRAGMA_OMP_MASTER:
8401169689Skan      stmt = c_parser_omp_master (parser);
8402169689Skan      break;
8403169689Skan    case PRAGMA_OMP_ORDERED:
8404169689Skan      stmt = c_parser_omp_ordered (parser);
8405169689Skan      break;
8406169689Skan    case PRAGMA_OMP_PARALLEL:
8407169689Skan      stmt = c_parser_omp_parallel (parser);
8408169689Skan      break;
8409169689Skan    case PRAGMA_OMP_SECTIONS:
8410169689Skan      stmt = c_parser_omp_sections (parser);
8411169689Skan      break;
8412169689Skan    case PRAGMA_OMP_SINGLE:
8413169689Skan      stmt = c_parser_omp_single (parser);
8414169689Skan      break;
8415169689Skan    default:
8416169689Skan      gcc_unreachable ();
8417169689Skan    }
8418169689Skan
8419169689Skan  if (stmt)
8420169689Skan    SET_EXPR_LOCATION (stmt, loc);
8421169689Skan}
8422169689Skan
8423169689Skan
8424169689Skan/* OpenMP 2.5:
8425169689Skan   # pragma omp threadprivate (variable-list) */
8426169689Skan
8427169689Skanstatic void
8428169689Skanc_parser_omp_threadprivate (c_parser *parser)
8429169689Skan{
8430169689Skan  tree vars, t;
8431169689Skan
8432169689Skan  c_parser_consume_pragma (parser);
8433169689Skan  vars = c_parser_omp_var_list_parens (parser, 0, NULL);
8434169689Skan
8435169689Skan  if (!targetm.have_tls)
8436169689Skan    sorry ("threadprivate variables not supported in this target");
8437169689Skan
8438169689Skan  /* Mark every variable in VARS to be assigned thread local storage.  */
8439169689Skan  for (t = vars; t; t = TREE_CHAIN (t))
8440169689Skan    {
8441169689Skan      tree v = TREE_PURPOSE (t);
8442169689Skan
8443169689Skan      /* If V had already been marked threadprivate, it doesn't matter
8444169689Skan	 whether it had been used prior to this point.  */
8445169689Skan      if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
8446169689Skan	error ("%qE declared %<threadprivate%> after first use", v);
8447169689Skan      else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
8448169689Skan	error ("automatic variable %qE cannot be %<threadprivate%>", v);
8449169689Skan      else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
8450169689Skan	error ("%<threadprivate%> %qE has incomplete type", v);
8451169689Skan      else
8452169689Skan	{
8453169689Skan	  if (! DECL_THREAD_LOCAL_P (v))
8454169689Skan	    {
8455169689Skan	      DECL_TLS_MODEL (v) = decl_default_tls_model (v);
8456169689Skan	      /* If rtl has been already set for this var, call
8457169689Skan		 make_decl_rtl once again, so that encode_section_info
8458169689Skan		 has a chance to look at the new decl flags.  */
8459169689Skan	      if (DECL_RTL_SET_P (v))
8460169689Skan		make_decl_rtl (v);
8461169689Skan	    }
8462169689Skan	  C_DECL_THREADPRIVATE_P (v) = 1;
8463169689Skan	}
8464169689Skan    }
8465169689Skan
8466169689Skan  c_parser_skip_to_pragma_eol (parser);
8467169689Skan}
8468169689Skan
8469169689Skan
8470169689Skan/* Parse a single source file.  */
8471169689Skan
8472169689Skanvoid
8473169689Skanc_parse_file (void)
8474169689Skan{
8475169689Skan  /* Use local storage to begin.  If the first token is a pragma, parse it.
8476169689Skan     If it is #pragma GCC pch_preprocess, then this will load a PCH file
8477169689Skan     which will cause garbage collection.  */
8478169689Skan  c_parser tparser;
8479169689Skan
8480169689Skan  memset (&tparser, 0, sizeof tparser);
8481169689Skan  the_parser = &tparser;
8482169689Skan
8483169689Skan  if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
8484169689Skan    c_parser_pragma_pch_preprocess (&tparser);
8485169689Skan
8486169689Skan  the_parser = GGC_NEW (c_parser);
8487169689Skan  *the_parser = tparser;
8488169689Skan
8489169689Skan  c_parser_translation_unit (the_parser);
8490169689Skan  the_parser = NULL;
8491169689Skan}
8492169689Skan
8493261188Spfg/* APPLE LOCAL begin radar 5732232 - blocks (C++ ce) */
8494261188Spfg
8495261188Spfg/* APPLE LOCAL begin radar 6300081  */
8496261188Spfg
8497261188Spfg/* This function builds a "generic" block struct type, to be passed
8498261188Spfg   into the debug information for blocks pointers, to allow gdb to
8499261188Spfg   find the actual function pointer for the block.  Any time the Blocks
8500261188Spfg   structure layout changes, this may also need to change.
8501261188Spfg
8502261188Spfg   Currently a block pointer is a pointer to a __block_literal_n struct,
8503261188Spfg   the third field of which is a pointer to a __block_descriptor struct,
8504261188Spfg   whose third field is the function pointer.  There are other fields as
8505261188Spfg   well, but these are the ones gdb needs to know about to find the
8506261188Spfg   function pointer.  Therefore a generic block struct currently looks
8507261188Spfg   like this:
8508261188Spfg
8509261188Spfg   struct __block_literal_generic
8510261188Spfg   {
8511261188Spfg      void * __isa;
8512261188Spfg      int __flags;
8513261188Spfg      int __reserved;
8514261188Spfg      void (*__FuncPtr)(void *);
8515261188Spfg      struct __block_descriptor
8516261188Spfg	 {
8517261188Spfg	   unsigned long int reserved;
8518261188Spfg	  unsigned long int Size;
8519261188Spfg	} *__descriptor;
8520261188Spfg   };
8521261188Spfg
8522261188Spfg   IF AT ANY TIME THE STRUCTURE OF A __BLOCK_LITERAL_N CHANGES, THIS
8523261188Spfg   MUST BE CHANGED ALSO!!
8524261188Spfg
8525261188Spfg*/
8526261188Spfg
8527261188Spfgtree
8528261188Spfg/* APPLE LOCAL radar 6353006  */
8529261188Spfgc_build_generic_block_struct_type (void)
8530261188Spfg{
8531261188Spfg  tree field_decl_chain;
8532261188Spfg  tree field_decl;
8533261188Spfg  tree block_struct_type;
8534261188Spfg
8535261188Spfg  push_to_top_level ();
8536261188Spfg  block_struct_type = start_struct (RECORD_TYPE,
8537261188Spfg				   get_identifier ("__block_literal_generic"));
8538261188Spfg
8539261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__isa"), ptr_type_node);
8540261188Spfg  field_decl_chain = field_decl;
8541261188Spfg
8542261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__flags"),
8543261188Spfg			   integer_type_node);
8544261188Spfg  chainon (field_decl_chain, field_decl);
8545261188Spfg
8546261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__reserved"),
8547261188Spfg			   integer_type_node);
8548261188Spfg  chainon (field_decl_chain, field_decl);
8549261188Spfg
8550261188Spfg  /* void *__FuncPtr; */
8551261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__FuncPtr"), ptr_type_node);
8552261188Spfg  chainon (field_decl_chain, field_decl);
8553261188Spfg
8554261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__descriptor"),
8555261188Spfg			   build_block_descriptor_type (false));
8556261188Spfg  chainon (field_decl_chain, field_decl);
8557261188Spfg
8558261188Spfg  TYPE_BLOCK_IMPL_STRUCT (block_struct_type) = 1;
8559261188Spfg  finish_struct (block_struct_type, field_decl_chain, NULL_TREE);
8560261188Spfg  pop_from_top_level ();
8561261188Spfg  return block_struct_type;
8562261188Spfg}
8563261188Spfg/* APPLE LOCAL end radar 6300081  */
8564261188Spfg
8565261188Spfg/* APPLE LOCAL begin radar 5847213 - radar 6329245 */
8566261188Spfg/** build_block_struct_type -
8567261188Spfg struct __block_literal_n {
8568261188Spfg  void *__isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
8569261188Spfg  int __flags;
8570261188Spfg  int __reserved;
8571261188Spfg  void *__FuncPtr;
8572261188Spfg  struct __block_descriptor {
8573261188Spfg    unsigned long int reserved;     // NULL
8574261188Spfg    unsigned long int Size;  // sizeof(struct __block_literal_n)
8575261188Spfg
8576261188Spfg    // optional helper functions
8577261188Spfg    void *CopyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE
8578261188Spfg    void *DestroyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE
8579261188Spfg } *__descriptor;
8580261188Spfg
8581261188Spfg // imported variables
8582261188Spfg int x; // ref variable list ...
8583261188Spfg int *y; // byref variable list
8584261188Spfg };
8585261188Spfg*/
8586261188Spfgstatic tree
8587261188Spfgbuild_block_struct_type (struct block_sema_info * block_impl)
8588261188Spfg{
8589261188Spfg  tree field_decl_chain, field_decl, chain;
8590261188Spfg  char buffer[32];
8591261188Spfg  static int unique_count;
8592261188Spfg  tree block_struct_type;
8593261188Spfg
8594261188Spfg  /* Check and see if this block is required to have a Copy/Dispose
8595261188Spfg     helper function. If yes, set BlockHasCopyDispose to TRUE. */
8596261188Spfg  for (chain = block_impl->block_ref_decl_list; chain;
8597261188Spfg	chain = TREE_CHAIN (chain))
8598261188Spfg    if (block_requires_copying (TREE_VALUE (chain)))
8599261188Spfg    {
8600261188Spfg      block_impl->BlockHasCopyDispose = TRUE;
8601261188Spfg      break;
8602261188Spfg    }
8603261188Spfg
8604261188Spfg  /* Further check to see that we have __block variables which require
8605261188Spfg     Copy/Dispose helpers. */
8606261188Spfg  for (chain = block_impl->block_byref_decl_list; chain;
8607261188Spfg	chain = TREE_CHAIN (chain))
8608261188Spfg    if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain)))
8609261188Spfg      {
8610261188Spfg	block_impl->BlockHasCopyDispose = TRUE;
8611261188Spfg	break;
8612261188Spfg      }
8613261188Spfg
8614261188Spfg  sprintf(buffer, "__block_literal_%d", ++unique_count);
8615261188Spfg  push_to_top_level ();
8616261188Spfg  block_struct_type = start_struct (RECORD_TYPE, get_identifier (buffer));
8617261188Spfg
8618261188Spfg  /* void *__isa; */
8619261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__isa"), ptr_type_node);
8620261188Spfg  field_decl_chain = field_decl;
8621261188Spfg
8622261188Spfg  /* int __flags */
8623261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__flags"),
8624261188Spfg			   integer_type_node);
8625261188Spfg  chainon (field_decl_chain, field_decl);
8626261188Spfg
8627261188Spfg  /* int __reserved */
8628261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__reserved"),
8629261188Spfg			   integer_type_node);
8630261188Spfg  chainon (field_decl_chain, field_decl);
8631261188Spfg
8632261188Spfg  /* void *__FuncPtr; */
8633261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__FuncPtr"), ptr_type_node);
8634261188Spfg  chainon (field_decl_chain, field_decl);
8635261188Spfg
8636261188Spfg  /* struct __block_descriptor *__descriptor */
8637261188Spfg  field_decl = build_decl (FIELD_DECL, get_identifier ("__descriptor"),
8638261188Spfg			    build_block_descriptor_type (block_impl->BlockHasCopyDispose));
8639261188Spfg  chainon (field_decl_chain, field_decl);
8640261188Spfg
8641261188Spfg  if (block_impl->BlockHasCopyDispose)
8642261188Spfg  {
8643261188Spfg    /* If inner block of a nested block has BlockHasCopyDispose, so
8644261188Spfg	does its outer block. */
8645261188Spfg    if (block_impl->prev_block_info)
8646261188Spfg      block_impl->prev_block_info->BlockHasCopyDispose = TRUE;
8647261188Spfg  }
8648261188Spfg
8649261188Spfg  /* int x; // ref variable list ... */
8650261188Spfg  for (chain = block_impl->block_ref_decl_list; chain; chain = TREE_CHAIN (chain))
8651261188Spfg  {
8652261188Spfg    tree p = TREE_VALUE (chain);
8653261188Spfg    /* Note! const-ness of copied in variable must not be carried over to the
8654261188Spfg	type of the synthesized struct field. It prevents to assign to this
8655261188Spfg	field when copy constructor is synthesized. */
8656261188Spfg    field_decl = build_decl (FIELD_DECL, DECL_NAME (p),
8657261188Spfg			     c_build_qualified_type (TREE_TYPE (p),
8658261188Spfg			                             TYPE_UNQUALIFIED));
8659261188Spfg    chainon (field_decl_chain, field_decl);
8660261188Spfg  }
8661261188Spfg
8662261188Spfg  /* int *y; // byref variable list */
8663261188Spfg  for (chain = block_impl->block_byref_decl_list; chain; chain = TREE_CHAIN (chain))
8664261188Spfg  {
8665261188Spfg    tree p = TREE_VALUE (chain);
8666261188Spfg    field_decl = build_decl (FIELD_DECL, DECL_NAME (p),
8667261188Spfg			     TREE_TYPE (p));
8668261188Spfg    chainon (field_decl_chain, field_decl);
8669261188Spfg  }
8670261188Spfg  pop_from_top_level ();
8671261188Spfg  finish_struct (block_struct_type, field_decl_chain, NULL_TREE);
8672261188Spfg  return block_struct_type;
8673261188Spfg}
8674261188Spfg
8675261188Spfg/** build_descriptor_block_decl -
8676261188Spfg  This routine builds a static block_descriptior variable of type:
8677261188Spfg  struct __block_descriptor; and initializes it to:
8678261188Spfg  {0, sizeof(struct literal_block_n),
8679261188Spfg   copy_helper_block_1, // only if block BLOCK_HAS_COPY_DISPOSE
8680261188Spfg   destroy_helper_block_1, // only if block BLOCK_HAS_COPY_DISPOSE
8681261188Spfg  }
8682261188Spfg*/
8683261188Spfgstatic tree
8684261188Spfgbuild_descriptor_block_decl (tree block_struct_type, struct block_sema_info *block_impl)
8685261188Spfg{
8686261188Spfg  extern tree create_tmp_var_raw (tree, const char *);
8687261188Spfg  static int desc_unique_count;
8688261188Spfg  int size;
8689261188Spfg  tree helper_addr, fields;
8690261188Spfg  tree decl, constructor, initlist;
8691261188Spfg  tree exp, bind;
8692261188Spfg  char name [32];
8693261188Spfg  tree descriptor_type =
8694261188Spfg    TREE_TYPE (build_block_descriptor_type (block_impl->BlockHasCopyDispose));
8695261188Spfg
8696261188Spfg  sprintf (name, "__block_descriptor_tmp_%d", ++desc_unique_count);
8697261188Spfg  decl = create_tmp_var_raw (descriptor_type, name);
8698261188Spfg  DECL_CONTEXT (decl) = NULL_TREE;
8699261188Spfg  DECL_ARTIFICIAL (decl) = 1;
8700261188Spfg
8701261188Spfg  /* Initialize "reserved" field to 0 for now. */
8702261188Spfg  fields = TYPE_FIELDS (descriptor_type);
8703261188Spfg  initlist = build_tree_list (fields, build_int_cst (long_unsigned_type_node, 0));
8704261188Spfg  fields = TREE_CHAIN (fields);
8705261188Spfg
8706261188Spfg  /* Initialize "Size" field. */
8707261188Spfg  size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (block_struct_type));
8708261188Spfg  initlist = tree_cons (fields,
8709261188Spfg			build_int_cst (long_unsigned_type_node, size),
8710261188Spfg			initlist);
8711261188Spfg
8712261188Spfg  if (block_impl->BlockHasCopyDispose)
8713261188Spfg    {
8714261188Spfg      /* Initialize "CopyFuncPtr" and "DestroyFuncPtr" fields. */
8715261188Spfg      /* Helpers were previously generated completeley as a nested
8716261188Spfg	 function (and context was required for code gen.) But they are not,
8717261188Spfg	 so context must be set to NULL so initialization logic does not complain. */
8718261188Spfg      DECL_CONTEXT (block_impl->copy_helper_func_decl) = NULL_TREE;
8719261188Spfg      fields = TREE_CHAIN (fields);
8720261188Spfg      helper_addr = build_fold_addr_expr (block_impl->copy_helper_func_decl);
8721261188Spfg      helper_addr = convert (ptr_type_node, helper_addr);
8722261188Spfg      initlist = tree_cons (fields, helper_addr, initlist);
8723261188Spfg      DECL_CONTEXT (block_impl->destroy_helper_func_decl) = NULL_TREE;
8724261188Spfg      fields = TREE_CHAIN (fields);
8725261188Spfg      helper_addr = build_fold_addr_expr (block_impl->destroy_helper_func_decl);
8726261188Spfg      helper_addr = convert (ptr_type_node, helper_addr);
8727261188Spfg      initlist = tree_cons (fields, helper_addr, initlist);
8728261188Spfg    }
8729261188Spfg  constructor = build_constructor_from_list (descriptor_type,
8730261188Spfg			                     nreverse (initlist));
8731261188Spfg  TREE_CONSTANT (constructor) = 1;
8732261188Spfg  TREE_STATIC (constructor) = 1;
8733261188Spfg  TREE_READONLY (constructor) = 1;
8734261188Spfg  DECL_INITIAL (decl) = constructor;
8735261188Spfg  exp = build_stmt (DECL_EXPR, decl);
8736261188Spfg  bind = build3 (BIND_EXPR, void_type_node, decl, exp, NULL);
8737261188Spfg  TREE_SIDE_EFFECTS (bind) = 1;
8738261188Spfg  add_stmt (bind);
8739261188Spfg  TREE_PUBLIC (decl) = 0;
8740261188Spfg  TREE_STATIC (decl) = 1;
8741261188Spfg  finish_decl (decl, constructor, NULL_TREE);
8742261188Spfg  return decl;
8743261188Spfg}
8744261188Spfg
8745261188Spfg/**
8746261188Spfg build_block_struct_initlist - builds the initializer list:
8747261188Spfg { &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa,
8748261188Spfg   BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
8749261188Spfg   0, // __reserved
8750261188Spfg   &helper_1, // __FuncPtr,
8751261188Spfg   &static_descriptor_variable // __descriptor,
8752261188Spfg   x, // user variables.
8753261188Spfg   &y
8754261188Spfg   ...
8755261188Spfg }
8756261188Spfg*/
8757261188Spfgstatic tree
8758261188Spfgbuild_block_struct_initlist (tree block_struct_type,
8759261188Spfg			     struct block_sema_info *block_impl)
8760261188Spfg{
8761261188Spfg  tree initlist, helper_addr;
8762261188Spfg  tree chain, fields;
8763261188Spfg  /* APPLE LOCAL radar 7735196 */
8764261188Spfg  unsigned int flags = 0;
8765261188Spfg  static tree NSConcreteStackBlock_decl = NULL_TREE;
8766261188Spfg  static tree NSConcreteGlobalBlock_decl = NULL_TREE;
8767261188Spfg  tree descriptor_block_decl = build_descriptor_block_decl (block_struct_type, block_impl);
8768261188Spfg
8769261188Spfg  if (block_impl->BlockHasCopyDispose)
8770261188Spfg    /* Note! setting of this flag merely indicates to the runtime that
8771261188Spfg	we have destroy_helper_block/copy_helper_block helper
8772261188Spfg	routines. */
8773261188Spfg    flags |= BLOCK_HAS_COPY_DISPOSE;
8774261188Spfg  /* APPLE LOCAL begin radar 7735196 */
8775261188Spfg  if (block_impl->return_type && aggregate_value_p(block_impl->return_type, 0))
8776261188Spfg    flags |= BLOCK_USE_STRET;
8777261188Spfg  /* APPLE LOCAL end 7735196 */
8778261188Spfg
8779261188Spfg  fields = TYPE_FIELDS (block_struct_type);
8780261188Spfg  /* APPLE LOCAL begin radar 6230297 */
8781261188Spfg  if (!current_function_decl ||
8782261188Spfg      (block_impl->block_ref_decl_list == NULL_TREE &&
8783261188Spfg	block_impl->block_byref_decl_list == NULL_TREE))
8784261188Spfg  /* APPLE LOCAL end radar 6230297 */
8785261188Spfg    {
8786261188Spfg      /* This is a global block. */
8787261188Spfg      /* Find an existing declaration for _NSConcreteGlobalBlock or declare
8788261188Spfg	 extern void *_NSConcreteGlobalBlock; */
8789261188Spfg      if (NSConcreteGlobalBlock_decl == NULL_TREE)
8790261188Spfg	{
8791261188Spfg	  tree name_id = get_identifier("_NSConcreteGlobalBlock");
8792261188Spfg	  NSConcreteGlobalBlock_decl = lookup_name (name_id);
8793261188Spfg	  if (!NSConcreteGlobalBlock_decl)
8794261188Spfg	    {
8795261188Spfg	      NSConcreteGlobalBlock_decl = build_decl (VAR_DECL, name_id, ptr_type_node);
8796261188Spfg	      DECL_EXTERNAL (NSConcreteGlobalBlock_decl) = 1;
8797261188Spfg	      TREE_PUBLIC (NSConcreteGlobalBlock_decl) = 1;
8798261188Spfg	      pushdecl_top_level (NSConcreteGlobalBlock_decl);
8799261188Spfg	      rest_of_decl_compilation (NSConcreteGlobalBlock_decl, 0, 0);
8800261188Spfg	    }
8801261188Spfg	}
8802261188Spfg      /* APPLE LOCAL begin radar 6457359 */
8803261188Spfg      initlist = build_tree_list (fields,
8804261188Spfg			          convert (ptr_type_node,
8805261188Spfg			                   build_fold_addr_expr (NSConcreteGlobalBlock_decl)));
8806261188Spfg      /* APPLE LOCAL end radar 6457359 */
8807261188Spfg      flags |= BLOCK_IS_GLOBAL;
8808261188Spfg    }
8809261188Spfg  else
8810261188Spfg    {
8811261188Spfg      /* Find an existing declaration for _NSConcreteStackBlock or declare
8812261188Spfg	 extern void *_NSConcreteStackBlock; */
8813261188Spfg      if (NSConcreteStackBlock_decl == NULL_TREE)
8814261188Spfg	{
8815261188Spfg	  tree name_id = get_identifier("_NSConcreteStackBlock");
8816261188Spfg	  NSConcreteStackBlock_decl = lookup_name (name_id);
8817261188Spfg	  if (!NSConcreteStackBlock_decl)
8818261188Spfg	    {
8819261188Spfg	      NSConcreteStackBlock_decl = build_decl (VAR_DECL, name_id, ptr_type_node);
8820261188Spfg	      DECL_EXTERNAL (NSConcreteStackBlock_decl) = 1;
8821261188Spfg	      TREE_PUBLIC (NSConcreteStackBlock_decl) = 1;
8822261188Spfg	      pushdecl_top_level (NSConcreteStackBlock_decl);
8823261188Spfg	      rest_of_decl_compilation (NSConcreteStackBlock_decl, 0, 0);
8824261188Spfg	    }
8825261188Spfg	}
8826261188Spfg      /* APPLE LOCAL begin radar 6457359 */
8827261188Spfg      initlist = build_tree_list (fields,
8828261188Spfg			          convert (ptr_type_node,
8829261188Spfg			                   build_fold_addr_expr (NSConcreteStackBlock_decl)));
8830261188Spfg      /* APPLE LOCAL end radar 6457359 */
8831261188Spfg    }
8832261188Spfg  fields = TREE_CHAIN (fields);
8833261188Spfg
8834261188Spfg  /* __flags */
8835261188Spfg  initlist = tree_cons (fields,
8836261188Spfg			build_int_cst (integer_type_node, flags),
8837261188Spfg			initlist);
8838261188Spfg  fields = TREE_CHAIN (fields);
8839261188Spfg
8840261188Spfg  /* __reserved */
8841261188Spfg  initlist = tree_cons (fields,
8842261188Spfg			build_int_cst (integer_type_node, 0),
8843261188Spfg			initlist);
8844261188Spfg  fields = TREE_CHAIN (fields);
8845261188Spfg
8846261188Spfg  /* __FuncPtr */
8847261188Spfg  helper_addr = build_fold_addr_expr (block_impl->helper_func_decl);
8848261188Spfg  helper_addr = convert (ptr_type_node, helper_addr);
8849261188Spfg  initlist = tree_cons (fields, helper_addr, initlist);
8850261188Spfg  fields = TREE_CHAIN (fields);
8851261188Spfg
8852261188Spfg  /* __descriptor */
8853261188Spfg  /* APPLE LOCAL begin radar 6457359 */
8854261188Spfg  initlist = tree_cons (fields,
8855261188Spfg			build_fold_addr_expr (descriptor_block_decl),
8856261188Spfg			initlist);
8857261188Spfg  /* APPLE LOCAL end radar 6457359 */
8858261188Spfg  for (chain = block_impl->block_original_ref_decl_list; chain;
8859261188Spfg	chain = TREE_CHAIN (chain))
8860261188Spfg    {
8861261188Spfg      tree y = TREE_VALUE (chain);
8862261188Spfg      TREE_USED (y) = 1;
8863261188Spfg      fields = TREE_CHAIN (fields);
8864261188Spfg      initlist = tree_cons (fields, y, initlist);
8865261188Spfg    }
8866261188Spfg  for (chain = block_impl->block_byref_decl_list; chain;
8867261188Spfg	chain = TREE_CHAIN (chain))
8868261188Spfg    {
8869261188Spfg      tree y = lookup_name (DECL_NAME (TREE_VALUE (chain)));
8870261188Spfg      tree forwarding_expr;
8871261188Spfg      gcc_assert (y);
8872261188Spfg      TREE_USED (y) = 1;
8873261188Spfg      if (COPYABLE_BYREF_LOCAL_VAR (y))
8874261188Spfg	 {
8875261188Spfg	  /* For variables declared __block, either the original one
8876261188Spfg	     at the point of declaration or the imported version (which is
8877261188Spfg	     initialized in the helper function's prologue) is used to
8878261188Spfg	     initilize the byref variable field in the temporary. */
8879261188Spfg	   if (TREE_CODE (TREE_TYPE (y)) != RECORD_TYPE)
8880261188Spfg	     y = build_indirect_ref (y, "unary *");
8881261188Spfg	  /* We will be using the __block_struct_variable.__forwarding as the
8882261188Spfg	     initializer. */
8883261188Spfg	   forwarding_expr = build_component_ref (y, get_identifier ("__forwarding"));
8884261188Spfg	 }
8885261188Spfg      else
8886261188Spfg	/* Global variable is always assumed passed by its address. */
8887261188Spfg	forwarding_expr = build_fold_addr_expr (y);
8888261188Spfg      fields = TREE_CHAIN (fields);
8889261188Spfg      initlist = tree_cons (fields, forwarding_expr, initlist);
8890261188Spfg    }
8891261188Spfg  return initlist;
8892261188Spfg}
8893261188Spfg
8894261188Spfg/**
8895261188Spfg build_block_literal_tmp - This routine:
8896261188Spfg
8897261188Spfg 1) builds block type:
8898261188Spfg struct __block_literal_n {
8899261188Spfg  void *__isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
8900261188Spfg  int __flags;
8901261188Spfg  int __reserved;
8902261188Spfg  void *__FuncPtr
8903261188Spfg  struct __block_descriptor {
8904261188Spfg    unsigned long int reserved;     // NULL
8905261188Spfg    unsigned long int Size;  // sizeof(struct Block_literal_1)
8906261188Spfg
8907261188Spfg    // optional helper functions
8908261188Spfg    void *CopyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE
8909261188Spfg    void *DestroyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE
8910261188Spfg } *__descriptor;
8911261188Spfg
8912261188Spfg // imported variables
8913261188Spfg int x; // ref variable list ...
8914261188Spfg int *y; // byref variable list
8915261188Spfg };
8916261188Spfg
8917261188Spfg 2) build function prototype:
8918261188Spfg double helper_1(struct __block_literal_n *ii, int z);
8919261188Spfg
8920261188Spfg 3) build the temporary initialization:
8921261188Spfg struct __block_literal_n I = {
8922261188Spfg   &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa,
8923261188Spfg   BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
8924261188Spfg   0, // __reserved
8925261188Spfg   &helper_1, // __FuncPtr
8926261188Spfg   &static_descriptor_variable // __descriptor,
8927261188Spfg   x, // user variables.
8928261188Spfg   &y
8929261188Spfg   ...
8930261188Spfg };
8931261188SpfgIt return the temporary.
8932261188Spfg*/
8933261188Spfg
8934261188Spfgstatic tree
8935261188Spfgbuild_block_literal_tmp (const char *name,
8936261188Spfg			 struct block_sema_info * block_impl)
8937261188Spfg{
8938261188Spfg  extern tree create_tmp_var_raw (tree, const char *);
8939261188Spfg  tree block_holder_tmp_decl;
8940261188Spfg  tree constructor, initlist;
8941261188Spfg  tree exp, bind;
8942261188Spfg  tree block_struct_type = TREE_TYPE (block_impl->block_arg_ptr_type);
8943261188Spfg  /* APPLE LOCAL begin radar 6230297 */
8944261188Spfg  bool staticBlockTmp = (block_impl->block_ref_decl_list == NULL_TREE &&
8945261188Spfg			  block_impl->block_byref_decl_list == NULL_TREE);
8946261188Spfg
8947261188Spfg
8948261188Spfg  block_holder_tmp_decl = create_tmp_var_raw (block_struct_type, name);
8949261188Spfg  /* Context will not be known until when the literal is synthesized.
8950261188Spfg     This is more so in the case of nested block literal blocks.  */
8951261188Spfg  DECL_CONTEXT (block_holder_tmp_decl) = staticBlockTmp ? NULL_TREE
8952261188Spfg			                                 : current_function_decl;
8953261188Spfg  /* In the new ABI, helper function decl. is the initializer for the
8954261188Spfg     descriptor variable which is always declared static. So, it must
8955261188Spfg     have no context; otherwise, gcc thinks that it requires trampoline! when
8956261188Spfg     address of this function is used as initializer. */
8957261188Spfg  DECL_CONTEXT (block_impl->helper_func_decl) = NULL_TREE;
8958261188Spfg  /* APPLE LOCAL end radar 6230297 */
8959261188Spfg  DECL_ARTIFICIAL (block_holder_tmp_decl) = 1;
8960261188Spfg
8961261188Spfg  initlist = build_block_struct_initlist (block_struct_type,
8962261188Spfg					  block_impl);
8963261188Spfg  initlist = nreverse (initlist);
8964261188Spfg  constructor = build_constructor_from_list (block_struct_type,
8965261188Spfg			                      initlist);
8966261188Spfg  TREE_CONSTANT (constructor) = 1;
8967261188Spfg  TREE_STATIC (constructor) = 1;
8968261188Spfg  TREE_READONLY (constructor) = 1;
8969261188Spfg  DECL_INITIAL (block_holder_tmp_decl) = constructor;
8970261188Spfg  exp = build_stmt (DECL_EXPR, block_holder_tmp_decl);
8971261188Spfg  bind = build3 (BIND_EXPR, void_type_node, block_holder_tmp_decl, exp, NULL);
8972261188Spfg  TREE_SIDE_EFFECTS (bind) = 1;
8973261188Spfg  add_stmt (bind);
8974261188Spfg  /* Temporary representing a global block is made global static.  */
8975261188Spfg  /* APPLE LOCAL radar 6230297 */
8976261188Spfg  if (staticBlockTmp || global_bindings_p ()) {
8977261188Spfg    TREE_PUBLIC (block_holder_tmp_decl) = 0;
8978261188Spfg    TREE_STATIC (block_holder_tmp_decl) = 1;
8979261188Spfg    finish_decl (block_holder_tmp_decl, constructor, NULL_TREE);
8980261188Spfg  }
8981261188Spfg  return block_holder_tmp_decl;
8982261188Spfg}
8983261188Spfg/* APPLE LOCAL end radar 5847213 - radar 6329245 */
8984261188Spfg
8985261188Spfgstatic tree
8986261188Spfgclean_and_exit (tree block)
8987261188Spfg{
8988261188Spfg  pop_function_context ();
8989261188Spfg  free (finish_block (block));
8990261188Spfg  return error_mark_node;
8991261188Spfg}
8992261188Spfg
8993261188Spfg/** synth_copy_helper_block_func - This function synthesizes
8994261188Spfg  void copy_helper_block (struct block* _dest, struct block *_src) function.
8995261188Spfg*/
8996261188Spfg
8997261188Spfgstatic void
8998261188Spfgsynth_copy_helper_block_func (struct block_sema_info * block_impl)
8999261188Spfg{
9000261188Spfg  tree stmt, chain, fnbody;
9001261188Spfg  tree dst_arg, src_arg;
9002261188Spfg  struct c_arg_info * arg_info;
9003261188Spfg  /* Set up: (struct block* _dest, struct block *_src) parameters. */
9004261188Spfg  dst_arg = build_decl (PARM_DECL, get_identifier ("_dst"),
9005261188Spfg			 block_impl->block_arg_ptr_type);
9006261188Spfg  DECL_CONTEXT (dst_arg) = cur_block->copy_helper_func_decl;
9007261188Spfg  TREE_USED (dst_arg) = 1;
9008261188Spfg  DECL_ARG_TYPE (dst_arg) = block_impl->block_arg_ptr_type;
9009261188Spfg  src_arg = build_decl (PARM_DECL, get_identifier ("_src"),
9010261188Spfg			 block_impl->block_arg_ptr_type);
9011261188Spfg  /* APPLE LOCAL radar 5847213 */
9012261188Spfg  DECL_CONTEXT (src_arg) = cur_block->copy_helper_func_decl;
9013261188Spfg  TREE_USED (src_arg) = 1;
9014261188Spfg  DECL_ARG_TYPE (src_arg) = block_impl->block_arg_ptr_type;
9015261188Spfg  arg_info = xcalloc (1, sizeof (struct c_arg_info));
9016261188Spfg  TREE_CHAIN (dst_arg) = src_arg;
9017261188Spfg  arg_info->parms = dst_arg;
9018261188Spfg  arg_info->types = tree_cons (NULL_TREE, block_impl->block_arg_ptr_type,
9019261188Spfg			        tree_cons (NULL_TREE,
9020261188Spfg			                   block_impl->block_arg_ptr_type,
9021261188Spfg			                   NULL_TREE));
9022261188Spfg  /* function header synthesis. */
9023261188Spfg  push_function_context ();
9024261188Spfg  start_block_helper_function (cur_block->copy_helper_func_decl);
9025261188Spfg  store_parm_decls_from (arg_info);
9026261188Spfg
9027261188Spfg  /* Body of the function. */
9028261188Spfg  stmt = c_begin_compound_stmt (true);
9029261188Spfg  for (chain = block_impl->block_ref_decl_list; chain;
9030261188Spfg	chain = TREE_CHAIN (chain))
9031261188Spfg    if (block_requires_copying (TREE_VALUE (chain)))
9032261188Spfg    {
9033261188Spfg      /* APPLE LOCAL begin radar 6175959 */
9034261188Spfg      int flag;
9035261188Spfg      tree call_exp;
9036261188Spfg      tree p = TREE_VALUE (chain);
9037261188Spfg      tree dst_block_component, src_block_component;
9038261188Spfg      dst_block_component = build_component_ref (build_indirect_ref (dst_arg, "->"),
9039261188Spfg						 DECL_NAME (p));
9040261188Spfg      src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"),
9041261188Spfg						 DECL_NAME (p));
9042261188Spfg
9043261188Spfg      if (TREE_CODE (TREE_TYPE (p)) == BLOCK_POINTER_TYPE)
9044261188Spfg	 /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, BLOCK_FIELD_IS_BLOCK) */
9045261188Spfg	 flag = BLOCK_FIELD_IS_BLOCK;
9046261188Spfg      else
9047261188Spfg	 /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, BLOCK_FIELD_IS_OBJECT) */
9048261188Spfg	 flag = BLOCK_FIELD_IS_OBJECT;
9049261188Spfg      dst_block_component = build_fold_addr_expr (dst_block_component);
9050261188Spfg      call_exp = build_block_object_assign_call_exp (dst_block_component, src_block_component, flag);
9051261188Spfg      add_stmt (call_exp);
9052261188Spfg      /* APPLE LOCAL end radar 6175959 */
9053261188Spfg    }
9054261188Spfg
9055261188Spfg  /* For each __block declared variable must generate call to:
9056261188Spfg     _Block_object_assign(&_dest->myImportedBlock, _src->myImportedBlock, BLOCK_FIELD_IS_BYREF [|BLOCK_FIELD_IS_WEAK])
9057261188Spfg  */
9058261188Spfg  for (chain = block_impl->block_byref_decl_list; chain;
9059261188Spfg	  chain = TREE_CHAIN (chain))
9060261188Spfg    if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain)))
9061261188Spfg      {
9062261188Spfg	 int flag = BLOCK_FIELD_IS_BYREF;
9063261188Spfg	tree call_exp;
9064261188Spfg	tree p = TREE_VALUE (chain);
9065261188Spfg	tree dst_block_component, src_block_component;
9066261188Spfg	dst_block_component = build_component_ref (build_indirect_ref (dst_arg, "->"),
9067261188Spfg						   DECL_NAME (p));
9068261188Spfg	src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"),
9069261188Spfg						   DECL_NAME (p));
9070261188Spfg
9071261188Spfg	/* _Block_object_assign(&_dest->myImportedClosure, _src->myImportedClosure, BLOCK_FIELD_IS_BYREF [|BLOCK_FIELD_IS_WEAK]) */
9072261188Spfg	 if (COPYABLE_WEAK_BLOCK (p))
9073261188Spfg	  flag |= BLOCK_FIELD_IS_WEAK;
9074261188Spfg
9075261188Spfg	dst_block_component = build_fold_addr_expr (dst_block_component);
9076261188Spfg	call_exp = build_block_object_assign_call_exp (dst_block_component, src_block_component, flag);
9077261188Spfg	add_stmt (call_exp);
9078261188Spfg      }
9079261188Spfg
9080261188Spfg  fnbody = c_end_compound_stmt (stmt, true);
9081261188Spfg  add_stmt (fnbody);
9082261188Spfg  finish_function ();
9083261188Spfg  pop_function_context ();
9084261188Spfg  free (arg_info);
9085261188Spfg}
9086261188Spfg
9087261188Spfgstatic void
9088261188Spfgsynth_destroy_helper_block_func (struct block_sema_info * block_impl)
9089261188Spfg{
9090261188Spfg  tree stmt, chain, fnbody;
9091261188Spfg  tree src_arg;
9092261188Spfg  struct c_arg_info * arg_info;
9093261188Spfg  /* Set up: (struct block *_src) parameter. */
9094261188Spfg  src_arg = build_decl (PARM_DECL, get_identifier ("_src"),
9095261188Spfg			 block_impl->block_arg_ptr_type);
9096261188Spfg  TREE_USED (src_arg) = 1;
9097261188Spfg  DECL_ARG_TYPE (src_arg) = block_impl->block_arg_ptr_type;
9098261188Spfg  arg_info = xcalloc (1, sizeof (struct c_arg_info));
9099261188Spfg  arg_info->parms = src_arg;
9100261188Spfg  arg_info->types = tree_cons (NULL_TREE, block_impl->block_arg_ptr_type,
9101261188Spfg			        NULL_TREE);
9102261188Spfg
9103261188Spfg  /* function header synthesis. */
9104261188Spfg  push_function_context ();
9105261188Spfg  start_block_helper_function (cur_block->destroy_helper_func_decl);
9106261188Spfg  store_parm_decls_from (arg_info);
9107261188Spfg
9108261188Spfg  /* Body of the function. */
9109261188Spfg  stmt = c_begin_compound_stmt (true);
9110261188Spfg  for (chain = block_impl->block_ref_decl_list; chain;
9111261188Spfg	chain = TREE_CHAIN (chain))
9112261188Spfg    if (block_requires_copying (TREE_VALUE (chain)))
9113261188Spfg    {
9114261188Spfg      int flag;
9115261188Spfg      tree rel_exp;
9116261188Spfg      tree p = TREE_VALUE (chain);
9117261188Spfg      tree src_block_component;
9118261188Spfg      src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"),
9119261188Spfg						 DECL_NAME (p));
9120261188Spfg
9121261188Spfg      if (TREE_CODE (TREE_TYPE (p)) == BLOCK_POINTER_TYPE)
9122261188Spfg	/* _Block_object_dispose(_src->imported_object_0, BLOCK_FIELD_IS_BLOCK); */
9123261188Spfg	 flag = BLOCK_FIELD_IS_BLOCK;
9124261188Spfg      else
9125261188Spfg	/* _Block_object_dispose(_src->imported_object_0, BLOCK_FIELD_IS_OBJECT); */
9126261188Spfg	flag = BLOCK_FIELD_IS_OBJECT;
9127261188Spfg      rel_exp = build_block_object_dispose_call_exp (src_block_component, flag);
9128261188Spfg      add_stmt (rel_exp);
9129261188Spfg    }
9130261188Spfg
9131261188Spfg  /* For each __block declared variable must generate call to:
9132261188Spfg   _Block_object_dispose(_src->myImportedClosure, BLOCK_FIELD_IS_BYREF[|BLOCK_FIELD_IS_WEAK])
9133261188Spfg   */
9134261188Spfg  for (chain = block_impl->block_byref_decl_list; chain;
9135261188Spfg	chain = TREE_CHAIN (chain))
9136261188Spfg    if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain)))
9137261188Spfg      {
9138261188Spfg	tree call_exp;
9139261188Spfg	 int flag = BLOCK_FIELD_IS_BYREF;
9140261188Spfg	tree p = TREE_VALUE (chain);
9141261188Spfg	tree src_block_component;
9142261188Spfg
9143261188Spfg	src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"),
9144261188Spfg						   DECL_NAME (p));
9145261188Spfg	 if (COPYABLE_WEAK_BLOCK (p))
9146261188Spfg	   flag |= BLOCK_FIELD_IS_WEAK;
9147261188Spfg      /* _Block_object_dispose(_src->myImportedClosure, BLOCK_FIELD_IS_BYREF[|BLOCK_FIELD_IS_WEAK]) */
9148261188Spfg      call_exp = build_block_object_dispose_call_exp (src_block_component, flag);
9149261188Spfg      add_stmt (call_exp);
9150261188Spfg    }
9151261188Spfg
9152261188Spfg  fnbody = c_end_compound_stmt (stmt, true);
9153261188Spfg  add_stmt (fnbody);
9154261188Spfg  finish_function ();
9155261188Spfg  pop_function_context ();
9156261188Spfg  free (arg_info);
9157261188Spfg}
9158261188Spfg
9159261188Spfg/* Parse a block-id.
9160261188Spfg
9161261188Spfg   GNU Extension:
9162261188Spfg
9163261188Spfg   block-id:
9164261188Spfg     specifier-qualifier-list block-declarator
9165261188Spfg
9166261188Spfg   Returns the DECL specified or implied.  */
9167261188Spfg
9168261188Spfgstatic tree
9169261188Spfgc_parser_block_id (c_parser* parser)
9170261188Spfg{
9171261188Spfg  struct c_declspecs *specs = build_null_declspecs ();
9172261188Spfg  struct c_declarator *declarator;
9173261188Spfg  bool dummy = false;
9174261188Spfg
9175261188Spfg  c_parser_declspecs (parser, specs, false, true, true);
9176261188Spfg  if (!specs->declspecs_seen_p)
9177261188Spfg    {
9178261188Spfg      c_parser_error (parser, "expected specifier-qualifier-list");
9179261188Spfg      return NULL;
9180261188Spfg    }
9181261188Spfg  pending_xref_error ();
9182261188Spfg  finish_declspecs (specs);
9183261188Spfg  declarator = c_parser_declarator (parser, specs->type_seen_p,
9184261188Spfg				    C_DTR_BLOCK, &dummy);
9185261188Spfg  if (declarator == NULL)
9186261188Spfg    return NULL;
9187261188Spfg
9188261188Spfg  return grokblockdecl (specs, declarator);
9189261188Spfg}
9190261188Spfg
9191261188Spfg/* Parse a block-literal-expr.
9192261188Spfg
9193261188Spfg   GNU Extension:
9194261188Spfg
9195261188Spfg  block-literal-expr:
9196261188Spfg    ^ parameter-declation-clause exception-specification [opt] compound-statement
9197261188Spfg    ^ block-id compound-statement
9198261188Spfg
9199261188Spfg    It synthesizes the helper function for later generation and builds
9200261188Spfg    the necessary data to represent the block literal where it is
9201261188Spfg    declared.  */
9202261188Spfgstatic tree
9203261188Spfgc_parser_block_literal_expr (c_parser* parser)
9204261188Spfg{
9205261188Spfg  char name [32];
9206261188Spfg  static int global_unique_count;
9207261188Spfg  int unique_count = ++global_unique_count;
9208261188Spfg  tree block_helper_function_decl;
9209261188Spfg  tree expr, body, type, arglist = void_list_node, ftype;
9210261188Spfg  tree self_arg, stmt;
9211261188Spfg  struct c_arg_info *args = NULL;
9212261188Spfg  tree arg_type = void_list_node;
9213261188Spfg  struct block_sema_info *block_impl;
9214261188Spfg  tree tmp;
9215261188Spfg  bool open_paren_seen = false;
9216261188Spfg  tree restype;
9217261188Spfg  tree fnbody, typelist;
9218261188Spfg  tree helper_function_type;
9219261188Spfg  tree block;
9220261188Spfg  /* APPLE LOCAL radar 6185344 */
9221261188Spfg  tree declared_block_return_type = NULL_TREE;
9222261188Spfg  /* APPLE LOCAL radar 6237713 */
9223261188Spfg  tree attributes = NULL_TREE;
9224261188Spfg
9225261188Spfg  c_parser_consume_token (parser); /* eat '^' */
9226261188Spfg
9227261188Spfg  /* APPLE LOCAL begin radar 6237713 */
9228261188Spfg  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
9229261188Spfg    attributes = c_parser_attributes (parser);
9230261188Spfg  /* APPLE LOCAL end radar 6237713 */
9231261188Spfg
9232261188Spfg  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
9233261188Spfg    {
9234261188Spfg      /* Parse the optional argument list */
9235261188Spfg      c_parser_consume_token (parser);
9236261188Spfg      /* Open the scope to collect parameter decls */
9237261188Spfg      push_scope ();
9238261188Spfg      args = c_parser_parms_declarator (parser, true, NULL_TREE);
9239261188Spfg      /* Check for args as it might be NULL due to error. */
9240261188Spfg      if (args)
9241261188Spfg	{
9242261188Spfg	  arglist = args->parms;
9243261188Spfg	  arg_type = args->types;
9244261188Spfg	}
9245261188Spfg      else
9246261188Spfg	{
9247261188Spfg	  pop_scope ();
9248261188Spfg	  return error_mark_node;
9249261188Spfg	}
9250261188Spfg      open_paren_seen = true;
9251261188Spfg      pop_scope ();
9252261188Spfg    }
9253261188Spfg  else if (c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
9254261188Spfg    {
9255261188Spfg      /* Parse user declared return type. */
9256261188Spfg      tree decl;
9257261188Spfg
9258261188Spfg      /* APPLE LOCAL begin radar 6237713 */
9259261188Spfg      if (attributes)
9260261188Spfg	{
9261261188Spfg	  warning (0, "attributes before block type are ignored");
9262261188Spfg	  attributes = NULL_TREE;
9263261188Spfg	}
9264261188Spfg      /* APPLE LOCAL end radar 6237713 */
9265261188Spfg
9266261188Spfg      decl = c_parser_block_id (parser);
9267261188Spfg
9268261188Spfg      if (decl && decl != error_mark_node)
9269261188Spfg	{
9270261188Spfg	  arg_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
9271261188Spfg	  arglist = DECL_ARGUMENTS (decl);
9272261188Spfg	  declared_block_return_type = TREE_TYPE (TREE_TYPE (decl));
9273261188Spfg	}
9274261188Spfg    }
9275261188Spfg
9276261188Spfg  block = begin_block ();
9277261188Spfg
9278261188Spfg  cur_block->arg_info = NULL;
9279261188Spfg  if (declared_block_return_type)
9280261188Spfg    {
9281261188Spfg      cur_block->return_type = TYPE_MAIN_VARIANT (declared_block_return_type);
9282261188Spfg      cur_block->block_has_return_type = true;
9283261188Spfg  }
9284261188Spfg  else
9285261188Spfg    cur_block->return_type = NULL_TREE;
9286261188Spfg
9287261188Spfg  if (args)
9288261188Spfg    cur_block->arg_info = args;
9289261188Spfg  else
9290261188Spfg    cur_block->arg_info = xcalloc (1, sizeof (struct c_arg_info));
9291261188Spfg
9292261188Spfg  if (declared_block_return_type)
9293261188Spfg    {
9294261188Spfg      cur_block->arg_info->parms = arglist;
9295261188Spfg      cur_block->arg_info->types = arg_type;
9296261188Spfg    }
9297261188Spfg
9298261188Spfg  /* Must also build hidden parameter .block_descriptor added to the helper
9299261188Spfg   function, even though we do not know its type yet. */
9300261188Spfg  /* APPLE LOCAL radar 6404979 */
9301261188Spfg  self_arg = build_decl (PARM_DECL, get_identifier (".block_descriptor"),
9302261188Spfg			  ptr_type_node);
9303261188Spfg  TREE_USED (self_arg) = 1;  /* Prevent unused parameter '.block_descriptor' warning. */
9304261188Spfg  TREE_CHAIN (self_arg) = cur_block->arg_info->parms;
9305261188Spfg  cur_block->arg_info->types = tree_cons (NULL_TREE, ptr_type_node, arg_type);
9306261188Spfg  cur_block->arg_info->parms = self_arg;
9307261188Spfg
9308261188Spfg  /* APPLE LOCAL begin radar 6185344 */
9309261188Spfg  /* Build the declaration of the helper function (if we do not know its result
9310261188Spfg     type yet, assume it is 'void'. If user provided it, use it).
9311261188Spfg     Treat this as a nested function and use nested function infrastructure for
9312261188Spfg     its generation. */
9313261188Spfg
9314261188Spfg  ftype = build_function_type ((!cur_block->block_has_return_type
9315261188Spfg			         ? void_type_node : cur_block->return_type),
9316261188Spfg			        cur_block->arg_info->types);
9317261188Spfg  /* APPLE LOCAL end radar 6185344 */
9318261188Spfg  /* APPLE LOCAL radar 6160536 - radar 6411649 */
9319261188Spfg  block_helper_function_decl = build_helper_func_decl (build_block_helper_name (0),
9320261188Spfg			                                  ftype);
9321261188Spfg  DECL_CONTEXT (block_helper_function_decl) = current_function_decl;
9322261188Spfg  cur_block->helper_func_decl = block_helper_function_decl;
9323261188Spfg
9324261188Spfg  push_function_context ();
9325261188Spfg  start_block_helper_function (cur_block->helper_func_decl);
9326261188Spfg  /* Set block's scope to the scope of the helper function's main body.
9327261188Spfg     This is primarily used when nested blocks are declared. */
9328261188Spfg  /* FIXME: Name of objc_get_current_scope needs to get changed. */
9329261188Spfg  cur_block->the_scope = (struct c_scope*)objc_get_current_scope ();
9330261188Spfg
9331261188Spfg  /* Enter parameter list to the scope of the helper function. */
9332261188Spfg  store_parm_decls_from (cur_block->arg_info);
9333261188Spfg
9334261188Spfg  /* APPLE LOCAL begin radar 6237713 */
9335261188Spfg  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
9336261188Spfg    attributes = c_parser_attributes (parser);
9337261188Spfg  /* APPLE LOCAL radar 6246527 */
9338261188Spfg  any_recognized_block_attribute (attributes);
9339261188Spfg  decl_attributes (&cur_block->helper_func_decl, attributes, 0);
9340261188Spfg  /* APPLE LOCAL end radar 6237713 */
9341261188Spfg
9342261188Spfg  /* Start parsing body or expression part of the block literal. */
9343261188Spfg  if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) {
9344261188Spfg    tree save_c_break_label = c_break_label;
9345261188Spfg    tree save_c_cont_label = c_cont_label;
9346261188Spfg    /* Indicate no valid break/continue context by setting these variables
9347261188Spfg     to some non-null, non-label value.  We'll notice and emit the proper
9348261188Spfg     error message in c_finish_bc_stmt.  */
9349261188Spfg    c_break_label = c_cont_label = size_zero_node;
9350261188Spfg    c_parser_consume_token (parser); /* Consure '{'. */
9351261188Spfg    stmt = c_begin_compound_stmt (true);
9352261188Spfg    c_parser_compound_statement_nostart (parser);
9353261188Spfg    c_cont_label = save_c_cont_label;
9354261188Spfg    c_break_label = save_c_break_label;
9355261188Spfg  }
9356261188Spfg  else
9357261188Spfg    {
9358261188Spfg      struct c_expr expr;
9359261188Spfg      stmt = c_begin_compound_stmt (true);
9360261188Spfg      error ("blocks require { }");
9361261188Spfg      expr = c_parser_cast_expression (parser, NULL);
9362261188Spfg      body = expr.value;
9363261188Spfg      if (body == error_mark_node)
9364261188Spfg	return clean_and_exit (block);
9365261188Spfg
9366261188Spfg      if (cur_block->return_type)
9367261188Spfg	{
9368261188Spfg	  error ("return not allowed in block expression literal");
9369261188Spfg	  return clean_and_exit (block);
9370261188Spfg	}
9371261188Spfg      else if (!open_paren_seen)
9372261188Spfg	{
9373261188Spfg	  error ("argument list is required for block expression literals");
9374261188Spfg	  return clean_and_exit (block);
9375261188Spfg	}
9376261188Spfg      else
9377261188Spfg	{
9378261188Spfg	  tree restype = TYPE_MAIN_VARIANT (TREE_TYPE (body));
9379261188Spfg
9380261188Spfg	  add_stmt (body);
9381261188Spfg	  TREE_TYPE (current_function_decl)
9382261188Spfg	    = build_function_type (restype,
9383261188Spfg				   TYPE_ARG_TYPES (TREE_TYPE (current_function_decl)));
9384261188Spfg	  TREE_TYPE (DECL_RESULT (current_function_decl)) = restype;
9385261188Spfg	  relayout_decl (DECL_RESULT (current_function_decl));
9386261188Spfg	  cur_block->return_type = restype;
9387261188Spfg	}
9388261188Spfg    }
9389261188Spfg
9390261188Spfg  cur_block->block_arg_ptr_type =
9391261188Spfg    build_pointer_type (build_block_struct_type (cur_block));
9392261188Spfg
9393261188Spfg  restype = !cur_block->return_type ? void_type_node
9394261188Spfg				    : cur_block->return_type;
9395261188Spfg  if (restype == error_mark_node)
9396261188Spfg    return clean_and_exit (block);
9397261188Spfg
9398261188Spfg  /* Now that we know type of the hidden .block_descriptor argument, fix its type. */
9399261188Spfg  TREE_TYPE (self_arg) = cur_block->block_arg_ptr_type;
9400261188Spfg  DECL_ARG_TYPE (self_arg) = cur_block->block_arg_ptr_type;
9401261188Spfg
9402261188Spfg  /* The DECL_RESULT should already have the correct type by now.  */
9403261188Spfg  gcc_assert (TREE_TYPE (DECL_RESULT (current_function_decl))
9404261188Spfg	      == restype);
9405261188Spfg
9406261188Spfg  cur_block->block_body = stmt;
9407261188Spfg  block_build_prologue (cur_block);
9408261188Spfg
9409261188Spfg  fnbody = c_end_compound_stmt (stmt, true);
9410261188Spfg  add_stmt (fnbody);
9411261188Spfg
9412261188Spfg  /* We are done parsing of the block body. Return type of block is now known.
9413261188Spfg     We also know all we need to know about the helper function. So, fix its
9414261188Spfg    type here. */
9415261188Spfg  /* We moved this here because for global blocks, helper function body is
9416261188Spfg     not nested and is gimplified in call to finish_function() and return type
9417261188Spfg     of the function must be correct. */
9418261188Spfg  ftype = build_function_type (restype, arg_type);
9419261188Spfg  /* Declare helper function; as in:
9420261188Spfg     double helper_1(struct block_1 *ii, int z); */
9421261188Spfg  typelist = TYPE_ARG_TYPES (ftype);
9422261188Spfg  /* (struct block_1 *ii, int z, ...) */
9423261188Spfg  typelist = tree_cons (NULL_TREE, cur_block->block_arg_ptr_type,
9424261188Spfg			 typelist);
9425261188Spfg  helper_function_type = build_function_type (TREE_TYPE (ftype), typelist);
9426261188Spfg  TREE_TYPE (cur_block->helper_func_decl) = helper_function_type;
9427261188Spfg  finish_function ();
9428261188Spfg  pop_function_context ();
9429261188Spfg
9430261188Spfg  /* Build the declaration for copy_helper_block and destroy_helper_block
9431261188Spfg   helper functions for later use. */
9432261188Spfg
9433261188Spfg  if (cur_block->BlockHasCopyDispose)
9434261188Spfg  {
9435261188Spfg    /* void copy_helper_block (struct block*, struct block *); */
9436261188Spfg    tree s_ftype = build_function_type (void_type_node,
9437261188Spfg			                 tree_cons (NULL_TREE, cur_block->block_arg_ptr_type,
9438261188Spfg			                            tree_cons (NULL_TREE,
9439261188Spfg			                                       cur_block->block_arg_ptr_type,
9440261188Spfg			                                       void_list_node)));
9441261188Spfg    sprintf (name, "__copy_helper_block_%d", unique_count);
9442261188Spfg    cur_block->copy_helper_func_decl =
9443261188Spfg    build_helper_func_decl (get_identifier (name), s_ftype);
9444261188Spfg    synth_copy_helper_block_func (cur_block);
9445261188Spfg
9446261188Spfg    /* void destroy_helper_block (struct block*); */
9447261188Spfg    s_ftype = build_function_type (void_type_node,
9448261188Spfg			            tree_cons (NULL_TREE,
9449261188Spfg			                       cur_block->block_arg_ptr_type, void_list_node));
9450261188Spfg    sprintf (name, "__destroy_helper_block_%d", unique_count);
9451261188Spfg    cur_block->destroy_helper_func_decl =
9452261188Spfg    build_helper_func_decl (get_identifier (name), s_ftype);
9453261188Spfg    synth_destroy_helper_block_func (cur_block);
9454261188Spfg  }
9455261188Spfg
9456261188Spfg  block_impl = finish_block (block);
9457261188Spfg
9458261188Spfg  /* Build unqiue name of the temporary used in code gen. */
9459261188Spfg  sprintf (name, "__block_holder_tmp_%d", unique_count);
9460261188Spfg  tmp = build_block_literal_tmp (name, block_impl);
9461261188Spfg  tmp = build_fold_addr_expr (tmp);
9462261188Spfg  type = build_block_pointer_type (ftype);
9463261188Spfg  expr = convert (type, convert (ptr_type_node, tmp));
9464261188Spfg  free (block_impl);
9465261188Spfg  return expr;
9466261188Spfg}
9467261188Spfg/* APPLE LOCAL end radar 5732232 - blocks (C++ ce) */
9468261188Spfg
9469169689Skan#include "gt-c-parser.h"
9470