1*e4b17023SJohn Marino /* Parser for C and Objective-C.
2*e4b17023SJohn Marino Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3*e4b17023SJohn Marino 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011,
4*e4b17023SJohn Marino 2012 Free Software Foundation, Inc.
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino Parser actions based on the old Bison parser; structure somewhat
7*e4b17023SJohn Marino influenced by and fragments based on the C++ parser.
8*e4b17023SJohn Marino
9*e4b17023SJohn Marino This file is part of GCC.
10*e4b17023SJohn Marino
11*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
12*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
13*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
14*e4b17023SJohn Marino version.
15*e4b17023SJohn Marino
16*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
18*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19*e4b17023SJohn Marino for more details.
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
22*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
23*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino /* TODO:
26*e4b17023SJohn Marino
27*e4b17023SJohn Marino Make sure all relevant comments, and all relevant code from all
28*e4b17023SJohn Marino actions, brought over from old parser. Verify exact correspondence
29*e4b17023SJohn Marino of syntax accepted.
30*e4b17023SJohn Marino
31*e4b17023SJohn Marino Add testcases covering every input symbol in every state in old and
32*e4b17023SJohn Marino new parsers.
33*e4b17023SJohn Marino
34*e4b17023SJohn Marino Include full syntax for GNU C, including erroneous cases accepted
35*e4b17023SJohn Marino with error messages, in syntax productions in comments.
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino Make more diagnostics in the front end generally take an explicit
38*e4b17023SJohn Marino location rather than implicitly using input_location. */
39*e4b17023SJohn Marino
40*e4b17023SJohn Marino #include "config.h"
41*e4b17023SJohn Marino #include "system.h"
42*e4b17023SJohn Marino #include "coretypes.h"
43*e4b17023SJohn Marino #include "tm.h" /* For rtl.h: needs enum reg_class. */
44*e4b17023SJohn Marino #include "tree.h"
45*e4b17023SJohn Marino #include "langhooks.h"
46*e4b17023SJohn Marino #include "input.h"
47*e4b17023SJohn Marino #include "cpplib.h"
48*e4b17023SJohn Marino #include "timevar.h"
49*e4b17023SJohn Marino #include "c-family/c-pragma.h"
50*e4b17023SJohn Marino #include "c-tree.h"
51*e4b17023SJohn Marino #include "flags.h"
52*e4b17023SJohn Marino #include "output.h"
53*e4b17023SJohn Marino #include "ggc.h"
54*e4b17023SJohn Marino #include "c-family/c-common.h"
55*e4b17023SJohn Marino #include "c-family/c-objc.h"
56*e4b17023SJohn Marino #include "vec.h"
57*e4b17023SJohn Marino #include "target.h"
58*e4b17023SJohn Marino #include "cgraph.h"
59*e4b17023SJohn Marino #include "plugin.h"
60*e4b17023SJohn Marino
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino /* Initialization routine for this file. */
63*e4b17023SJohn Marino
64*e4b17023SJohn Marino void
c_parse_init(void)65*e4b17023SJohn Marino c_parse_init (void)
66*e4b17023SJohn Marino {
67*e4b17023SJohn Marino /* The only initialization required is of the reserved word
68*e4b17023SJohn Marino identifiers. */
69*e4b17023SJohn Marino unsigned int i;
70*e4b17023SJohn Marino tree id;
71*e4b17023SJohn Marino int mask = 0;
72*e4b17023SJohn Marino
73*e4b17023SJohn Marino /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
74*e4b17023SJohn Marino the c_token structure. */
75*e4b17023SJohn Marino gcc_assert (RID_MAX <= 255);
76*e4b17023SJohn Marino
77*e4b17023SJohn Marino mask |= D_CXXONLY;
78*e4b17023SJohn Marino if (!flag_isoc99)
79*e4b17023SJohn Marino mask |= D_C99;
80*e4b17023SJohn Marino if (flag_no_asm)
81*e4b17023SJohn Marino {
82*e4b17023SJohn Marino mask |= D_ASM | D_EXT;
83*e4b17023SJohn Marino if (!flag_isoc99)
84*e4b17023SJohn Marino mask |= D_EXT89;
85*e4b17023SJohn Marino }
86*e4b17023SJohn Marino if (!c_dialect_objc ())
87*e4b17023SJohn Marino mask |= D_OBJC | D_CXX_OBJC;
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino ridpointers = ggc_alloc_cleared_vec_tree ((int) RID_MAX);
90*e4b17023SJohn Marino for (i = 0; i < num_c_common_reswords; i++)
91*e4b17023SJohn Marino {
92*e4b17023SJohn Marino /* If a keyword is disabled, do not enter it into the table
93*e4b17023SJohn Marino and so create a canonical spelling that isn't a keyword. */
94*e4b17023SJohn Marino if (c_common_reswords[i].disable & mask)
95*e4b17023SJohn Marino {
96*e4b17023SJohn Marino if (warn_cxx_compat
97*e4b17023SJohn Marino && (c_common_reswords[i].disable & D_CXXWARN))
98*e4b17023SJohn Marino {
99*e4b17023SJohn Marino id = get_identifier (c_common_reswords[i].word);
100*e4b17023SJohn Marino C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
101*e4b17023SJohn Marino C_IS_RESERVED_WORD (id) = 1;
102*e4b17023SJohn Marino }
103*e4b17023SJohn Marino continue;
104*e4b17023SJohn Marino }
105*e4b17023SJohn Marino
106*e4b17023SJohn Marino id = get_identifier (c_common_reswords[i].word);
107*e4b17023SJohn Marino C_SET_RID_CODE (id, c_common_reswords[i].rid);
108*e4b17023SJohn Marino C_IS_RESERVED_WORD (id) = 1;
109*e4b17023SJohn Marino ridpointers [(int) c_common_reswords[i].rid] = id;
110*e4b17023SJohn Marino }
111*e4b17023SJohn Marino }
112*e4b17023SJohn Marino
113*e4b17023SJohn Marino /* The C lexer intermediates between the lexer in cpplib and c-lex.c
114*e4b17023SJohn Marino and the C parser. Unlike the C++ lexer, the parser structure
115*e4b17023SJohn Marino stores the lexer information instead of using a separate structure.
116*e4b17023SJohn Marino Identifiers are separated into ordinary identifiers, type names,
117*e4b17023SJohn Marino keywords and some other Objective-C types of identifiers, and some
118*e4b17023SJohn Marino look-ahead is maintained.
119*e4b17023SJohn Marino
120*e4b17023SJohn Marino ??? It might be a good idea to lex the whole file up front (as for
121*e4b17023SJohn Marino C++). It would then be possible to share more of the C and C++
122*e4b17023SJohn Marino lexer code, if desired. */
123*e4b17023SJohn Marino
124*e4b17023SJohn Marino /* The following local token type is used. */
125*e4b17023SJohn Marino
126*e4b17023SJohn Marino /* A keyword. */
127*e4b17023SJohn Marino #define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
128*e4b17023SJohn Marino
129*e4b17023SJohn Marino /* More information about the type of a CPP_NAME token. */
130*e4b17023SJohn Marino typedef enum c_id_kind {
131*e4b17023SJohn Marino /* An ordinary identifier. */
132*e4b17023SJohn Marino C_ID_ID,
133*e4b17023SJohn Marino /* An identifier declared as a typedef name. */
134*e4b17023SJohn Marino C_ID_TYPENAME,
135*e4b17023SJohn Marino /* An identifier declared as an Objective-C class name. */
136*e4b17023SJohn Marino C_ID_CLASSNAME,
137*e4b17023SJohn Marino /* An address space identifier. */
138*e4b17023SJohn Marino C_ID_ADDRSPACE,
139*e4b17023SJohn Marino /* Not an identifier. */
140*e4b17023SJohn Marino C_ID_NONE
141*e4b17023SJohn Marino } c_id_kind;
142*e4b17023SJohn Marino
143*e4b17023SJohn Marino /* A single C token after string literal concatenation and conversion
144*e4b17023SJohn Marino of preprocessing tokens to tokens. */
145*e4b17023SJohn Marino typedef struct GTY (()) c_token {
146*e4b17023SJohn Marino /* The kind of token. */
147*e4b17023SJohn Marino ENUM_BITFIELD (cpp_ttype) type : 8;
148*e4b17023SJohn Marino /* If this token is a CPP_NAME, this value indicates whether also
149*e4b17023SJohn Marino declared as some kind of type. Otherwise, it is C_ID_NONE. */
150*e4b17023SJohn Marino ENUM_BITFIELD (c_id_kind) id_kind : 8;
151*e4b17023SJohn Marino /* If this token is a keyword, this value indicates which keyword.
152*e4b17023SJohn Marino Otherwise, this value is RID_MAX. */
153*e4b17023SJohn Marino ENUM_BITFIELD (rid) keyword : 8;
154*e4b17023SJohn Marino /* If this token is a CPP_PRAGMA, this indicates the pragma that
155*e4b17023SJohn Marino was seen. Otherwise it is PRAGMA_NONE. */
156*e4b17023SJohn Marino ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
157*e4b17023SJohn Marino /* The location at which this token was found. */
158*e4b17023SJohn Marino location_t location;
159*e4b17023SJohn Marino /* The value associated with this token, if any. */
160*e4b17023SJohn Marino tree value;
161*e4b17023SJohn Marino } c_token;
162*e4b17023SJohn Marino
163*e4b17023SJohn Marino /* A parser structure recording information about the state and
164*e4b17023SJohn Marino context of parsing. Includes lexer information with up to two
165*e4b17023SJohn Marino tokens of look-ahead; more are not needed for C. */
166*e4b17023SJohn Marino typedef struct GTY(()) c_parser {
167*e4b17023SJohn Marino /* The look-ahead tokens. */
168*e4b17023SJohn Marino c_token tokens[2];
169*e4b17023SJohn Marino /* How many look-ahead tokens are available (0, 1 or 2). */
170*e4b17023SJohn Marino short tokens_avail;
171*e4b17023SJohn Marino /* True if a syntax error is being recovered from; false otherwise.
172*e4b17023SJohn Marino c_parser_error sets this flag. It should clear this flag when
173*e4b17023SJohn Marino enough tokens have been consumed to recover from the error. */
174*e4b17023SJohn Marino BOOL_BITFIELD error : 1;
175*e4b17023SJohn Marino /* True if we're processing a pragma, and shouldn't automatically
176*e4b17023SJohn Marino consume CPP_PRAGMA_EOL. */
177*e4b17023SJohn Marino BOOL_BITFIELD in_pragma : 1;
178*e4b17023SJohn Marino /* True if we're parsing the outermost block of an if statement. */
179*e4b17023SJohn Marino BOOL_BITFIELD in_if_block : 1;
180*e4b17023SJohn Marino /* True if we want to lex an untranslated string. */
181*e4b17023SJohn Marino BOOL_BITFIELD lex_untranslated_string : 1;
182*e4b17023SJohn Marino
183*e4b17023SJohn Marino /* Objective-C specific parser/lexer information. */
184*e4b17023SJohn Marino
185*e4b17023SJohn Marino /* True if we are in a context where the Objective-C "PQ" keywords
186*e4b17023SJohn Marino are considered keywords. */
187*e4b17023SJohn Marino BOOL_BITFIELD objc_pq_context : 1;
188*e4b17023SJohn Marino /* True if we are parsing a (potential) Objective-C foreach
189*e4b17023SJohn Marino statement. This is set to true after we parsed 'for (' and while
190*e4b17023SJohn Marino we wait for 'in' or ';' to decide if it's a standard C for loop or an
191*e4b17023SJohn Marino Objective-C foreach loop. */
192*e4b17023SJohn Marino BOOL_BITFIELD objc_could_be_foreach_context : 1;
193*e4b17023SJohn Marino /* The following flag is needed to contextualize Objective-C lexical
194*e4b17023SJohn Marino analysis. In some cases (e.g., 'int NSObject;'), it is
195*e4b17023SJohn Marino undesirable to bind an identifier to an Objective-C class, even
196*e4b17023SJohn Marino if a class with that name exists. */
197*e4b17023SJohn Marino BOOL_BITFIELD objc_need_raw_identifier : 1;
198*e4b17023SJohn Marino /* Nonzero if we're processing a __transaction statement. The value
199*e4b17023SJohn Marino is 1 | TM_STMT_ATTR_*. */
200*e4b17023SJohn Marino unsigned int in_transaction : 4;
201*e4b17023SJohn Marino /* True if we are in a context where the Objective-C "Property attribute"
202*e4b17023SJohn Marino keywords are valid. */
203*e4b17023SJohn Marino BOOL_BITFIELD objc_property_attr_context : 1;
204*e4b17023SJohn Marino } c_parser;
205*e4b17023SJohn Marino
206*e4b17023SJohn Marino
207*e4b17023SJohn Marino /* The actual parser and external interface. ??? Does this need to be
208*e4b17023SJohn Marino garbage-collected? */
209*e4b17023SJohn Marino
210*e4b17023SJohn Marino static GTY (()) c_parser *the_parser;
211*e4b17023SJohn Marino
212*e4b17023SJohn Marino /* Read in and lex a single token, storing it in *TOKEN. */
213*e4b17023SJohn Marino
214*e4b17023SJohn Marino static void
c_lex_one_token(c_parser * parser,c_token * token)215*e4b17023SJohn Marino c_lex_one_token (c_parser *parser, c_token *token)
216*e4b17023SJohn Marino {
217*e4b17023SJohn Marino timevar_push (TV_LEX);
218*e4b17023SJohn Marino
219*e4b17023SJohn Marino token->type = c_lex_with_flags (&token->value, &token->location, NULL,
220*e4b17023SJohn Marino (parser->lex_untranslated_string
221*e4b17023SJohn Marino ? C_LEX_STRING_NO_TRANSLATE : 0));
222*e4b17023SJohn Marino token->id_kind = C_ID_NONE;
223*e4b17023SJohn Marino token->keyword = RID_MAX;
224*e4b17023SJohn Marino token->pragma_kind = PRAGMA_NONE;
225*e4b17023SJohn Marino
226*e4b17023SJohn Marino switch (token->type)
227*e4b17023SJohn Marino {
228*e4b17023SJohn Marino case CPP_NAME:
229*e4b17023SJohn Marino {
230*e4b17023SJohn Marino tree decl;
231*e4b17023SJohn Marino
232*e4b17023SJohn Marino bool objc_force_identifier = parser->objc_need_raw_identifier;
233*e4b17023SJohn Marino if (c_dialect_objc ())
234*e4b17023SJohn Marino parser->objc_need_raw_identifier = false;
235*e4b17023SJohn Marino
236*e4b17023SJohn Marino if (C_IS_RESERVED_WORD (token->value))
237*e4b17023SJohn Marino {
238*e4b17023SJohn Marino enum rid rid_code = C_RID_CODE (token->value);
239*e4b17023SJohn Marino
240*e4b17023SJohn Marino if (rid_code == RID_CXX_COMPAT_WARN)
241*e4b17023SJohn Marino {
242*e4b17023SJohn Marino warning_at (token->location,
243*e4b17023SJohn Marino OPT_Wc___compat,
244*e4b17023SJohn Marino "identifier %qE conflicts with C++ keyword",
245*e4b17023SJohn Marino token->value);
246*e4b17023SJohn Marino }
247*e4b17023SJohn Marino else if (rid_code >= RID_FIRST_ADDR_SPACE
248*e4b17023SJohn Marino && rid_code <= RID_LAST_ADDR_SPACE)
249*e4b17023SJohn Marino {
250*e4b17023SJohn Marino token->id_kind = C_ID_ADDRSPACE;
251*e4b17023SJohn Marino token->keyword = rid_code;
252*e4b17023SJohn Marino break;
253*e4b17023SJohn Marino }
254*e4b17023SJohn Marino else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
255*e4b17023SJohn Marino {
256*e4b17023SJohn Marino /* We found an Objective-C "pq" keyword (in, out,
257*e4b17023SJohn Marino inout, bycopy, byref, oneway). They need special
258*e4b17023SJohn Marino care because the interpretation depends on the
259*e4b17023SJohn Marino context. */
260*e4b17023SJohn Marino if (parser->objc_pq_context)
261*e4b17023SJohn Marino {
262*e4b17023SJohn Marino token->type = CPP_KEYWORD;
263*e4b17023SJohn Marino token->keyword = rid_code;
264*e4b17023SJohn Marino break;
265*e4b17023SJohn Marino }
266*e4b17023SJohn Marino else if (parser->objc_could_be_foreach_context
267*e4b17023SJohn Marino && rid_code == RID_IN)
268*e4b17023SJohn Marino {
269*e4b17023SJohn Marino /* We are in Objective-C, inside a (potential)
270*e4b17023SJohn Marino foreach context (which means after having
271*e4b17023SJohn Marino parsed 'for (', but before having parsed ';'),
272*e4b17023SJohn Marino and we found 'in'. We consider it the keyword
273*e4b17023SJohn Marino which terminates the declaration at the
274*e4b17023SJohn Marino beginning of a foreach-statement. Note that
275*e4b17023SJohn Marino this means you can't use 'in' for anything else
276*e4b17023SJohn Marino in that context; in particular, in Objective-C
277*e4b17023SJohn Marino you can't use 'in' as the name of the running
278*e4b17023SJohn Marino variable in a C for loop. We could potentially
279*e4b17023SJohn Marino try to add code here to disambiguate, but it
280*e4b17023SJohn Marino seems a reasonable limitation. */
281*e4b17023SJohn Marino token->type = CPP_KEYWORD;
282*e4b17023SJohn Marino token->keyword = rid_code;
283*e4b17023SJohn Marino break;
284*e4b17023SJohn Marino }
285*e4b17023SJohn Marino /* Else, "pq" keywords outside of the "pq" context are
286*e4b17023SJohn Marino not keywords, and we fall through to the code for
287*e4b17023SJohn Marino normal tokens. */
288*e4b17023SJohn Marino }
289*e4b17023SJohn Marino else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
290*e4b17023SJohn Marino {
291*e4b17023SJohn Marino /* We found an Objective-C "property attribute"
292*e4b17023SJohn Marino keyword (getter, setter, readonly, etc). These are
293*e4b17023SJohn Marino only valid in the property context. */
294*e4b17023SJohn Marino if (parser->objc_property_attr_context)
295*e4b17023SJohn Marino {
296*e4b17023SJohn Marino token->type = CPP_KEYWORD;
297*e4b17023SJohn Marino token->keyword = rid_code;
298*e4b17023SJohn Marino break;
299*e4b17023SJohn Marino }
300*e4b17023SJohn Marino /* Else they are not special keywords.
301*e4b17023SJohn Marino */
302*e4b17023SJohn Marino }
303*e4b17023SJohn Marino else if (c_dialect_objc ()
304*e4b17023SJohn Marino && (OBJC_IS_AT_KEYWORD (rid_code)
305*e4b17023SJohn Marino || OBJC_IS_CXX_KEYWORD (rid_code)))
306*e4b17023SJohn Marino {
307*e4b17023SJohn Marino /* We found one of the Objective-C "@" keywords (defs,
308*e4b17023SJohn Marino selector, synchronized, etc) or one of the
309*e4b17023SJohn Marino Objective-C "cxx" keywords (class, private,
310*e4b17023SJohn Marino protected, public, try, catch, throw) without a
311*e4b17023SJohn Marino preceding '@' sign. Do nothing and fall through to
312*e4b17023SJohn Marino the code for normal tokens (in C++ we would still
313*e4b17023SJohn Marino consider the CXX ones keywords, but not in C). */
314*e4b17023SJohn Marino ;
315*e4b17023SJohn Marino }
316*e4b17023SJohn Marino else
317*e4b17023SJohn Marino {
318*e4b17023SJohn Marino token->type = CPP_KEYWORD;
319*e4b17023SJohn Marino token->keyword = rid_code;
320*e4b17023SJohn Marino break;
321*e4b17023SJohn Marino }
322*e4b17023SJohn Marino }
323*e4b17023SJohn Marino
324*e4b17023SJohn Marino decl = lookup_name (token->value);
325*e4b17023SJohn Marino if (decl)
326*e4b17023SJohn Marino {
327*e4b17023SJohn Marino if (TREE_CODE (decl) == TYPE_DECL)
328*e4b17023SJohn Marino {
329*e4b17023SJohn Marino token->id_kind = C_ID_TYPENAME;
330*e4b17023SJohn Marino break;
331*e4b17023SJohn Marino }
332*e4b17023SJohn Marino }
333*e4b17023SJohn Marino else if (c_dialect_objc ())
334*e4b17023SJohn Marino {
335*e4b17023SJohn Marino tree objc_interface_decl = objc_is_class_name (token->value);
336*e4b17023SJohn Marino /* Objective-C class names are in the same namespace as
337*e4b17023SJohn Marino variables and typedefs, and hence are shadowed by local
338*e4b17023SJohn Marino declarations. */
339*e4b17023SJohn Marino if (objc_interface_decl
340*e4b17023SJohn Marino && (!objc_force_identifier || global_bindings_p ()))
341*e4b17023SJohn Marino {
342*e4b17023SJohn Marino token->value = objc_interface_decl;
343*e4b17023SJohn Marino token->id_kind = C_ID_CLASSNAME;
344*e4b17023SJohn Marino break;
345*e4b17023SJohn Marino }
346*e4b17023SJohn Marino }
347*e4b17023SJohn Marino token->id_kind = C_ID_ID;
348*e4b17023SJohn Marino }
349*e4b17023SJohn Marino break;
350*e4b17023SJohn Marino case CPP_AT_NAME:
351*e4b17023SJohn Marino /* This only happens in Objective-C; it must be a keyword. */
352*e4b17023SJohn Marino token->type = CPP_KEYWORD;
353*e4b17023SJohn Marino switch (C_RID_CODE (token->value))
354*e4b17023SJohn Marino {
355*e4b17023SJohn Marino /* Replace 'class' with '@class', 'private' with '@private',
356*e4b17023SJohn Marino etc. This prevents confusion with the C++ keyword
357*e4b17023SJohn Marino 'class', and makes the tokens consistent with other
358*e4b17023SJohn Marino Objective-C 'AT' keywords. For example '@class' is
359*e4b17023SJohn Marino reported as RID_AT_CLASS which is consistent with
360*e4b17023SJohn Marino '@synchronized', which is reported as
361*e4b17023SJohn Marino RID_AT_SYNCHRONIZED.
362*e4b17023SJohn Marino */
363*e4b17023SJohn Marino case RID_CLASS: token->keyword = RID_AT_CLASS; break;
364*e4b17023SJohn Marino case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
365*e4b17023SJohn Marino case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
366*e4b17023SJohn Marino case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
367*e4b17023SJohn Marino case RID_THROW: token->keyword = RID_AT_THROW; break;
368*e4b17023SJohn Marino case RID_TRY: token->keyword = RID_AT_TRY; break;
369*e4b17023SJohn Marino case RID_CATCH: token->keyword = RID_AT_CATCH; break;
370*e4b17023SJohn Marino default: token->keyword = C_RID_CODE (token->value);
371*e4b17023SJohn Marino }
372*e4b17023SJohn Marino break;
373*e4b17023SJohn Marino case CPP_COLON:
374*e4b17023SJohn Marino case CPP_COMMA:
375*e4b17023SJohn Marino case CPP_CLOSE_PAREN:
376*e4b17023SJohn Marino case CPP_SEMICOLON:
377*e4b17023SJohn Marino /* These tokens may affect the interpretation of any identifiers
378*e4b17023SJohn Marino following, if doing Objective-C. */
379*e4b17023SJohn Marino if (c_dialect_objc ())
380*e4b17023SJohn Marino parser->objc_need_raw_identifier = false;
381*e4b17023SJohn Marino break;
382*e4b17023SJohn Marino case CPP_PRAGMA:
383*e4b17023SJohn Marino /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
384*e4b17023SJohn Marino token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
385*e4b17023SJohn Marino token->value = NULL;
386*e4b17023SJohn Marino break;
387*e4b17023SJohn Marino default:
388*e4b17023SJohn Marino break;
389*e4b17023SJohn Marino }
390*e4b17023SJohn Marino timevar_pop (TV_LEX);
391*e4b17023SJohn Marino }
392*e4b17023SJohn Marino
393*e4b17023SJohn Marino /* Return a pointer to the next token from PARSER, reading it in if
394*e4b17023SJohn Marino necessary. */
395*e4b17023SJohn Marino
396*e4b17023SJohn Marino static inline c_token *
c_parser_peek_token(c_parser * parser)397*e4b17023SJohn Marino c_parser_peek_token (c_parser *parser)
398*e4b17023SJohn Marino {
399*e4b17023SJohn Marino if (parser->tokens_avail == 0)
400*e4b17023SJohn Marino {
401*e4b17023SJohn Marino c_lex_one_token (parser, &parser->tokens[0]);
402*e4b17023SJohn Marino parser->tokens_avail = 1;
403*e4b17023SJohn Marino }
404*e4b17023SJohn Marino return &parser->tokens[0];
405*e4b17023SJohn Marino }
406*e4b17023SJohn Marino
407*e4b17023SJohn Marino /* Return true if the next token from PARSER has the indicated
408*e4b17023SJohn Marino TYPE. */
409*e4b17023SJohn Marino
410*e4b17023SJohn Marino static inline bool
c_parser_next_token_is(c_parser * parser,enum cpp_ttype type)411*e4b17023SJohn Marino c_parser_next_token_is (c_parser *parser, enum cpp_ttype type)
412*e4b17023SJohn Marino {
413*e4b17023SJohn Marino return c_parser_peek_token (parser)->type == type;
414*e4b17023SJohn Marino }
415*e4b17023SJohn Marino
416*e4b17023SJohn Marino /* Return true if the next token from PARSER does not have the
417*e4b17023SJohn Marino indicated TYPE. */
418*e4b17023SJohn Marino
419*e4b17023SJohn Marino static inline bool
c_parser_next_token_is_not(c_parser * parser,enum cpp_ttype type)420*e4b17023SJohn Marino c_parser_next_token_is_not (c_parser *parser, enum cpp_ttype type)
421*e4b17023SJohn Marino {
422*e4b17023SJohn Marino return !c_parser_next_token_is (parser, type);
423*e4b17023SJohn Marino }
424*e4b17023SJohn Marino
425*e4b17023SJohn Marino /* Return true if the next token from PARSER is the indicated
426*e4b17023SJohn Marino KEYWORD. */
427*e4b17023SJohn Marino
428*e4b17023SJohn Marino static inline bool
c_parser_next_token_is_keyword(c_parser * parser,enum rid keyword)429*e4b17023SJohn Marino c_parser_next_token_is_keyword (c_parser *parser, enum rid keyword)
430*e4b17023SJohn Marino {
431*e4b17023SJohn Marino return c_parser_peek_token (parser)->keyword == keyword;
432*e4b17023SJohn Marino }
433*e4b17023SJohn Marino
434*e4b17023SJohn Marino /* Return a pointer to the next-but-one token from PARSER, reading it
435*e4b17023SJohn Marino in if necessary. The next token is already read in. */
436*e4b17023SJohn Marino
437*e4b17023SJohn Marino static c_token *
c_parser_peek_2nd_token(c_parser * parser)438*e4b17023SJohn Marino c_parser_peek_2nd_token (c_parser *parser)
439*e4b17023SJohn Marino {
440*e4b17023SJohn Marino if (parser->tokens_avail >= 2)
441*e4b17023SJohn Marino return &parser->tokens[1];
442*e4b17023SJohn Marino gcc_assert (parser->tokens_avail == 1);
443*e4b17023SJohn Marino gcc_assert (parser->tokens[0].type != CPP_EOF);
444*e4b17023SJohn Marino gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
445*e4b17023SJohn Marino c_lex_one_token (parser, &parser->tokens[1]);
446*e4b17023SJohn Marino parser->tokens_avail = 2;
447*e4b17023SJohn Marino return &parser->tokens[1];
448*e4b17023SJohn Marino }
449*e4b17023SJohn Marino
450*e4b17023SJohn Marino /* Return true if TOKEN can start a type name,
451*e4b17023SJohn Marino false otherwise. */
452*e4b17023SJohn Marino static bool
c_token_starts_typename(c_token * token)453*e4b17023SJohn Marino c_token_starts_typename (c_token *token)
454*e4b17023SJohn Marino {
455*e4b17023SJohn Marino switch (token->type)
456*e4b17023SJohn Marino {
457*e4b17023SJohn Marino case CPP_NAME:
458*e4b17023SJohn Marino switch (token->id_kind)
459*e4b17023SJohn Marino {
460*e4b17023SJohn Marino case C_ID_ID:
461*e4b17023SJohn Marino return false;
462*e4b17023SJohn Marino case C_ID_ADDRSPACE:
463*e4b17023SJohn Marino return true;
464*e4b17023SJohn Marino case C_ID_TYPENAME:
465*e4b17023SJohn Marino return true;
466*e4b17023SJohn Marino case C_ID_CLASSNAME:
467*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
468*e4b17023SJohn Marino return true;
469*e4b17023SJohn Marino default:
470*e4b17023SJohn Marino gcc_unreachable ();
471*e4b17023SJohn Marino }
472*e4b17023SJohn Marino case CPP_KEYWORD:
473*e4b17023SJohn Marino switch (token->keyword)
474*e4b17023SJohn Marino {
475*e4b17023SJohn Marino case RID_UNSIGNED:
476*e4b17023SJohn Marino case RID_LONG:
477*e4b17023SJohn Marino case RID_INT128:
478*e4b17023SJohn Marino case RID_SHORT:
479*e4b17023SJohn Marino case RID_SIGNED:
480*e4b17023SJohn Marino case RID_COMPLEX:
481*e4b17023SJohn Marino case RID_INT:
482*e4b17023SJohn Marino case RID_CHAR:
483*e4b17023SJohn Marino case RID_FLOAT:
484*e4b17023SJohn Marino case RID_DOUBLE:
485*e4b17023SJohn Marino case RID_VOID:
486*e4b17023SJohn Marino case RID_DFLOAT32:
487*e4b17023SJohn Marino case RID_DFLOAT64:
488*e4b17023SJohn Marino case RID_DFLOAT128:
489*e4b17023SJohn Marino case RID_BOOL:
490*e4b17023SJohn Marino case RID_ENUM:
491*e4b17023SJohn Marino case RID_STRUCT:
492*e4b17023SJohn Marino case RID_UNION:
493*e4b17023SJohn Marino case RID_TYPEOF:
494*e4b17023SJohn Marino case RID_CONST:
495*e4b17023SJohn Marino case RID_VOLATILE:
496*e4b17023SJohn Marino case RID_RESTRICT:
497*e4b17023SJohn Marino case RID_ATTRIBUTE:
498*e4b17023SJohn Marino case RID_FRACT:
499*e4b17023SJohn Marino case RID_ACCUM:
500*e4b17023SJohn Marino case RID_SAT:
501*e4b17023SJohn Marino return true;
502*e4b17023SJohn Marino default:
503*e4b17023SJohn Marino return false;
504*e4b17023SJohn Marino }
505*e4b17023SJohn Marino case CPP_LESS:
506*e4b17023SJohn Marino if (c_dialect_objc ())
507*e4b17023SJohn Marino return true;
508*e4b17023SJohn Marino return false;
509*e4b17023SJohn Marino default:
510*e4b17023SJohn Marino return false;
511*e4b17023SJohn Marino }
512*e4b17023SJohn Marino }
513*e4b17023SJohn Marino
514*e4b17023SJohn Marino enum c_lookahead_kind {
515*e4b17023SJohn Marino /* Always treat unknown identifiers as typenames. */
516*e4b17023SJohn Marino cla_prefer_type,
517*e4b17023SJohn Marino
518*e4b17023SJohn Marino /* Could be parsing a nonabstract declarator. Only treat an identifier
519*e4b17023SJohn Marino as a typename if followed by another identifier or a star. */
520*e4b17023SJohn Marino cla_nonabstract_decl,
521*e4b17023SJohn Marino
522*e4b17023SJohn Marino /* Never treat identifiers as typenames. */
523*e4b17023SJohn Marino cla_prefer_id
524*e4b17023SJohn Marino };
525*e4b17023SJohn Marino
526*e4b17023SJohn Marino /* Return true if the next token from PARSER can start a type name,
527*e4b17023SJohn Marino false otherwise. LA specifies how to do lookahead in order to
528*e4b17023SJohn Marino detect unknown type names. If unsure, pick CLA_PREFER_ID. */
529*e4b17023SJohn Marino
530*e4b17023SJohn Marino static inline bool
c_parser_next_tokens_start_typename(c_parser * parser,enum c_lookahead_kind la)531*e4b17023SJohn Marino c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
532*e4b17023SJohn Marino {
533*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
534*e4b17023SJohn Marino if (c_token_starts_typename (token))
535*e4b17023SJohn Marino return true;
536*e4b17023SJohn Marino
537*e4b17023SJohn Marino /* Try a bit harder to detect an unknown typename. */
538*e4b17023SJohn Marino if (la != cla_prefer_id
539*e4b17023SJohn Marino && token->type == CPP_NAME
540*e4b17023SJohn Marino && token->id_kind == C_ID_ID
541*e4b17023SJohn Marino
542*e4b17023SJohn Marino /* Do not try too hard when we could have "object in array". */
543*e4b17023SJohn Marino && !parser->objc_could_be_foreach_context
544*e4b17023SJohn Marino
545*e4b17023SJohn Marino && (la == cla_prefer_type
546*e4b17023SJohn Marino || c_parser_peek_2nd_token (parser)->type == CPP_NAME
547*e4b17023SJohn Marino || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
548*e4b17023SJohn Marino
549*e4b17023SJohn Marino /* Only unknown identifiers. */
550*e4b17023SJohn Marino && !lookup_name (token->value))
551*e4b17023SJohn Marino return true;
552*e4b17023SJohn Marino
553*e4b17023SJohn Marino return false;
554*e4b17023SJohn Marino }
555*e4b17023SJohn Marino
556*e4b17023SJohn Marino /* Return true if TOKEN is a type qualifier, false otherwise. */
557*e4b17023SJohn Marino static bool
c_token_is_qualifier(c_token * token)558*e4b17023SJohn Marino c_token_is_qualifier (c_token *token)
559*e4b17023SJohn Marino {
560*e4b17023SJohn Marino switch (token->type)
561*e4b17023SJohn Marino {
562*e4b17023SJohn Marino case CPP_NAME:
563*e4b17023SJohn Marino switch (token->id_kind)
564*e4b17023SJohn Marino {
565*e4b17023SJohn Marino case C_ID_ADDRSPACE:
566*e4b17023SJohn Marino return true;
567*e4b17023SJohn Marino default:
568*e4b17023SJohn Marino return false;
569*e4b17023SJohn Marino }
570*e4b17023SJohn Marino case CPP_KEYWORD:
571*e4b17023SJohn Marino switch (token->keyword)
572*e4b17023SJohn Marino {
573*e4b17023SJohn Marino case RID_CONST:
574*e4b17023SJohn Marino case RID_VOLATILE:
575*e4b17023SJohn Marino case RID_RESTRICT:
576*e4b17023SJohn Marino case RID_ATTRIBUTE:
577*e4b17023SJohn Marino return true;
578*e4b17023SJohn Marino default:
579*e4b17023SJohn Marino return false;
580*e4b17023SJohn Marino }
581*e4b17023SJohn Marino case CPP_LESS:
582*e4b17023SJohn Marino return false;
583*e4b17023SJohn Marino default:
584*e4b17023SJohn Marino gcc_unreachable ();
585*e4b17023SJohn Marino }
586*e4b17023SJohn Marino }
587*e4b17023SJohn Marino
588*e4b17023SJohn Marino /* Return true if the next token from PARSER is a type qualifier,
589*e4b17023SJohn Marino false otherwise. */
590*e4b17023SJohn Marino static inline bool
c_parser_next_token_is_qualifier(c_parser * parser)591*e4b17023SJohn Marino c_parser_next_token_is_qualifier (c_parser *parser)
592*e4b17023SJohn Marino {
593*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
594*e4b17023SJohn Marino return c_token_is_qualifier (token);
595*e4b17023SJohn Marino }
596*e4b17023SJohn Marino
597*e4b17023SJohn Marino /* Return true if TOKEN can start declaration specifiers, false
598*e4b17023SJohn Marino otherwise. */
599*e4b17023SJohn Marino static bool
c_token_starts_declspecs(c_token * token)600*e4b17023SJohn Marino c_token_starts_declspecs (c_token *token)
601*e4b17023SJohn Marino {
602*e4b17023SJohn Marino switch (token->type)
603*e4b17023SJohn Marino {
604*e4b17023SJohn Marino case CPP_NAME:
605*e4b17023SJohn Marino switch (token->id_kind)
606*e4b17023SJohn Marino {
607*e4b17023SJohn Marino case C_ID_ID:
608*e4b17023SJohn Marino return false;
609*e4b17023SJohn Marino case C_ID_ADDRSPACE:
610*e4b17023SJohn Marino return true;
611*e4b17023SJohn Marino case C_ID_TYPENAME:
612*e4b17023SJohn Marino return true;
613*e4b17023SJohn Marino case C_ID_CLASSNAME:
614*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
615*e4b17023SJohn Marino return true;
616*e4b17023SJohn Marino default:
617*e4b17023SJohn Marino gcc_unreachable ();
618*e4b17023SJohn Marino }
619*e4b17023SJohn Marino case CPP_KEYWORD:
620*e4b17023SJohn Marino switch (token->keyword)
621*e4b17023SJohn Marino {
622*e4b17023SJohn Marino case RID_STATIC:
623*e4b17023SJohn Marino case RID_EXTERN:
624*e4b17023SJohn Marino case RID_REGISTER:
625*e4b17023SJohn Marino case RID_TYPEDEF:
626*e4b17023SJohn Marino case RID_INLINE:
627*e4b17023SJohn Marino case RID_NORETURN:
628*e4b17023SJohn Marino case RID_AUTO:
629*e4b17023SJohn Marino case RID_THREAD:
630*e4b17023SJohn Marino case RID_UNSIGNED:
631*e4b17023SJohn Marino case RID_LONG:
632*e4b17023SJohn Marino case RID_INT128:
633*e4b17023SJohn Marino case RID_SHORT:
634*e4b17023SJohn Marino case RID_SIGNED:
635*e4b17023SJohn Marino case RID_COMPLEX:
636*e4b17023SJohn Marino case RID_INT:
637*e4b17023SJohn Marino case RID_CHAR:
638*e4b17023SJohn Marino case RID_FLOAT:
639*e4b17023SJohn Marino case RID_DOUBLE:
640*e4b17023SJohn Marino case RID_VOID:
641*e4b17023SJohn Marino case RID_DFLOAT32:
642*e4b17023SJohn Marino case RID_DFLOAT64:
643*e4b17023SJohn Marino case RID_DFLOAT128:
644*e4b17023SJohn Marino case RID_BOOL:
645*e4b17023SJohn Marino case RID_ENUM:
646*e4b17023SJohn Marino case RID_STRUCT:
647*e4b17023SJohn Marino case RID_UNION:
648*e4b17023SJohn Marino case RID_TYPEOF:
649*e4b17023SJohn Marino case RID_CONST:
650*e4b17023SJohn Marino case RID_VOLATILE:
651*e4b17023SJohn Marino case RID_RESTRICT:
652*e4b17023SJohn Marino case RID_ATTRIBUTE:
653*e4b17023SJohn Marino case RID_FRACT:
654*e4b17023SJohn Marino case RID_ACCUM:
655*e4b17023SJohn Marino case RID_SAT:
656*e4b17023SJohn Marino case RID_ALIGNAS:
657*e4b17023SJohn Marino return true;
658*e4b17023SJohn Marino default:
659*e4b17023SJohn Marino return false;
660*e4b17023SJohn Marino }
661*e4b17023SJohn Marino case CPP_LESS:
662*e4b17023SJohn Marino if (c_dialect_objc ())
663*e4b17023SJohn Marino return true;
664*e4b17023SJohn Marino return false;
665*e4b17023SJohn Marino default:
666*e4b17023SJohn Marino return false;
667*e4b17023SJohn Marino }
668*e4b17023SJohn Marino }
669*e4b17023SJohn Marino
670*e4b17023SJohn Marino
671*e4b17023SJohn Marino /* Return true if TOKEN can start declaration specifiers or a static
672*e4b17023SJohn Marino assertion, false otherwise. */
673*e4b17023SJohn Marino static bool
c_token_starts_declaration(c_token * token)674*e4b17023SJohn Marino c_token_starts_declaration (c_token *token)
675*e4b17023SJohn Marino {
676*e4b17023SJohn Marino if (c_token_starts_declspecs (token)
677*e4b17023SJohn Marino || token->keyword == RID_STATIC_ASSERT)
678*e4b17023SJohn Marino return true;
679*e4b17023SJohn Marino else
680*e4b17023SJohn Marino return false;
681*e4b17023SJohn Marino }
682*e4b17023SJohn Marino
683*e4b17023SJohn Marino /* Return true if the next token from PARSER can start declaration
684*e4b17023SJohn Marino specifiers, false otherwise. */
685*e4b17023SJohn Marino static inline bool
c_parser_next_token_starts_declspecs(c_parser * parser)686*e4b17023SJohn Marino c_parser_next_token_starts_declspecs (c_parser *parser)
687*e4b17023SJohn Marino {
688*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
689*e4b17023SJohn Marino
690*e4b17023SJohn Marino /* In Objective-C, a classname normally starts a declspecs unless it
691*e4b17023SJohn Marino is immediately followed by a dot. In that case, it is the
692*e4b17023SJohn Marino Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
693*e4b17023SJohn Marino setter/getter on the class. c_token_starts_declspecs() can't
694*e4b17023SJohn Marino differentiate between the two cases because it only checks the
695*e4b17023SJohn Marino current token, so we have a special check here. */
696*e4b17023SJohn Marino if (c_dialect_objc ()
697*e4b17023SJohn Marino && token->type == CPP_NAME
698*e4b17023SJohn Marino && token->id_kind == C_ID_CLASSNAME
699*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
700*e4b17023SJohn Marino return false;
701*e4b17023SJohn Marino
702*e4b17023SJohn Marino return c_token_starts_declspecs (token);
703*e4b17023SJohn Marino }
704*e4b17023SJohn Marino
705*e4b17023SJohn Marino /* Return true if the next tokens from PARSER can start declaration
706*e4b17023SJohn Marino specifiers or a static assertion, false otherwise. */
707*e4b17023SJohn Marino static inline bool
c_parser_next_tokens_start_declaration(c_parser * parser)708*e4b17023SJohn Marino c_parser_next_tokens_start_declaration (c_parser *parser)
709*e4b17023SJohn Marino {
710*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
711*e4b17023SJohn Marino
712*e4b17023SJohn Marino /* Same as above. */
713*e4b17023SJohn Marino if (c_dialect_objc ()
714*e4b17023SJohn Marino && token->type == CPP_NAME
715*e4b17023SJohn Marino && token->id_kind == C_ID_CLASSNAME
716*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
717*e4b17023SJohn Marino return false;
718*e4b17023SJohn Marino
719*e4b17023SJohn Marino /* Labels do not start declarations. */
720*e4b17023SJohn Marino if (token->type == CPP_NAME
721*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
722*e4b17023SJohn Marino return false;
723*e4b17023SJohn Marino
724*e4b17023SJohn Marino if (c_token_starts_declaration (token))
725*e4b17023SJohn Marino return true;
726*e4b17023SJohn Marino
727*e4b17023SJohn Marino if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
728*e4b17023SJohn Marino return true;
729*e4b17023SJohn Marino
730*e4b17023SJohn Marino return false;
731*e4b17023SJohn Marino }
732*e4b17023SJohn Marino
733*e4b17023SJohn Marino /* Consume the next token from PARSER. */
734*e4b17023SJohn Marino
735*e4b17023SJohn Marino static void
c_parser_consume_token(c_parser * parser)736*e4b17023SJohn Marino c_parser_consume_token (c_parser *parser)
737*e4b17023SJohn Marino {
738*e4b17023SJohn Marino gcc_assert (parser->tokens_avail >= 1);
739*e4b17023SJohn Marino gcc_assert (parser->tokens[0].type != CPP_EOF);
740*e4b17023SJohn Marino gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
741*e4b17023SJohn Marino gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
742*e4b17023SJohn Marino if (parser->tokens_avail == 2)
743*e4b17023SJohn Marino parser->tokens[0] = parser->tokens[1];
744*e4b17023SJohn Marino parser->tokens_avail--;
745*e4b17023SJohn Marino }
746*e4b17023SJohn Marino
747*e4b17023SJohn Marino /* Expect the current token to be a #pragma. Consume it and remember
748*e4b17023SJohn Marino that we've begun parsing a pragma. */
749*e4b17023SJohn Marino
750*e4b17023SJohn Marino static void
c_parser_consume_pragma(c_parser * parser)751*e4b17023SJohn Marino c_parser_consume_pragma (c_parser *parser)
752*e4b17023SJohn Marino {
753*e4b17023SJohn Marino gcc_assert (!parser->in_pragma);
754*e4b17023SJohn Marino gcc_assert (parser->tokens_avail >= 1);
755*e4b17023SJohn Marino gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
756*e4b17023SJohn Marino if (parser->tokens_avail == 2)
757*e4b17023SJohn Marino parser->tokens[0] = parser->tokens[1];
758*e4b17023SJohn Marino parser->tokens_avail--;
759*e4b17023SJohn Marino parser->in_pragma = true;
760*e4b17023SJohn Marino }
761*e4b17023SJohn Marino
762*e4b17023SJohn Marino /* Update the globals input_location and in_system_header from
763*e4b17023SJohn Marino TOKEN. */
764*e4b17023SJohn Marino static inline void
c_parser_set_source_position_from_token(c_token * token)765*e4b17023SJohn Marino c_parser_set_source_position_from_token (c_token *token)
766*e4b17023SJohn Marino {
767*e4b17023SJohn Marino if (token->type != CPP_EOF)
768*e4b17023SJohn Marino {
769*e4b17023SJohn Marino input_location = token->location;
770*e4b17023SJohn Marino }
771*e4b17023SJohn Marino }
772*e4b17023SJohn Marino
773*e4b17023SJohn Marino /* Issue a diagnostic of the form
774*e4b17023SJohn Marino FILE:LINE: MESSAGE before TOKEN
775*e4b17023SJohn Marino where TOKEN is the next token in the input stream of PARSER.
776*e4b17023SJohn Marino MESSAGE (specified by the caller) is usually of the form "expected
777*e4b17023SJohn Marino OTHER-TOKEN".
778*e4b17023SJohn Marino
779*e4b17023SJohn Marino Do not issue a diagnostic if still recovering from an error.
780*e4b17023SJohn Marino
781*e4b17023SJohn Marino ??? This is taken from the C++ parser, but building up messages in
782*e4b17023SJohn Marino this way is not i18n-friendly and some other approach should be
783*e4b17023SJohn Marino used. */
784*e4b17023SJohn Marino
785*e4b17023SJohn Marino static void
c_parser_error(c_parser * parser,const char * gmsgid)786*e4b17023SJohn Marino c_parser_error (c_parser *parser, const char *gmsgid)
787*e4b17023SJohn Marino {
788*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
789*e4b17023SJohn Marino if (parser->error)
790*e4b17023SJohn Marino return;
791*e4b17023SJohn Marino parser->error = true;
792*e4b17023SJohn Marino if (!gmsgid)
793*e4b17023SJohn Marino return;
794*e4b17023SJohn Marino /* This diagnostic makes more sense if it is tagged to the line of
795*e4b17023SJohn Marino the token we just peeked at. */
796*e4b17023SJohn Marino c_parser_set_source_position_from_token (token);
797*e4b17023SJohn Marino c_parse_error (gmsgid,
798*e4b17023SJohn Marino /* Because c_parse_error does not understand
799*e4b17023SJohn Marino CPP_KEYWORD, keywords are treated like
800*e4b17023SJohn Marino identifiers. */
801*e4b17023SJohn Marino (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
802*e4b17023SJohn Marino /* ??? The C parser does not save the cpp flags of a
803*e4b17023SJohn Marino token, we need to pass 0 here and we will not get
804*e4b17023SJohn Marino the source spelling of some tokens but rather the
805*e4b17023SJohn Marino canonical spelling. */
806*e4b17023SJohn Marino token->value, /*flags=*/0);
807*e4b17023SJohn Marino }
808*e4b17023SJohn Marino
809*e4b17023SJohn Marino /* If the next token is of the indicated TYPE, consume it. Otherwise,
810*e4b17023SJohn Marino issue the error MSGID. If MSGID is NULL then a message has already
811*e4b17023SJohn Marino been produced and no message will be produced this time. Returns
812*e4b17023SJohn Marino true if found, false otherwise. */
813*e4b17023SJohn Marino
814*e4b17023SJohn Marino static bool
c_parser_require(c_parser * parser,enum cpp_ttype type,const char * msgid)815*e4b17023SJohn Marino c_parser_require (c_parser *parser,
816*e4b17023SJohn Marino enum cpp_ttype type,
817*e4b17023SJohn Marino const char *msgid)
818*e4b17023SJohn Marino {
819*e4b17023SJohn Marino if (c_parser_next_token_is (parser, type))
820*e4b17023SJohn Marino {
821*e4b17023SJohn Marino c_parser_consume_token (parser);
822*e4b17023SJohn Marino return true;
823*e4b17023SJohn Marino }
824*e4b17023SJohn Marino else
825*e4b17023SJohn Marino {
826*e4b17023SJohn Marino c_parser_error (parser, msgid);
827*e4b17023SJohn Marino return false;
828*e4b17023SJohn Marino }
829*e4b17023SJohn Marino }
830*e4b17023SJohn Marino
831*e4b17023SJohn Marino /* If the next token is the indicated keyword, consume it. Otherwise,
832*e4b17023SJohn Marino issue the error MSGID. Returns true if found, false otherwise. */
833*e4b17023SJohn Marino
834*e4b17023SJohn Marino static bool
c_parser_require_keyword(c_parser * parser,enum rid keyword,const char * msgid)835*e4b17023SJohn Marino c_parser_require_keyword (c_parser *parser,
836*e4b17023SJohn Marino enum rid keyword,
837*e4b17023SJohn Marino const char *msgid)
838*e4b17023SJohn Marino {
839*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, keyword))
840*e4b17023SJohn Marino {
841*e4b17023SJohn Marino c_parser_consume_token (parser);
842*e4b17023SJohn Marino return true;
843*e4b17023SJohn Marino }
844*e4b17023SJohn Marino else
845*e4b17023SJohn Marino {
846*e4b17023SJohn Marino c_parser_error (parser, msgid);
847*e4b17023SJohn Marino return false;
848*e4b17023SJohn Marino }
849*e4b17023SJohn Marino }
850*e4b17023SJohn Marino
851*e4b17023SJohn Marino /* Like c_parser_require, except that tokens will be skipped until the
852*e4b17023SJohn Marino desired token is found. An error message is still produced if the
853*e4b17023SJohn Marino next token is not as expected. If MSGID is NULL then a message has
854*e4b17023SJohn Marino already been produced and no message will be produced this
855*e4b17023SJohn Marino time. */
856*e4b17023SJohn Marino
857*e4b17023SJohn Marino static void
c_parser_skip_until_found(c_parser * parser,enum cpp_ttype type,const char * msgid)858*e4b17023SJohn Marino c_parser_skip_until_found (c_parser *parser,
859*e4b17023SJohn Marino enum cpp_ttype type,
860*e4b17023SJohn Marino const char *msgid)
861*e4b17023SJohn Marino {
862*e4b17023SJohn Marino unsigned nesting_depth = 0;
863*e4b17023SJohn Marino
864*e4b17023SJohn Marino if (c_parser_require (parser, type, msgid))
865*e4b17023SJohn Marino return;
866*e4b17023SJohn Marino
867*e4b17023SJohn Marino /* Skip tokens until the desired token is found. */
868*e4b17023SJohn Marino while (true)
869*e4b17023SJohn Marino {
870*e4b17023SJohn Marino /* Peek at the next token. */
871*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
872*e4b17023SJohn Marino /* If we've reached the token we want, consume it and stop. */
873*e4b17023SJohn Marino if (token->type == type && !nesting_depth)
874*e4b17023SJohn Marino {
875*e4b17023SJohn Marino c_parser_consume_token (parser);
876*e4b17023SJohn Marino break;
877*e4b17023SJohn Marino }
878*e4b17023SJohn Marino
879*e4b17023SJohn Marino /* If we've run out of tokens, stop. */
880*e4b17023SJohn Marino if (token->type == CPP_EOF)
881*e4b17023SJohn Marino return;
882*e4b17023SJohn Marino if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
883*e4b17023SJohn Marino return;
884*e4b17023SJohn Marino if (token->type == CPP_OPEN_BRACE
885*e4b17023SJohn Marino || token->type == CPP_OPEN_PAREN
886*e4b17023SJohn Marino || token->type == CPP_OPEN_SQUARE)
887*e4b17023SJohn Marino ++nesting_depth;
888*e4b17023SJohn Marino else if (token->type == CPP_CLOSE_BRACE
889*e4b17023SJohn Marino || token->type == CPP_CLOSE_PAREN
890*e4b17023SJohn Marino || token->type == CPP_CLOSE_SQUARE)
891*e4b17023SJohn Marino {
892*e4b17023SJohn Marino if (nesting_depth-- == 0)
893*e4b17023SJohn Marino break;
894*e4b17023SJohn Marino }
895*e4b17023SJohn Marino /* Consume this token. */
896*e4b17023SJohn Marino c_parser_consume_token (parser);
897*e4b17023SJohn Marino }
898*e4b17023SJohn Marino parser->error = false;
899*e4b17023SJohn Marino }
900*e4b17023SJohn Marino
901*e4b17023SJohn Marino /* Skip tokens until the end of a parameter is found, but do not
902*e4b17023SJohn Marino consume the comma, semicolon or closing delimiter. */
903*e4b17023SJohn Marino
904*e4b17023SJohn Marino static void
c_parser_skip_to_end_of_parameter(c_parser * parser)905*e4b17023SJohn Marino c_parser_skip_to_end_of_parameter (c_parser *parser)
906*e4b17023SJohn Marino {
907*e4b17023SJohn Marino unsigned nesting_depth = 0;
908*e4b17023SJohn Marino
909*e4b17023SJohn Marino while (true)
910*e4b17023SJohn Marino {
911*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
912*e4b17023SJohn Marino if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
913*e4b17023SJohn Marino && !nesting_depth)
914*e4b17023SJohn Marino break;
915*e4b17023SJohn Marino /* If we've run out of tokens, stop. */
916*e4b17023SJohn Marino if (token->type == CPP_EOF)
917*e4b17023SJohn Marino return;
918*e4b17023SJohn Marino if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
919*e4b17023SJohn Marino return;
920*e4b17023SJohn Marino if (token->type == CPP_OPEN_BRACE
921*e4b17023SJohn Marino || token->type == CPP_OPEN_PAREN
922*e4b17023SJohn Marino || token->type == CPP_OPEN_SQUARE)
923*e4b17023SJohn Marino ++nesting_depth;
924*e4b17023SJohn Marino else if (token->type == CPP_CLOSE_BRACE
925*e4b17023SJohn Marino || token->type == CPP_CLOSE_PAREN
926*e4b17023SJohn Marino || token->type == CPP_CLOSE_SQUARE)
927*e4b17023SJohn Marino {
928*e4b17023SJohn Marino if (nesting_depth-- == 0)
929*e4b17023SJohn Marino break;
930*e4b17023SJohn Marino }
931*e4b17023SJohn Marino /* Consume this token. */
932*e4b17023SJohn Marino c_parser_consume_token (parser);
933*e4b17023SJohn Marino }
934*e4b17023SJohn Marino parser->error = false;
935*e4b17023SJohn Marino }
936*e4b17023SJohn Marino
937*e4b17023SJohn Marino /* Expect to be at the end of the pragma directive and consume an
938*e4b17023SJohn Marino end of line marker. */
939*e4b17023SJohn Marino
940*e4b17023SJohn Marino static void
c_parser_skip_to_pragma_eol(c_parser * parser)941*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (c_parser *parser)
942*e4b17023SJohn Marino {
943*e4b17023SJohn Marino gcc_assert (parser->in_pragma);
944*e4b17023SJohn Marino parser->in_pragma = false;
945*e4b17023SJohn Marino
946*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_PRAGMA_EOL, "expected end of line"))
947*e4b17023SJohn Marino while (true)
948*e4b17023SJohn Marino {
949*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
950*e4b17023SJohn Marino if (token->type == CPP_EOF)
951*e4b17023SJohn Marino break;
952*e4b17023SJohn Marino if (token->type == CPP_PRAGMA_EOL)
953*e4b17023SJohn Marino {
954*e4b17023SJohn Marino c_parser_consume_token (parser);
955*e4b17023SJohn Marino break;
956*e4b17023SJohn Marino }
957*e4b17023SJohn Marino c_parser_consume_token (parser);
958*e4b17023SJohn Marino }
959*e4b17023SJohn Marino
960*e4b17023SJohn Marino parser->error = false;
961*e4b17023SJohn Marino }
962*e4b17023SJohn Marino
963*e4b17023SJohn Marino /* Skip tokens until we have consumed an entire block, or until we
964*e4b17023SJohn Marino have consumed a non-nested ';'. */
965*e4b17023SJohn Marino
966*e4b17023SJohn Marino static void
c_parser_skip_to_end_of_block_or_statement(c_parser * parser)967*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
968*e4b17023SJohn Marino {
969*e4b17023SJohn Marino unsigned nesting_depth = 0;
970*e4b17023SJohn Marino bool save_error = parser->error;
971*e4b17023SJohn Marino
972*e4b17023SJohn Marino while (true)
973*e4b17023SJohn Marino {
974*e4b17023SJohn Marino c_token *token;
975*e4b17023SJohn Marino
976*e4b17023SJohn Marino /* Peek at the next token. */
977*e4b17023SJohn Marino token = c_parser_peek_token (parser);
978*e4b17023SJohn Marino
979*e4b17023SJohn Marino switch (token->type)
980*e4b17023SJohn Marino {
981*e4b17023SJohn Marino case CPP_EOF:
982*e4b17023SJohn Marino return;
983*e4b17023SJohn Marino
984*e4b17023SJohn Marino case CPP_PRAGMA_EOL:
985*e4b17023SJohn Marino if (parser->in_pragma)
986*e4b17023SJohn Marino return;
987*e4b17023SJohn Marino break;
988*e4b17023SJohn Marino
989*e4b17023SJohn Marino case CPP_SEMICOLON:
990*e4b17023SJohn Marino /* If the next token is a ';', we have reached the
991*e4b17023SJohn Marino end of the statement. */
992*e4b17023SJohn Marino if (!nesting_depth)
993*e4b17023SJohn Marino {
994*e4b17023SJohn Marino /* Consume the ';'. */
995*e4b17023SJohn Marino c_parser_consume_token (parser);
996*e4b17023SJohn Marino goto finished;
997*e4b17023SJohn Marino }
998*e4b17023SJohn Marino break;
999*e4b17023SJohn Marino
1000*e4b17023SJohn Marino case CPP_CLOSE_BRACE:
1001*e4b17023SJohn Marino /* If the next token is a non-nested '}', then we have
1002*e4b17023SJohn Marino reached the end of the current block. */
1003*e4b17023SJohn Marino if (nesting_depth == 0 || --nesting_depth == 0)
1004*e4b17023SJohn Marino {
1005*e4b17023SJohn Marino c_parser_consume_token (parser);
1006*e4b17023SJohn Marino goto finished;
1007*e4b17023SJohn Marino }
1008*e4b17023SJohn Marino break;
1009*e4b17023SJohn Marino
1010*e4b17023SJohn Marino case CPP_OPEN_BRACE:
1011*e4b17023SJohn Marino /* If it the next token is a '{', then we are entering a new
1012*e4b17023SJohn Marino block. Consume the entire block. */
1013*e4b17023SJohn Marino ++nesting_depth;
1014*e4b17023SJohn Marino break;
1015*e4b17023SJohn Marino
1016*e4b17023SJohn Marino case CPP_PRAGMA:
1017*e4b17023SJohn Marino /* If we see a pragma, consume the whole thing at once. We
1018*e4b17023SJohn Marino have some safeguards against consuming pragmas willy-nilly.
1019*e4b17023SJohn Marino Normally, we'd expect to be here with parser->error set,
1020*e4b17023SJohn Marino which disables these safeguards. But it's possible to get
1021*e4b17023SJohn Marino here for secondary error recovery, after parser->error has
1022*e4b17023SJohn Marino been cleared. */
1023*e4b17023SJohn Marino c_parser_consume_pragma (parser);
1024*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
1025*e4b17023SJohn Marino parser->error = save_error;
1026*e4b17023SJohn Marino continue;
1027*e4b17023SJohn Marino
1028*e4b17023SJohn Marino default:
1029*e4b17023SJohn Marino break;
1030*e4b17023SJohn Marino }
1031*e4b17023SJohn Marino
1032*e4b17023SJohn Marino c_parser_consume_token (parser);
1033*e4b17023SJohn Marino }
1034*e4b17023SJohn Marino
1035*e4b17023SJohn Marino finished:
1036*e4b17023SJohn Marino parser->error = false;
1037*e4b17023SJohn Marino }
1038*e4b17023SJohn Marino
1039*e4b17023SJohn Marino /* CPP's options (initialized by c-opts.c). */
1040*e4b17023SJohn Marino extern cpp_options *cpp_opts;
1041*e4b17023SJohn Marino
1042*e4b17023SJohn Marino /* Save the warning flags which are controlled by __extension__. */
1043*e4b17023SJohn Marino
1044*e4b17023SJohn Marino static inline int
disable_extension_diagnostics(void)1045*e4b17023SJohn Marino disable_extension_diagnostics (void)
1046*e4b17023SJohn Marino {
1047*e4b17023SJohn Marino int ret = (pedantic
1048*e4b17023SJohn Marino | (warn_pointer_arith << 1)
1049*e4b17023SJohn Marino | (warn_traditional << 2)
1050*e4b17023SJohn Marino | (flag_iso << 3)
1051*e4b17023SJohn Marino | (warn_long_long << 4)
1052*e4b17023SJohn Marino | (warn_cxx_compat << 5)
1053*e4b17023SJohn Marino | (warn_overlength_strings << 6));
1054*e4b17023SJohn Marino cpp_opts->cpp_pedantic = pedantic = 0;
1055*e4b17023SJohn Marino warn_pointer_arith = 0;
1056*e4b17023SJohn Marino cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1057*e4b17023SJohn Marino flag_iso = 0;
1058*e4b17023SJohn Marino cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1059*e4b17023SJohn Marino warn_cxx_compat = 0;
1060*e4b17023SJohn Marino warn_overlength_strings = 0;
1061*e4b17023SJohn Marino return ret;
1062*e4b17023SJohn Marino }
1063*e4b17023SJohn Marino
1064*e4b17023SJohn Marino /* Restore the warning flags which are controlled by __extension__.
1065*e4b17023SJohn Marino FLAGS is the return value from disable_extension_diagnostics. */
1066*e4b17023SJohn Marino
1067*e4b17023SJohn Marino static inline void
restore_extension_diagnostics(int flags)1068*e4b17023SJohn Marino restore_extension_diagnostics (int flags)
1069*e4b17023SJohn Marino {
1070*e4b17023SJohn Marino cpp_opts->cpp_pedantic = pedantic = flags & 1;
1071*e4b17023SJohn Marino warn_pointer_arith = (flags >> 1) & 1;
1072*e4b17023SJohn Marino cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1073*e4b17023SJohn Marino flag_iso = (flags >> 3) & 1;
1074*e4b17023SJohn Marino cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1075*e4b17023SJohn Marino warn_cxx_compat = (flags >> 5) & 1;
1076*e4b17023SJohn Marino warn_overlength_strings = (flags >> 6) & 1;
1077*e4b17023SJohn Marino }
1078*e4b17023SJohn Marino
1079*e4b17023SJohn Marino /* Possibly kinds of declarator to parse. */
1080*e4b17023SJohn Marino typedef enum c_dtr_syn {
1081*e4b17023SJohn Marino /* A normal declarator with an identifier. */
1082*e4b17023SJohn Marino C_DTR_NORMAL,
1083*e4b17023SJohn Marino /* An abstract declarator (maybe empty). */
1084*e4b17023SJohn Marino C_DTR_ABSTRACT,
1085*e4b17023SJohn Marino /* A parameter declarator: may be either, but after a type name does
1086*e4b17023SJohn Marino not redeclare a typedef name as an identifier if it can
1087*e4b17023SJohn Marino alternatively be interpreted as a typedef name; see DR#009,
1088*e4b17023SJohn Marino applied in C90 TC1, omitted from C99 and reapplied in C99 TC2
1089*e4b17023SJohn Marino following DR#249. For example, given a typedef T, "int T" and
1090*e4b17023SJohn Marino "int *T" are valid parameter declarations redeclaring T, while
1091*e4b17023SJohn Marino "int (T)" and "int * (T)" and "int (T[])" and "int (T (int))" are
1092*e4b17023SJohn Marino abstract declarators rather than involving redundant parentheses;
1093*e4b17023SJohn Marino the same applies with attributes inside the parentheses before
1094*e4b17023SJohn Marino "T". */
1095*e4b17023SJohn Marino C_DTR_PARM
1096*e4b17023SJohn Marino } c_dtr_syn;
1097*e4b17023SJohn Marino
1098*e4b17023SJohn Marino /* The binary operation precedence levels, where 0 is a dummy lowest level
1099*e4b17023SJohn Marino used for the bottom of the stack. */
1100*e4b17023SJohn Marino enum c_parser_prec {
1101*e4b17023SJohn Marino PREC_NONE,
1102*e4b17023SJohn Marino PREC_LOGOR,
1103*e4b17023SJohn Marino PREC_LOGAND,
1104*e4b17023SJohn Marino PREC_BITOR,
1105*e4b17023SJohn Marino PREC_BITXOR,
1106*e4b17023SJohn Marino PREC_BITAND,
1107*e4b17023SJohn Marino PREC_EQ,
1108*e4b17023SJohn Marino PREC_REL,
1109*e4b17023SJohn Marino PREC_SHIFT,
1110*e4b17023SJohn Marino PREC_ADD,
1111*e4b17023SJohn Marino PREC_MULT,
1112*e4b17023SJohn Marino NUM_PRECS
1113*e4b17023SJohn Marino };
1114*e4b17023SJohn Marino
1115*e4b17023SJohn Marino static void c_parser_external_declaration (c_parser *);
1116*e4b17023SJohn Marino static void c_parser_asm_definition (c_parser *);
1117*e4b17023SJohn Marino static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1118*e4b17023SJohn Marino bool, bool, tree *);
1119*e4b17023SJohn Marino static void c_parser_static_assert_declaration_no_semi (c_parser *);
1120*e4b17023SJohn Marino static void c_parser_static_assert_declaration (c_parser *);
1121*e4b17023SJohn Marino static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
1122*e4b17023SJohn Marino bool, enum c_lookahead_kind);
1123*e4b17023SJohn Marino static struct c_typespec c_parser_enum_specifier (c_parser *);
1124*e4b17023SJohn Marino static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1125*e4b17023SJohn Marino static tree c_parser_struct_declaration (c_parser *);
1126*e4b17023SJohn Marino static struct c_typespec c_parser_typeof_specifier (c_parser *);
1127*e4b17023SJohn Marino static tree c_parser_alignas_specifier (c_parser *);
1128*e4b17023SJohn Marino static struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn,
1129*e4b17023SJohn Marino bool *);
1130*e4b17023SJohn Marino static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1131*e4b17023SJohn Marino c_dtr_syn, bool *);
1132*e4b17023SJohn Marino static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1133*e4b17023SJohn Marino bool,
1134*e4b17023SJohn Marino struct c_declarator *);
1135*e4b17023SJohn Marino static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree);
1136*e4b17023SJohn Marino static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1137*e4b17023SJohn Marino tree);
1138*e4b17023SJohn Marino static struct c_parm *c_parser_parameter_declaration (c_parser *, tree);
1139*e4b17023SJohn Marino static tree c_parser_simple_asm_expr (c_parser *);
1140*e4b17023SJohn Marino static tree c_parser_attributes (c_parser *);
1141*e4b17023SJohn Marino static struct c_type_name *c_parser_type_name (c_parser *);
1142*e4b17023SJohn Marino static struct c_expr c_parser_initializer (c_parser *);
1143*e4b17023SJohn Marino static struct c_expr c_parser_braced_init (c_parser *, tree, bool);
1144*e4b17023SJohn Marino static void c_parser_initelt (c_parser *, struct obstack *);
1145*e4b17023SJohn Marino static void c_parser_initval (c_parser *, struct c_expr *,
1146*e4b17023SJohn Marino struct obstack *);
1147*e4b17023SJohn Marino static tree c_parser_compound_statement (c_parser *);
1148*e4b17023SJohn Marino static void c_parser_compound_statement_nostart (c_parser *);
1149*e4b17023SJohn Marino static void c_parser_label (c_parser *);
1150*e4b17023SJohn Marino static void c_parser_statement (c_parser *);
1151*e4b17023SJohn Marino static void c_parser_statement_after_labels (c_parser *);
1152*e4b17023SJohn Marino static void c_parser_if_statement (c_parser *);
1153*e4b17023SJohn Marino static void c_parser_switch_statement (c_parser *);
1154*e4b17023SJohn Marino static void c_parser_while_statement (c_parser *);
1155*e4b17023SJohn Marino static void c_parser_do_statement (c_parser *);
1156*e4b17023SJohn Marino static void c_parser_for_statement (c_parser *);
1157*e4b17023SJohn Marino static tree c_parser_asm_statement (c_parser *);
1158*e4b17023SJohn Marino static tree c_parser_asm_operands (c_parser *, bool);
1159*e4b17023SJohn Marino static tree c_parser_asm_goto_operands (c_parser *);
1160*e4b17023SJohn Marino static tree c_parser_asm_clobbers (c_parser *);
1161*e4b17023SJohn Marino static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *);
1162*e4b17023SJohn Marino static struct c_expr c_parser_conditional_expression (c_parser *,
1163*e4b17023SJohn Marino struct c_expr *);
1164*e4b17023SJohn Marino static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1165*e4b17023SJohn Marino enum c_parser_prec);
1166*e4b17023SJohn Marino static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1167*e4b17023SJohn Marino static struct c_expr c_parser_unary_expression (c_parser *);
1168*e4b17023SJohn Marino static struct c_expr c_parser_sizeof_expression (c_parser *);
1169*e4b17023SJohn Marino static struct c_expr c_parser_alignof_expression (c_parser *);
1170*e4b17023SJohn Marino static struct c_expr c_parser_postfix_expression (c_parser *);
1171*e4b17023SJohn Marino static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1172*e4b17023SJohn Marino struct c_type_name *,
1173*e4b17023SJohn Marino location_t);
1174*e4b17023SJohn Marino static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1175*e4b17023SJohn Marino location_t loc,
1176*e4b17023SJohn Marino struct c_expr);
1177*e4b17023SJohn Marino static tree c_parser_transaction (c_parser *, enum rid);
1178*e4b17023SJohn Marino static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1179*e4b17023SJohn Marino static tree c_parser_transaction_cancel (c_parser *);
1180*e4b17023SJohn Marino static struct c_expr c_parser_expression (c_parser *);
1181*e4b17023SJohn Marino static struct c_expr c_parser_expression_conv (c_parser *);
1182*e4b17023SJohn Marino static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
1183*e4b17023SJohn Marino VEC(tree,gc) **);
1184*e4b17023SJohn Marino static void c_parser_omp_construct (c_parser *);
1185*e4b17023SJohn Marino static void c_parser_omp_threadprivate (c_parser *);
1186*e4b17023SJohn Marino static void c_parser_omp_barrier (c_parser *);
1187*e4b17023SJohn Marino static void c_parser_omp_flush (c_parser *);
1188*e4b17023SJohn Marino static void c_parser_omp_taskwait (c_parser *);
1189*e4b17023SJohn Marino static void c_parser_omp_taskyield (c_parser *);
1190*e4b17023SJohn Marino
1191*e4b17023SJohn Marino enum pragma_context { pragma_external, pragma_stmt, pragma_compound };
1192*e4b17023SJohn Marino static bool c_parser_pragma (c_parser *, enum pragma_context);
1193*e4b17023SJohn Marino
1194*e4b17023SJohn Marino /* These Objective-C parser functions are only ever called when
1195*e4b17023SJohn Marino compiling Objective-C. */
1196*e4b17023SJohn Marino static void c_parser_objc_class_definition (c_parser *, tree);
1197*e4b17023SJohn Marino static void c_parser_objc_class_instance_variables (c_parser *);
1198*e4b17023SJohn Marino static void c_parser_objc_class_declaration (c_parser *);
1199*e4b17023SJohn Marino static void c_parser_objc_alias_declaration (c_parser *);
1200*e4b17023SJohn Marino static void c_parser_objc_protocol_definition (c_parser *, tree);
1201*e4b17023SJohn Marino static bool c_parser_objc_method_type (c_parser *);
1202*e4b17023SJohn Marino static void c_parser_objc_method_definition (c_parser *);
1203*e4b17023SJohn Marino static void c_parser_objc_methodprotolist (c_parser *);
1204*e4b17023SJohn Marino static void c_parser_objc_methodproto (c_parser *);
1205*e4b17023SJohn Marino static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1206*e4b17023SJohn Marino static tree c_parser_objc_type_name (c_parser *);
1207*e4b17023SJohn Marino static tree c_parser_objc_protocol_refs (c_parser *);
1208*e4b17023SJohn Marino static void c_parser_objc_try_catch_finally_statement (c_parser *);
1209*e4b17023SJohn Marino static void c_parser_objc_synchronized_statement (c_parser *);
1210*e4b17023SJohn Marino static tree c_parser_objc_selector (c_parser *);
1211*e4b17023SJohn Marino static tree c_parser_objc_selector_arg (c_parser *);
1212*e4b17023SJohn Marino static tree c_parser_objc_receiver (c_parser *);
1213*e4b17023SJohn Marino static tree c_parser_objc_message_args (c_parser *);
1214*e4b17023SJohn Marino static tree c_parser_objc_keywordexpr (c_parser *);
1215*e4b17023SJohn Marino static void c_parser_objc_at_property_declaration (c_parser *);
1216*e4b17023SJohn Marino static void c_parser_objc_at_synthesize_declaration (c_parser *);
1217*e4b17023SJohn Marino static void c_parser_objc_at_dynamic_declaration (c_parser *);
1218*e4b17023SJohn Marino static bool c_parser_objc_diagnose_bad_element_prefix
1219*e4b17023SJohn Marino (c_parser *, struct c_declspecs *);
1220*e4b17023SJohn Marino
1221*e4b17023SJohn Marino /* Parse a translation unit (C90 6.7, C99 6.9).
1222*e4b17023SJohn Marino
1223*e4b17023SJohn Marino translation-unit:
1224*e4b17023SJohn Marino external-declarations
1225*e4b17023SJohn Marino
1226*e4b17023SJohn Marino external-declarations:
1227*e4b17023SJohn Marino external-declaration
1228*e4b17023SJohn Marino external-declarations external-declaration
1229*e4b17023SJohn Marino
1230*e4b17023SJohn Marino GNU extensions:
1231*e4b17023SJohn Marino
1232*e4b17023SJohn Marino translation-unit:
1233*e4b17023SJohn Marino empty
1234*e4b17023SJohn Marino */
1235*e4b17023SJohn Marino
1236*e4b17023SJohn Marino static void
c_parser_translation_unit(c_parser * parser)1237*e4b17023SJohn Marino c_parser_translation_unit (c_parser *parser)
1238*e4b17023SJohn Marino {
1239*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_EOF))
1240*e4b17023SJohn Marino {
1241*e4b17023SJohn Marino pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
1242*e4b17023SJohn Marino "ISO C forbids an empty translation unit");
1243*e4b17023SJohn Marino }
1244*e4b17023SJohn Marino else
1245*e4b17023SJohn Marino {
1246*e4b17023SJohn Marino void *obstack_position = obstack_alloc (&parser_obstack, 0);
1247*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (false);
1248*e4b17023SJohn Marino do
1249*e4b17023SJohn Marino {
1250*e4b17023SJohn Marino ggc_collect ();
1251*e4b17023SJohn Marino c_parser_external_declaration (parser);
1252*e4b17023SJohn Marino obstack_free (&parser_obstack, obstack_position);
1253*e4b17023SJohn Marino }
1254*e4b17023SJohn Marino while (c_parser_next_token_is_not (parser, CPP_EOF));
1255*e4b17023SJohn Marino }
1256*e4b17023SJohn Marino }
1257*e4b17023SJohn Marino
1258*e4b17023SJohn Marino /* Parse an external declaration (C90 6.7, C99 6.9).
1259*e4b17023SJohn Marino
1260*e4b17023SJohn Marino external-declaration:
1261*e4b17023SJohn Marino function-definition
1262*e4b17023SJohn Marino declaration
1263*e4b17023SJohn Marino
1264*e4b17023SJohn Marino GNU extensions:
1265*e4b17023SJohn Marino
1266*e4b17023SJohn Marino external-declaration:
1267*e4b17023SJohn Marino asm-definition
1268*e4b17023SJohn Marino ;
1269*e4b17023SJohn Marino __extension__ external-declaration
1270*e4b17023SJohn Marino
1271*e4b17023SJohn Marino Objective-C:
1272*e4b17023SJohn Marino
1273*e4b17023SJohn Marino external-declaration:
1274*e4b17023SJohn Marino objc-class-definition
1275*e4b17023SJohn Marino objc-class-declaration
1276*e4b17023SJohn Marino objc-alias-declaration
1277*e4b17023SJohn Marino objc-protocol-definition
1278*e4b17023SJohn Marino objc-method-definition
1279*e4b17023SJohn Marino @end
1280*e4b17023SJohn Marino */
1281*e4b17023SJohn Marino
1282*e4b17023SJohn Marino static void
c_parser_external_declaration(c_parser * parser)1283*e4b17023SJohn Marino c_parser_external_declaration (c_parser *parser)
1284*e4b17023SJohn Marino {
1285*e4b17023SJohn Marino int ext;
1286*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
1287*e4b17023SJohn Marino {
1288*e4b17023SJohn Marino case CPP_KEYWORD:
1289*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->keyword)
1290*e4b17023SJohn Marino {
1291*e4b17023SJohn Marino case RID_EXTENSION:
1292*e4b17023SJohn Marino ext = disable_extension_diagnostics ();
1293*e4b17023SJohn Marino c_parser_consume_token (parser);
1294*e4b17023SJohn Marino c_parser_external_declaration (parser);
1295*e4b17023SJohn Marino restore_extension_diagnostics (ext);
1296*e4b17023SJohn Marino break;
1297*e4b17023SJohn Marino case RID_ASM:
1298*e4b17023SJohn Marino c_parser_asm_definition (parser);
1299*e4b17023SJohn Marino break;
1300*e4b17023SJohn Marino case RID_AT_INTERFACE:
1301*e4b17023SJohn Marino case RID_AT_IMPLEMENTATION:
1302*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
1303*e4b17023SJohn Marino c_parser_objc_class_definition (parser, NULL_TREE);
1304*e4b17023SJohn Marino break;
1305*e4b17023SJohn Marino case RID_AT_CLASS:
1306*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
1307*e4b17023SJohn Marino c_parser_objc_class_declaration (parser);
1308*e4b17023SJohn Marino break;
1309*e4b17023SJohn Marino case RID_AT_ALIAS:
1310*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
1311*e4b17023SJohn Marino c_parser_objc_alias_declaration (parser);
1312*e4b17023SJohn Marino break;
1313*e4b17023SJohn Marino case RID_AT_PROTOCOL:
1314*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
1315*e4b17023SJohn Marino c_parser_objc_protocol_definition (parser, NULL_TREE);
1316*e4b17023SJohn Marino break;
1317*e4b17023SJohn Marino case RID_AT_PROPERTY:
1318*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
1319*e4b17023SJohn Marino c_parser_objc_at_property_declaration (parser);
1320*e4b17023SJohn Marino break;
1321*e4b17023SJohn Marino case RID_AT_SYNTHESIZE:
1322*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
1323*e4b17023SJohn Marino c_parser_objc_at_synthesize_declaration (parser);
1324*e4b17023SJohn Marino break;
1325*e4b17023SJohn Marino case RID_AT_DYNAMIC:
1326*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
1327*e4b17023SJohn Marino c_parser_objc_at_dynamic_declaration (parser);
1328*e4b17023SJohn Marino break;
1329*e4b17023SJohn Marino case RID_AT_END:
1330*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
1331*e4b17023SJohn Marino c_parser_consume_token (parser);
1332*e4b17023SJohn Marino objc_finish_implementation ();
1333*e4b17023SJohn Marino break;
1334*e4b17023SJohn Marino default:
1335*e4b17023SJohn Marino goto decl_or_fndef;
1336*e4b17023SJohn Marino }
1337*e4b17023SJohn Marino break;
1338*e4b17023SJohn Marino case CPP_SEMICOLON:
1339*e4b17023SJohn Marino pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
1340*e4b17023SJohn Marino "ISO C does not allow extra %<;%> outside of a function");
1341*e4b17023SJohn Marino c_parser_consume_token (parser);
1342*e4b17023SJohn Marino break;
1343*e4b17023SJohn Marino case CPP_PRAGMA:
1344*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (true);
1345*e4b17023SJohn Marino c_parser_pragma (parser, pragma_external);
1346*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (false);
1347*e4b17023SJohn Marino break;
1348*e4b17023SJohn Marino case CPP_PLUS:
1349*e4b17023SJohn Marino case CPP_MINUS:
1350*e4b17023SJohn Marino if (c_dialect_objc ())
1351*e4b17023SJohn Marino {
1352*e4b17023SJohn Marino c_parser_objc_method_definition (parser);
1353*e4b17023SJohn Marino break;
1354*e4b17023SJohn Marino }
1355*e4b17023SJohn Marino /* Else fall through, and yield a syntax error trying to parse
1356*e4b17023SJohn Marino as a declaration or function definition. */
1357*e4b17023SJohn Marino default:
1358*e4b17023SJohn Marino decl_or_fndef:
1359*e4b17023SJohn Marino /* A declaration or a function definition (or, in Objective-C,
1360*e4b17023SJohn Marino an @interface or @protocol with prefix attributes). We can
1361*e4b17023SJohn Marino only tell which after parsing the declaration specifiers, if
1362*e4b17023SJohn Marino any, and the first declarator. */
1363*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, true, true, true, false, true, NULL);
1364*e4b17023SJohn Marino break;
1365*e4b17023SJohn Marino }
1366*e4b17023SJohn Marino }
1367*e4b17023SJohn Marino
1368*e4b17023SJohn Marino /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1369*e4b17023SJohn Marino 6.7, 6.9.1). If FNDEF_OK is true, a function definition is
1370*e4b17023SJohn Marino accepted; otherwise (old-style parameter declarations) only other
1371*e4b17023SJohn Marino declarations are accepted. If STATIC_ASSERT_OK is true, a static
1372*e4b17023SJohn Marino assertion is accepted; otherwise (old-style parameter declarations)
1373*e4b17023SJohn Marino it is not. If NESTED is true, we are inside a function or parsing
1374*e4b17023SJohn Marino old-style parameter declarations; any functions encountered are
1375*e4b17023SJohn Marino nested functions and declaration specifiers are required; otherwise
1376*e4b17023SJohn Marino we are at top level and functions are normal functions and
1377*e4b17023SJohn Marino declaration specifiers may be optional. If EMPTY_OK is true, empty
1378*e4b17023SJohn Marino declarations are OK (subject to all other constraints); otherwise
1379*e4b17023SJohn Marino (old-style parameter declarations) they are diagnosed. If
1380*e4b17023SJohn Marino START_ATTR_OK is true, the declaration specifiers may start with
1381*e4b17023SJohn Marino attributes; otherwise they may not.
1382*e4b17023SJohn Marino OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1383*e4b17023SJohn Marino declaration when parsing an Objective-C foreach statement.
1384*e4b17023SJohn Marino
1385*e4b17023SJohn Marino declaration:
1386*e4b17023SJohn Marino declaration-specifiers init-declarator-list[opt] ;
1387*e4b17023SJohn Marino static_assert-declaration
1388*e4b17023SJohn Marino
1389*e4b17023SJohn Marino function-definition:
1390*e4b17023SJohn Marino declaration-specifiers[opt] declarator declaration-list[opt]
1391*e4b17023SJohn Marino compound-statement
1392*e4b17023SJohn Marino
1393*e4b17023SJohn Marino declaration-list:
1394*e4b17023SJohn Marino declaration
1395*e4b17023SJohn Marino declaration-list declaration
1396*e4b17023SJohn Marino
1397*e4b17023SJohn Marino init-declarator-list:
1398*e4b17023SJohn Marino init-declarator
1399*e4b17023SJohn Marino init-declarator-list , init-declarator
1400*e4b17023SJohn Marino
1401*e4b17023SJohn Marino init-declarator:
1402*e4b17023SJohn Marino declarator simple-asm-expr[opt] attributes[opt]
1403*e4b17023SJohn Marino declarator simple-asm-expr[opt] attributes[opt] = initializer
1404*e4b17023SJohn Marino
1405*e4b17023SJohn Marino GNU extensions:
1406*e4b17023SJohn Marino
1407*e4b17023SJohn Marino nested-function-definition:
1408*e4b17023SJohn Marino declaration-specifiers declarator declaration-list[opt]
1409*e4b17023SJohn Marino compound-statement
1410*e4b17023SJohn Marino
1411*e4b17023SJohn Marino Objective-C:
1412*e4b17023SJohn Marino attributes objc-class-definition
1413*e4b17023SJohn Marino attributes objc-category-definition
1414*e4b17023SJohn Marino attributes objc-protocol-definition
1415*e4b17023SJohn Marino
1416*e4b17023SJohn Marino The simple-asm-expr and attributes are GNU extensions.
1417*e4b17023SJohn Marino
1418*e4b17023SJohn Marino This function does not handle __extension__; that is handled in its
1419*e4b17023SJohn Marino callers. ??? Following the old parser, __extension__ may start
1420*e4b17023SJohn Marino external declarations, declarations in functions and declarations
1421*e4b17023SJohn Marino at the start of "for" loops, but not old-style parameter
1422*e4b17023SJohn Marino declarations.
1423*e4b17023SJohn Marino
1424*e4b17023SJohn Marino C99 requires declaration specifiers in a function definition; the
1425*e4b17023SJohn Marino absence is diagnosed through the diagnosis of implicit int. In GNU
1426*e4b17023SJohn Marino C we also allow but diagnose declarations without declaration
1427*e4b17023SJohn Marino specifiers, but only at top level (elsewhere they conflict with
1428*e4b17023SJohn Marino other syntax).
1429*e4b17023SJohn Marino
1430*e4b17023SJohn Marino In Objective-C, declarations of the looping variable in a foreach
1431*e4b17023SJohn Marino statement are exceptionally terminated by 'in' (for example, 'for
1432*e4b17023SJohn Marino (NSObject *object in array) { ... }').
1433*e4b17023SJohn Marino
1434*e4b17023SJohn Marino OpenMP:
1435*e4b17023SJohn Marino
1436*e4b17023SJohn Marino declaration:
1437*e4b17023SJohn Marino threadprivate-directive */
1438*e4b17023SJohn Marino
1439*e4b17023SJohn Marino static void
c_parser_declaration_or_fndef(c_parser * parser,bool fndef_ok,bool static_assert_ok,bool empty_ok,bool nested,bool start_attr_ok,tree * objc_foreach_object_declaration)1440*e4b17023SJohn Marino c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1441*e4b17023SJohn Marino bool static_assert_ok, bool empty_ok,
1442*e4b17023SJohn Marino bool nested, bool start_attr_ok,
1443*e4b17023SJohn Marino tree *objc_foreach_object_declaration)
1444*e4b17023SJohn Marino {
1445*e4b17023SJohn Marino struct c_declspecs *specs;
1446*e4b17023SJohn Marino tree prefix_attrs;
1447*e4b17023SJohn Marino tree all_prefix_attrs;
1448*e4b17023SJohn Marino bool diagnosed_no_specs = false;
1449*e4b17023SJohn Marino location_t here = c_parser_peek_token (parser)->location;
1450*e4b17023SJohn Marino
1451*e4b17023SJohn Marino if (static_assert_ok
1452*e4b17023SJohn Marino && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1453*e4b17023SJohn Marino {
1454*e4b17023SJohn Marino c_parser_static_assert_declaration (parser);
1455*e4b17023SJohn Marino return;
1456*e4b17023SJohn Marino }
1457*e4b17023SJohn Marino specs = build_null_declspecs ();
1458*e4b17023SJohn Marino
1459*e4b17023SJohn Marino /* Try to detect an unknown type name when we have "A B" or "A *B". */
1460*e4b17023SJohn Marino if (c_parser_peek_token (parser)->type == CPP_NAME
1461*e4b17023SJohn Marino && c_parser_peek_token (parser)->id_kind == C_ID_ID
1462*e4b17023SJohn Marino && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1463*e4b17023SJohn Marino || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1464*e4b17023SJohn Marino && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1465*e4b17023SJohn Marino {
1466*e4b17023SJohn Marino error_at (here, "unknown type name %qE",
1467*e4b17023SJohn Marino c_parser_peek_token (parser)->value);
1468*e4b17023SJohn Marino
1469*e4b17023SJohn Marino /* Parse declspecs normally to get a correct pointer type, but avoid
1470*e4b17023SJohn Marino a further "fails to be a type name" error. Refuse nested functions
1471*e4b17023SJohn Marino since it is not how the user likely wants us to recover. */
1472*e4b17023SJohn Marino c_parser_peek_token (parser)->type = CPP_KEYWORD;
1473*e4b17023SJohn Marino c_parser_peek_token (parser)->keyword = RID_VOID;
1474*e4b17023SJohn Marino c_parser_peek_token (parser)->value = error_mark_node;
1475*e4b17023SJohn Marino fndef_ok = !nested;
1476*e4b17023SJohn Marino }
1477*e4b17023SJohn Marino
1478*e4b17023SJohn Marino c_parser_declspecs (parser, specs, true, true, start_attr_ok, cla_nonabstract_decl);
1479*e4b17023SJohn Marino if (parser->error)
1480*e4b17023SJohn Marino {
1481*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
1482*e4b17023SJohn Marino return;
1483*e4b17023SJohn Marino }
1484*e4b17023SJohn Marino if (nested && !specs->declspecs_seen_p)
1485*e4b17023SJohn Marino {
1486*e4b17023SJohn Marino c_parser_error (parser, "expected declaration specifiers");
1487*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
1488*e4b17023SJohn Marino return;
1489*e4b17023SJohn Marino }
1490*e4b17023SJohn Marino finish_declspecs (specs);
1491*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1492*e4b17023SJohn Marino {
1493*e4b17023SJohn Marino if (empty_ok)
1494*e4b17023SJohn Marino shadow_tag (specs);
1495*e4b17023SJohn Marino else
1496*e4b17023SJohn Marino {
1497*e4b17023SJohn Marino shadow_tag_warned (specs, 1);
1498*e4b17023SJohn Marino pedwarn (here, 0, "empty declaration");
1499*e4b17023SJohn Marino }
1500*e4b17023SJohn Marino c_parser_consume_token (parser);
1501*e4b17023SJohn Marino return;
1502*e4b17023SJohn Marino }
1503*e4b17023SJohn Marino
1504*e4b17023SJohn Marino /* Provide better error recovery. Note that a type name here is usually
1505*e4b17023SJohn Marino better diagnosed as a redeclaration. */
1506*e4b17023SJohn Marino if (empty_ok
1507*e4b17023SJohn Marino && specs->typespec_kind == ctsk_tagdef
1508*e4b17023SJohn Marino && c_parser_next_token_starts_declspecs (parser)
1509*e4b17023SJohn Marino && !c_parser_next_token_is (parser, CPP_NAME))
1510*e4b17023SJohn Marino {
1511*e4b17023SJohn Marino c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
1512*e4b17023SJohn Marino parser->error = false;
1513*e4b17023SJohn Marino shadow_tag_warned (specs, 1);
1514*e4b17023SJohn Marino return;
1515*e4b17023SJohn Marino }
1516*e4b17023SJohn Marino else if (c_dialect_objc ())
1517*e4b17023SJohn Marino {
1518*e4b17023SJohn Marino /* Prefix attributes are an error on method decls. */
1519*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
1520*e4b17023SJohn Marino {
1521*e4b17023SJohn Marino case CPP_PLUS:
1522*e4b17023SJohn Marino case CPP_MINUS:
1523*e4b17023SJohn Marino if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1524*e4b17023SJohn Marino return;
1525*e4b17023SJohn Marino if (specs->attrs)
1526*e4b17023SJohn Marino {
1527*e4b17023SJohn Marino warning_at (c_parser_peek_token (parser)->location,
1528*e4b17023SJohn Marino OPT_Wattributes,
1529*e4b17023SJohn Marino "prefix attributes are ignored for methods");
1530*e4b17023SJohn Marino specs->attrs = NULL_TREE;
1531*e4b17023SJohn Marino }
1532*e4b17023SJohn Marino if (fndef_ok)
1533*e4b17023SJohn Marino c_parser_objc_method_definition (parser);
1534*e4b17023SJohn Marino else
1535*e4b17023SJohn Marino c_parser_objc_methodproto (parser);
1536*e4b17023SJohn Marino return;
1537*e4b17023SJohn Marino break;
1538*e4b17023SJohn Marino default:
1539*e4b17023SJohn Marino break;
1540*e4b17023SJohn Marino }
1541*e4b17023SJohn Marino /* This is where we parse 'attributes @interface ...',
1542*e4b17023SJohn Marino 'attributes @implementation ...', 'attributes @protocol ...'
1543*e4b17023SJohn Marino (where attributes could be, for example, __attribute__
1544*e4b17023SJohn Marino ((deprecated)).
1545*e4b17023SJohn Marino */
1546*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->keyword)
1547*e4b17023SJohn Marino {
1548*e4b17023SJohn Marino case RID_AT_INTERFACE:
1549*e4b17023SJohn Marino {
1550*e4b17023SJohn Marino if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1551*e4b17023SJohn Marino return;
1552*e4b17023SJohn Marino c_parser_objc_class_definition (parser, specs->attrs);
1553*e4b17023SJohn Marino return;
1554*e4b17023SJohn Marino }
1555*e4b17023SJohn Marino break;
1556*e4b17023SJohn Marino case RID_AT_IMPLEMENTATION:
1557*e4b17023SJohn Marino {
1558*e4b17023SJohn Marino if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1559*e4b17023SJohn Marino return;
1560*e4b17023SJohn Marino if (specs->attrs)
1561*e4b17023SJohn Marino {
1562*e4b17023SJohn Marino warning_at (c_parser_peek_token (parser)->location,
1563*e4b17023SJohn Marino OPT_Wattributes,
1564*e4b17023SJohn Marino "prefix attributes are ignored for implementations");
1565*e4b17023SJohn Marino specs->attrs = NULL_TREE;
1566*e4b17023SJohn Marino }
1567*e4b17023SJohn Marino c_parser_objc_class_definition (parser, NULL_TREE);
1568*e4b17023SJohn Marino return;
1569*e4b17023SJohn Marino }
1570*e4b17023SJohn Marino break;
1571*e4b17023SJohn Marino case RID_AT_PROTOCOL:
1572*e4b17023SJohn Marino {
1573*e4b17023SJohn Marino if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1574*e4b17023SJohn Marino return;
1575*e4b17023SJohn Marino c_parser_objc_protocol_definition (parser, specs->attrs);
1576*e4b17023SJohn Marino return;
1577*e4b17023SJohn Marino }
1578*e4b17023SJohn Marino break;
1579*e4b17023SJohn Marino case RID_AT_ALIAS:
1580*e4b17023SJohn Marino case RID_AT_CLASS:
1581*e4b17023SJohn Marino case RID_AT_END:
1582*e4b17023SJohn Marino case RID_AT_PROPERTY:
1583*e4b17023SJohn Marino if (specs->attrs)
1584*e4b17023SJohn Marino {
1585*e4b17023SJohn Marino c_parser_error (parser, "unexpected attribute");
1586*e4b17023SJohn Marino specs->attrs = NULL;
1587*e4b17023SJohn Marino }
1588*e4b17023SJohn Marino break;
1589*e4b17023SJohn Marino default:
1590*e4b17023SJohn Marino break;
1591*e4b17023SJohn Marino }
1592*e4b17023SJohn Marino }
1593*e4b17023SJohn Marino
1594*e4b17023SJohn Marino pending_xref_error ();
1595*e4b17023SJohn Marino prefix_attrs = specs->attrs;
1596*e4b17023SJohn Marino all_prefix_attrs = prefix_attrs;
1597*e4b17023SJohn Marino specs->attrs = NULL_TREE;
1598*e4b17023SJohn Marino while (true)
1599*e4b17023SJohn Marino {
1600*e4b17023SJohn Marino struct c_declarator *declarator;
1601*e4b17023SJohn Marino bool dummy = false;
1602*e4b17023SJohn Marino timevar_id_t tv;
1603*e4b17023SJohn Marino tree fnbody;
1604*e4b17023SJohn Marino /* Declaring either one or more declarators (in which case we
1605*e4b17023SJohn Marino should diagnose if there were no declaration specifiers) or a
1606*e4b17023SJohn Marino function definition (in which case the diagnostic for
1607*e4b17023SJohn Marino implicit int suffices). */
1608*e4b17023SJohn Marino declarator = c_parser_declarator (parser,
1609*e4b17023SJohn Marino specs->typespec_kind != ctsk_none,
1610*e4b17023SJohn Marino C_DTR_NORMAL, &dummy);
1611*e4b17023SJohn Marino if (declarator == NULL)
1612*e4b17023SJohn Marino {
1613*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
1614*e4b17023SJohn Marino return;
1615*e4b17023SJohn Marino }
1616*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_EQ)
1617*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_COMMA)
1618*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_SEMICOLON)
1619*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_ASM)
1620*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
1621*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_IN))
1622*e4b17023SJohn Marino {
1623*e4b17023SJohn Marino tree asm_name = NULL_TREE;
1624*e4b17023SJohn Marino tree postfix_attrs = NULL_TREE;
1625*e4b17023SJohn Marino if (!diagnosed_no_specs && !specs->declspecs_seen_p)
1626*e4b17023SJohn Marino {
1627*e4b17023SJohn Marino diagnosed_no_specs = true;
1628*e4b17023SJohn Marino pedwarn (here, 0, "data definition has no type or storage class");
1629*e4b17023SJohn Marino }
1630*e4b17023SJohn Marino /* Having seen a data definition, there cannot now be a
1631*e4b17023SJohn Marino function definition. */
1632*e4b17023SJohn Marino fndef_ok = false;
1633*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ASM))
1634*e4b17023SJohn Marino asm_name = c_parser_simple_asm_expr (parser);
1635*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
1636*e4b17023SJohn Marino postfix_attrs = c_parser_attributes (parser);
1637*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_EQ))
1638*e4b17023SJohn Marino {
1639*e4b17023SJohn Marino tree d;
1640*e4b17023SJohn Marino struct c_expr init;
1641*e4b17023SJohn Marino location_t init_loc;
1642*e4b17023SJohn Marino c_parser_consume_token (parser);
1643*e4b17023SJohn Marino /* The declaration of the variable is in effect while
1644*e4b17023SJohn Marino its initializer is parsed. */
1645*e4b17023SJohn Marino d = start_decl (declarator, specs, true,
1646*e4b17023SJohn Marino chainon (postfix_attrs, all_prefix_attrs));
1647*e4b17023SJohn Marino if (!d)
1648*e4b17023SJohn Marino d = error_mark_node;
1649*e4b17023SJohn Marino start_init (d, asm_name, global_bindings_p ());
1650*e4b17023SJohn Marino init_loc = c_parser_peek_token (parser)->location;
1651*e4b17023SJohn Marino init = c_parser_initializer (parser);
1652*e4b17023SJohn Marino finish_init ();
1653*e4b17023SJohn Marino if (d != error_mark_node)
1654*e4b17023SJohn Marino {
1655*e4b17023SJohn Marino maybe_warn_string_init (TREE_TYPE (d), init);
1656*e4b17023SJohn Marino finish_decl (d, init_loc, init.value,
1657*e4b17023SJohn Marino init.original_type, asm_name);
1658*e4b17023SJohn Marino }
1659*e4b17023SJohn Marino }
1660*e4b17023SJohn Marino else
1661*e4b17023SJohn Marino {
1662*e4b17023SJohn Marino tree d = start_decl (declarator, specs, false,
1663*e4b17023SJohn Marino chainon (postfix_attrs,
1664*e4b17023SJohn Marino all_prefix_attrs));
1665*e4b17023SJohn Marino if (d)
1666*e4b17023SJohn Marino finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
1667*e4b17023SJohn Marino NULL_TREE, asm_name);
1668*e4b17023SJohn Marino
1669*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_IN))
1670*e4b17023SJohn Marino {
1671*e4b17023SJohn Marino if (d)
1672*e4b17023SJohn Marino *objc_foreach_object_declaration = d;
1673*e4b17023SJohn Marino else
1674*e4b17023SJohn Marino *objc_foreach_object_declaration = error_mark_node;
1675*e4b17023SJohn Marino }
1676*e4b17023SJohn Marino }
1677*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
1678*e4b17023SJohn Marino {
1679*e4b17023SJohn Marino c_parser_consume_token (parser);
1680*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
1681*e4b17023SJohn Marino all_prefix_attrs = chainon (c_parser_attributes (parser),
1682*e4b17023SJohn Marino prefix_attrs);
1683*e4b17023SJohn Marino else
1684*e4b17023SJohn Marino all_prefix_attrs = prefix_attrs;
1685*e4b17023SJohn Marino continue;
1686*e4b17023SJohn Marino }
1687*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1688*e4b17023SJohn Marino {
1689*e4b17023SJohn Marino c_parser_consume_token (parser);
1690*e4b17023SJohn Marino return;
1691*e4b17023SJohn Marino }
1692*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_IN))
1693*e4b17023SJohn Marino {
1694*e4b17023SJohn Marino /* This can only happen in Objective-C: we found the
1695*e4b17023SJohn Marino 'in' that terminates the declaration inside an
1696*e4b17023SJohn Marino Objective-C foreach statement. Do not consume the
1697*e4b17023SJohn Marino token, so that the caller can use it to determine
1698*e4b17023SJohn Marino that this indeed is a foreach context. */
1699*e4b17023SJohn Marino return;
1700*e4b17023SJohn Marino }
1701*e4b17023SJohn Marino else
1702*e4b17023SJohn Marino {
1703*e4b17023SJohn Marino c_parser_error (parser, "expected %<,%> or %<;%>");
1704*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
1705*e4b17023SJohn Marino return;
1706*e4b17023SJohn Marino }
1707*e4b17023SJohn Marino }
1708*e4b17023SJohn Marino else if (!fndef_ok)
1709*e4b17023SJohn Marino {
1710*e4b17023SJohn Marino c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
1711*e4b17023SJohn Marino "%<asm%> or %<__attribute__%>");
1712*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
1713*e4b17023SJohn Marino return;
1714*e4b17023SJohn Marino }
1715*e4b17023SJohn Marino /* Function definition (nested or otherwise). */
1716*e4b17023SJohn Marino if (nested)
1717*e4b17023SJohn Marino {
1718*e4b17023SJohn Marino pedwarn (here, OPT_pedantic, "ISO C forbids nested functions");
1719*e4b17023SJohn Marino c_push_function_context ();
1720*e4b17023SJohn Marino }
1721*e4b17023SJohn Marino if (!start_function (specs, declarator, all_prefix_attrs))
1722*e4b17023SJohn Marino {
1723*e4b17023SJohn Marino /* This can appear in many cases looking nothing like a
1724*e4b17023SJohn Marino function definition, so we don't give a more specific
1725*e4b17023SJohn Marino error suggesting there was one. */
1726*e4b17023SJohn Marino c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
1727*e4b17023SJohn Marino "or %<__attribute__%>");
1728*e4b17023SJohn Marino if (nested)
1729*e4b17023SJohn Marino c_pop_function_context ();
1730*e4b17023SJohn Marino break;
1731*e4b17023SJohn Marino }
1732*e4b17023SJohn Marino
1733*e4b17023SJohn Marino if (DECL_DECLARED_INLINE_P (current_function_decl))
1734*e4b17023SJohn Marino tv = TV_PARSE_INLINE;
1735*e4b17023SJohn Marino else
1736*e4b17023SJohn Marino tv = TV_PARSE_FUNC;
1737*e4b17023SJohn Marino timevar_push (tv);
1738*e4b17023SJohn Marino
1739*e4b17023SJohn Marino /* Parse old-style parameter declarations. ??? Attributes are
1740*e4b17023SJohn Marino not allowed to start declaration specifiers here because of a
1741*e4b17023SJohn Marino syntax conflict between a function declaration with attribute
1742*e4b17023SJohn Marino suffix and a function definition with an attribute prefix on
1743*e4b17023SJohn Marino first old-style parameter declaration. Following the old
1744*e4b17023SJohn Marino parser, they are not accepted on subsequent old-style
1745*e4b17023SJohn Marino parameter declarations either. However, there is no
1746*e4b17023SJohn Marino ambiguity after the first declaration, nor indeed on the
1747*e4b17023SJohn Marino first as long as we don't allow postfix attributes after a
1748*e4b17023SJohn Marino declarator with a nonempty identifier list in a definition;
1749*e4b17023SJohn Marino and postfix attributes have never been accepted here in
1750*e4b17023SJohn Marino function definitions either. */
1751*e4b17023SJohn Marino while (c_parser_next_token_is_not (parser, CPP_EOF)
1752*e4b17023SJohn Marino && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
1753*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, false, false, false,
1754*e4b17023SJohn Marino true, false, NULL);
1755*e4b17023SJohn Marino store_parm_decls ();
1756*e4b17023SJohn Marino DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
1757*e4b17023SJohn Marino = c_parser_peek_token (parser)->location;
1758*e4b17023SJohn Marino fnbody = c_parser_compound_statement (parser);
1759*e4b17023SJohn Marino if (nested)
1760*e4b17023SJohn Marino {
1761*e4b17023SJohn Marino tree decl = current_function_decl;
1762*e4b17023SJohn Marino /* Mark nested functions as needing static-chain initially.
1763*e4b17023SJohn Marino lower_nested_functions will recompute it but the
1764*e4b17023SJohn Marino DECL_STATIC_CHAIN flag is also used before that happens,
1765*e4b17023SJohn Marino by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
1766*e4b17023SJohn Marino DECL_STATIC_CHAIN (decl) = 1;
1767*e4b17023SJohn Marino add_stmt (fnbody);
1768*e4b17023SJohn Marino finish_function ();
1769*e4b17023SJohn Marino c_pop_function_context ();
1770*e4b17023SJohn Marino add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
1771*e4b17023SJohn Marino }
1772*e4b17023SJohn Marino else
1773*e4b17023SJohn Marino {
1774*e4b17023SJohn Marino add_stmt (fnbody);
1775*e4b17023SJohn Marino finish_function ();
1776*e4b17023SJohn Marino }
1777*e4b17023SJohn Marino
1778*e4b17023SJohn Marino timevar_pop (tv);
1779*e4b17023SJohn Marino break;
1780*e4b17023SJohn Marino }
1781*e4b17023SJohn Marino }
1782*e4b17023SJohn Marino
1783*e4b17023SJohn Marino /* Parse an asm-definition (asm() outside a function body). This is a
1784*e4b17023SJohn Marino GNU extension.
1785*e4b17023SJohn Marino
1786*e4b17023SJohn Marino asm-definition:
1787*e4b17023SJohn Marino simple-asm-expr ;
1788*e4b17023SJohn Marino */
1789*e4b17023SJohn Marino
1790*e4b17023SJohn Marino static void
c_parser_asm_definition(c_parser * parser)1791*e4b17023SJohn Marino c_parser_asm_definition (c_parser *parser)
1792*e4b17023SJohn Marino {
1793*e4b17023SJohn Marino tree asm_str = c_parser_simple_asm_expr (parser);
1794*e4b17023SJohn Marino if (asm_str)
1795*e4b17023SJohn Marino cgraph_add_asm_node (asm_str);
1796*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
1797*e4b17023SJohn Marino }
1798*e4b17023SJohn Marino
1799*e4b17023SJohn Marino /* Parse a static assertion (C11 6.7.10).
1800*e4b17023SJohn Marino
1801*e4b17023SJohn Marino static_assert-declaration:
1802*e4b17023SJohn Marino static_assert-declaration-no-semi ;
1803*e4b17023SJohn Marino */
1804*e4b17023SJohn Marino
1805*e4b17023SJohn Marino static void
c_parser_static_assert_declaration(c_parser * parser)1806*e4b17023SJohn Marino c_parser_static_assert_declaration (c_parser *parser)
1807*e4b17023SJohn Marino {
1808*e4b17023SJohn Marino c_parser_static_assert_declaration_no_semi (parser);
1809*e4b17023SJohn Marino if (parser->error
1810*e4b17023SJohn Marino || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
1811*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
1812*e4b17023SJohn Marino }
1813*e4b17023SJohn Marino
1814*e4b17023SJohn Marino /* Parse a static assertion (C11 6.7.10), without the trailing
1815*e4b17023SJohn Marino semicolon.
1816*e4b17023SJohn Marino
1817*e4b17023SJohn Marino static_assert-declaration-no-semi:
1818*e4b17023SJohn Marino _Static_assert ( constant-expression , string-literal )
1819*e4b17023SJohn Marino */
1820*e4b17023SJohn Marino
1821*e4b17023SJohn Marino static void
c_parser_static_assert_declaration_no_semi(c_parser * parser)1822*e4b17023SJohn Marino c_parser_static_assert_declaration_no_semi (c_parser *parser)
1823*e4b17023SJohn Marino {
1824*e4b17023SJohn Marino location_t assert_loc, value_loc;
1825*e4b17023SJohn Marino tree value;
1826*e4b17023SJohn Marino tree string;
1827*e4b17023SJohn Marino
1828*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
1829*e4b17023SJohn Marino assert_loc = c_parser_peek_token (parser)->location;
1830*e4b17023SJohn Marino if (!flag_isoc11)
1831*e4b17023SJohn Marino {
1832*e4b17023SJohn Marino if (flag_isoc99)
1833*e4b17023SJohn Marino pedwarn (assert_loc, OPT_pedantic,
1834*e4b17023SJohn Marino "ISO C99 does not support %<_Static_assert%>");
1835*e4b17023SJohn Marino else
1836*e4b17023SJohn Marino pedwarn (assert_loc, OPT_pedantic,
1837*e4b17023SJohn Marino "ISO C90 does not support %<_Static_assert%>");
1838*e4b17023SJohn Marino }
1839*e4b17023SJohn Marino c_parser_consume_token (parser);
1840*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
1841*e4b17023SJohn Marino return;
1842*e4b17023SJohn Marino value_loc = c_parser_peek_token (parser)->location;
1843*e4b17023SJohn Marino value = c_parser_expr_no_commas (parser, NULL).value;
1844*e4b17023SJohn Marino parser->lex_untranslated_string = true;
1845*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
1846*e4b17023SJohn Marino {
1847*e4b17023SJohn Marino parser->lex_untranslated_string = false;
1848*e4b17023SJohn Marino return;
1849*e4b17023SJohn Marino }
1850*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
1851*e4b17023SJohn Marino {
1852*e4b17023SJohn Marino case CPP_STRING:
1853*e4b17023SJohn Marino case CPP_STRING16:
1854*e4b17023SJohn Marino case CPP_STRING32:
1855*e4b17023SJohn Marino case CPP_WSTRING:
1856*e4b17023SJohn Marino case CPP_UTF8STRING:
1857*e4b17023SJohn Marino string = c_parser_peek_token (parser)->value;
1858*e4b17023SJohn Marino c_parser_consume_token (parser);
1859*e4b17023SJohn Marino parser->lex_untranslated_string = false;
1860*e4b17023SJohn Marino break;
1861*e4b17023SJohn Marino default:
1862*e4b17023SJohn Marino c_parser_error (parser, "expected string literal");
1863*e4b17023SJohn Marino parser->lex_untranslated_string = false;
1864*e4b17023SJohn Marino return;
1865*e4b17023SJohn Marino }
1866*e4b17023SJohn Marino c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
1867*e4b17023SJohn Marino
1868*e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
1869*e4b17023SJohn Marino {
1870*e4b17023SJohn Marino error_at (value_loc, "expression in static assertion is not an integer");
1871*e4b17023SJohn Marino return;
1872*e4b17023SJohn Marino }
1873*e4b17023SJohn Marino if (TREE_CODE (value) != INTEGER_CST)
1874*e4b17023SJohn Marino {
1875*e4b17023SJohn Marino value = c_fully_fold (value, false, NULL);
1876*e4b17023SJohn Marino if (TREE_CODE (value) == INTEGER_CST)
1877*e4b17023SJohn Marino pedwarn (value_loc, OPT_pedantic, "expression in static assertion "
1878*e4b17023SJohn Marino "is not an integer constant expression");
1879*e4b17023SJohn Marino }
1880*e4b17023SJohn Marino if (TREE_CODE (value) != INTEGER_CST)
1881*e4b17023SJohn Marino {
1882*e4b17023SJohn Marino error_at (value_loc, "expression in static assertion is not constant");
1883*e4b17023SJohn Marino return;
1884*e4b17023SJohn Marino }
1885*e4b17023SJohn Marino constant_expression_warning (value);
1886*e4b17023SJohn Marino if (integer_zerop (value))
1887*e4b17023SJohn Marino error_at (assert_loc, "static assertion failed: %E", string);
1888*e4b17023SJohn Marino }
1889*e4b17023SJohn Marino
1890*e4b17023SJohn Marino /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
1891*e4b17023SJohn Marino 6.7), adding them to SPECS (which may already include some).
1892*e4b17023SJohn Marino Storage class specifiers are accepted iff SCSPEC_OK; type
1893*e4b17023SJohn Marino specifiers are accepted iff TYPESPEC_OK; attributes are accepted at
1894*e4b17023SJohn Marino the start iff START_ATTR_OK.
1895*e4b17023SJohn Marino
1896*e4b17023SJohn Marino declaration-specifiers:
1897*e4b17023SJohn Marino storage-class-specifier declaration-specifiers[opt]
1898*e4b17023SJohn Marino type-specifier declaration-specifiers[opt]
1899*e4b17023SJohn Marino type-qualifier declaration-specifiers[opt]
1900*e4b17023SJohn Marino function-specifier declaration-specifiers[opt]
1901*e4b17023SJohn Marino alignment-specifier declaration-specifiers[opt]
1902*e4b17023SJohn Marino
1903*e4b17023SJohn Marino Function specifiers (inline) are from C99, and are currently
1904*e4b17023SJohn Marino handled as storage class specifiers, as is __thread. Alignment
1905*e4b17023SJohn Marino specifiers are from C11.
1906*e4b17023SJohn Marino
1907*e4b17023SJohn Marino C90 6.5.1, C99 6.7.1:
1908*e4b17023SJohn Marino storage-class-specifier:
1909*e4b17023SJohn Marino typedef
1910*e4b17023SJohn Marino extern
1911*e4b17023SJohn Marino static
1912*e4b17023SJohn Marino auto
1913*e4b17023SJohn Marino register
1914*e4b17023SJohn Marino
1915*e4b17023SJohn Marino C99 6.7.4:
1916*e4b17023SJohn Marino function-specifier:
1917*e4b17023SJohn Marino inline
1918*e4b17023SJohn Marino _Noreturn
1919*e4b17023SJohn Marino
1920*e4b17023SJohn Marino (_Noreturn is new in C11.)
1921*e4b17023SJohn Marino
1922*e4b17023SJohn Marino C90 6.5.2, C99 6.7.2:
1923*e4b17023SJohn Marino type-specifier:
1924*e4b17023SJohn Marino void
1925*e4b17023SJohn Marino char
1926*e4b17023SJohn Marino short
1927*e4b17023SJohn Marino int
1928*e4b17023SJohn Marino long
1929*e4b17023SJohn Marino float
1930*e4b17023SJohn Marino double
1931*e4b17023SJohn Marino signed
1932*e4b17023SJohn Marino unsigned
1933*e4b17023SJohn Marino _Bool
1934*e4b17023SJohn Marino _Complex
1935*e4b17023SJohn Marino [_Imaginary removed in C99 TC2]
1936*e4b17023SJohn Marino struct-or-union-specifier
1937*e4b17023SJohn Marino enum-specifier
1938*e4b17023SJohn Marino typedef-name
1939*e4b17023SJohn Marino
1940*e4b17023SJohn Marino (_Bool and _Complex are new in C99.)
1941*e4b17023SJohn Marino
1942*e4b17023SJohn Marino C90 6.5.3, C99 6.7.3:
1943*e4b17023SJohn Marino
1944*e4b17023SJohn Marino type-qualifier:
1945*e4b17023SJohn Marino const
1946*e4b17023SJohn Marino restrict
1947*e4b17023SJohn Marino volatile
1948*e4b17023SJohn Marino address-space-qualifier
1949*e4b17023SJohn Marino
1950*e4b17023SJohn Marino (restrict is new in C99.)
1951*e4b17023SJohn Marino
1952*e4b17023SJohn Marino GNU extensions:
1953*e4b17023SJohn Marino
1954*e4b17023SJohn Marino declaration-specifiers:
1955*e4b17023SJohn Marino attributes declaration-specifiers[opt]
1956*e4b17023SJohn Marino
1957*e4b17023SJohn Marino type-qualifier:
1958*e4b17023SJohn Marino address-space
1959*e4b17023SJohn Marino
1960*e4b17023SJohn Marino address-space:
1961*e4b17023SJohn Marino identifier recognized by the target
1962*e4b17023SJohn Marino
1963*e4b17023SJohn Marino storage-class-specifier:
1964*e4b17023SJohn Marino __thread
1965*e4b17023SJohn Marino
1966*e4b17023SJohn Marino type-specifier:
1967*e4b17023SJohn Marino typeof-specifier
1968*e4b17023SJohn Marino __int128
1969*e4b17023SJohn Marino _Decimal32
1970*e4b17023SJohn Marino _Decimal64
1971*e4b17023SJohn Marino _Decimal128
1972*e4b17023SJohn Marino _Fract
1973*e4b17023SJohn Marino _Accum
1974*e4b17023SJohn Marino _Sat
1975*e4b17023SJohn Marino
1976*e4b17023SJohn Marino (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
1977*e4b17023SJohn Marino http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
1978*e4b17023SJohn Marino
1979*e4b17023SJohn Marino Objective-C:
1980*e4b17023SJohn Marino
1981*e4b17023SJohn Marino type-specifier:
1982*e4b17023SJohn Marino class-name objc-protocol-refs[opt]
1983*e4b17023SJohn Marino typedef-name objc-protocol-refs
1984*e4b17023SJohn Marino objc-protocol-refs
1985*e4b17023SJohn Marino */
1986*e4b17023SJohn Marino
1987*e4b17023SJohn Marino static void
c_parser_declspecs(c_parser * parser,struct c_declspecs * specs,bool scspec_ok,bool typespec_ok,bool start_attr_ok,enum c_lookahead_kind la)1988*e4b17023SJohn Marino c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
1989*e4b17023SJohn Marino bool scspec_ok, bool typespec_ok, bool start_attr_ok,
1990*e4b17023SJohn Marino enum c_lookahead_kind la)
1991*e4b17023SJohn Marino {
1992*e4b17023SJohn Marino bool attrs_ok = start_attr_ok;
1993*e4b17023SJohn Marino bool seen_type = specs->typespec_kind != ctsk_none;
1994*e4b17023SJohn Marino
1995*e4b17023SJohn Marino if (!typespec_ok)
1996*e4b17023SJohn Marino gcc_assert (la == cla_prefer_id);
1997*e4b17023SJohn Marino
1998*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_NAME)
1999*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_KEYWORD)
2000*e4b17023SJohn Marino || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2001*e4b17023SJohn Marino {
2002*e4b17023SJohn Marino struct c_typespec t;
2003*e4b17023SJohn Marino tree attrs;
2004*e4b17023SJohn Marino tree align;
2005*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
2006*e4b17023SJohn Marino
2007*e4b17023SJohn Marino /* If we cannot accept a type, exit if the next token must start
2008*e4b17023SJohn Marino one. Also, if we already have seen a tagged definition,
2009*e4b17023SJohn Marino a typename would be an error anyway and likely the user
2010*e4b17023SJohn Marino has simply forgotten a semicolon, so we exit. */
2011*e4b17023SJohn Marino if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2012*e4b17023SJohn Marino && c_parser_next_tokens_start_typename (parser, la)
2013*e4b17023SJohn Marino && !c_parser_next_token_is_qualifier (parser))
2014*e4b17023SJohn Marino break;
2015*e4b17023SJohn Marino
2016*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
2017*e4b17023SJohn Marino {
2018*e4b17023SJohn Marino tree value = c_parser_peek_token (parser)->value;
2019*e4b17023SJohn Marino c_id_kind kind = c_parser_peek_token (parser)->id_kind;
2020*e4b17023SJohn Marino
2021*e4b17023SJohn Marino if (kind == C_ID_ADDRSPACE)
2022*e4b17023SJohn Marino {
2023*e4b17023SJohn Marino addr_space_t as
2024*e4b17023SJohn Marino = c_parser_peek_token (parser)->keyword - RID_FIRST_ADDR_SPACE;
2025*e4b17023SJohn Marino declspecs_add_addrspace (specs, as);
2026*e4b17023SJohn Marino c_parser_consume_token (parser);
2027*e4b17023SJohn Marino attrs_ok = true;
2028*e4b17023SJohn Marino continue;
2029*e4b17023SJohn Marino }
2030*e4b17023SJohn Marino
2031*e4b17023SJohn Marino gcc_assert (!c_parser_next_token_is_qualifier (parser));
2032*e4b17023SJohn Marino
2033*e4b17023SJohn Marino /* If we cannot accept a type, and the next token must start one,
2034*e4b17023SJohn Marino exit. Do the same if we already have seen a tagged definition,
2035*e4b17023SJohn Marino since it would be an error anyway and likely the user has simply
2036*e4b17023SJohn Marino forgotten a semicolon. */
2037*e4b17023SJohn Marino if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2038*e4b17023SJohn Marino break;
2039*e4b17023SJohn Marino
2040*e4b17023SJohn Marino /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2041*e4b17023SJohn Marino a C_ID_CLASSNAME. */
2042*e4b17023SJohn Marino c_parser_consume_token (parser);
2043*e4b17023SJohn Marino seen_type = true;
2044*e4b17023SJohn Marino attrs_ok = true;
2045*e4b17023SJohn Marino if (kind == C_ID_ID)
2046*e4b17023SJohn Marino {
2047*e4b17023SJohn Marino error ("unknown type name %qE", value);
2048*e4b17023SJohn Marino t.kind = ctsk_typedef;
2049*e4b17023SJohn Marino t.spec = error_mark_node;
2050*e4b17023SJohn Marino }
2051*e4b17023SJohn Marino else if (kind == C_ID_TYPENAME
2052*e4b17023SJohn Marino && (!c_dialect_objc ()
2053*e4b17023SJohn Marino || c_parser_next_token_is_not (parser, CPP_LESS)))
2054*e4b17023SJohn Marino {
2055*e4b17023SJohn Marino t.kind = ctsk_typedef;
2056*e4b17023SJohn Marino /* For a typedef name, record the meaning, not the name.
2057*e4b17023SJohn Marino In case of 'foo foo, bar;'. */
2058*e4b17023SJohn Marino t.spec = lookup_name (value);
2059*e4b17023SJohn Marino }
2060*e4b17023SJohn Marino else
2061*e4b17023SJohn Marino {
2062*e4b17023SJohn Marino tree proto = NULL_TREE;
2063*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
2064*e4b17023SJohn Marino t.kind = ctsk_objc;
2065*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_LESS))
2066*e4b17023SJohn Marino proto = c_parser_objc_protocol_refs (parser);
2067*e4b17023SJohn Marino t.spec = objc_get_protocol_qualified_type (value, proto);
2068*e4b17023SJohn Marino }
2069*e4b17023SJohn Marino t.expr = NULL_TREE;
2070*e4b17023SJohn Marino t.expr_const_operands = true;
2071*e4b17023SJohn Marino declspecs_add_type (loc, specs, t);
2072*e4b17023SJohn Marino continue;
2073*e4b17023SJohn Marino }
2074*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_LESS))
2075*e4b17023SJohn Marino {
2076*e4b17023SJohn Marino /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2077*e4b17023SJohn Marino nisse@lysator.liu.se. */
2078*e4b17023SJohn Marino tree proto;
2079*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
2080*e4b17023SJohn Marino if (!typespec_ok || seen_type)
2081*e4b17023SJohn Marino break;
2082*e4b17023SJohn Marino proto = c_parser_objc_protocol_refs (parser);
2083*e4b17023SJohn Marino t.kind = ctsk_objc;
2084*e4b17023SJohn Marino t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2085*e4b17023SJohn Marino t.expr = NULL_TREE;
2086*e4b17023SJohn Marino t.expr_const_operands = true;
2087*e4b17023SJohn Marino declspecs_add_type (loc, specs, t);
2088*e4b17023SJohn Marino continue;
2089*e4b17023SJohn Marino }
2090*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2091*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->keyword)
2092*e4b17023SJohn Marino {
2093*e4b17023SJohn Marino case RID_STATIC:
2094*e4b17023SJohn Marino case RID_EXTERN:
2095*e4b17023SJohn Marino case RID_REGISTER:
2096*e4b17023SJohn Marino case RID_TYPEDEF:
2097*e4b17023SJohn Marino case RID_INLINE:
2098*e4b17023SJohn Marino case RID_NORETURN:
2099*e4b17023SJohn Marino case RID_AUTO:
2100*e4b17023SJohn Marino case RID_THREAD:
2101*e4b17023SJohn Marino if (!scspec_ok)
2102*e4b17023SJohn Marino goto out;
2103*e4b17023SJohn Marino attrs_ok = true;
2104*e4b17023SJohn Marino /* TODO: Distinguish between function specifiers (inline, noreturn)
2105*e4b17023SJohn Marino and storage class specifiers, either here or in
2106*e4b17023SJohn Marino declspecs_add_scspec. */
2107*e4b17023SJohn Marino declspecs_add_scspec (specs, c_parser_peek_token (parser)->value);
2108*e4b17023SJohn Marino c_parser_consume_token (parser);
2109*e4b17023SJohn Marino break;
2110*e4b17023SJohn Marino case RID_UNSIGNED:
2111*e4b17023SJohn Marino case RID_LONG:
2112*e4b17023SJohn Marino case RID_INT128:
2113*e4b17023SJohn Marino case RID_SHORT:
2114*e4b17023SJohn Marino case RID_SIGNED:
2115*e4b17023SJohn Marino case RID_COMPLEX:
2116*e4b17023SJohn Marino case RID_INT:
2117*e4b17023SJohn Marino case RID_CHAR:
2118*e4b17023SJohn Marino case RID_FLOAT:
2119*e4b17023SJohn Marino case RID_DOUBLE:
2120*e4b17023SJohn Marino case RID_VOID:
2121*e4b17023SJohn Marino case RID_DFLOAT32:
2122*e4b17023SJohn Marino case RID_DFLOAT64:
2123*e4b17023SJohn Marino case RID_DFLOAT128:
2124*e4b17023SJohn Marino case RID_BOOL:
2125*e4b17023SJohn Marino case RID_FRACT:
2126*e4b17023SJohn Marino case RID_ACCUM:
2127*e4b17023SJohn Marino case RID_SAT:
2128*e4b17023SJohn Marino if (!typespec_ok)
2129*e4b17023SJohn Marino goto out;
2130*e4b17023SJohn Marino attrs_ok = true;
2131*e4b17023SJohn Marino seen_type = true;
2132*e4b17023SJohn Marino if (c_dialect_objc ())
2133*e4b17023SJohn Marino parser->objc_need_raw_identifier = true;
2134*e4b17023SJohn Marino t.kind = ctsk_resword;
2135*e4b17023SJohn Marino t.spec = c_parser_peek_token (parser)->value;
2136*e4b17023SJohn Marino t.expr = NULL_TREE;
2137*e4b17023SJohn Marino t.expr_const_operands = true;
2138*e4b17023SJohn Marino declspecs_add_type (loc, specs, t);
2139*e4b17023SJohn Marino c_parser_consume_token (parser);
2140*e4b17023SJohn Marino break;
2141*e4b17023SJohn Marino case RID_ENUM:
2142*e4b17023SJohn Marino if (!typespec_ok)
2143*e4b17023SJohn Marino goto out;
2144*e4b17023SJohn Marino attrs_ok = true;
2145*e4b17023SJohn Marino seen_type = true;
2146*e4b17023SJohn Marino t = c_parser_enum_specifier (parser);
2147*e4b17023SJohn Marino declspecs_add_type (loc, specs, t);
2148*e4b17023SJohn Marino break;
2149*e4b17023SJohn Marino case RID_STRUCT:
2150*e4b17023SJohn Marino case RID_UNION:
2151*e4b17023SJohn Marino if (!typespec_ok)
2152*e4b17023SJohn Marino goto out;
2153*e4b17023SJohn Marino attrs_ok = true;
2154*e4b17023SJohn Marino seen_type = true;
2155*e4b17023SJohn Marino t = c_parser_struct_or_union_specifier (parser);
2156*e4b17023SJohn Marino invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2157*e4b17023SJohn Marino declspecs_add_type (loc, specs, t);
2158*e4b17023SJohn Marino break;
2159*e4b17023SJohn Marino case RID_TYPEOF:
2160*e4b17023SJohn Marino /* ??? The old parser rejected typeof after other type
2161*e4b17023SJohn Marino specifiers, but is a syntax error the best way of
2162*e4b17023SJohn Marino handling this? */
2163*e4b17023SJohn Marino if (!typespec_ok || seen_type)
2164*e4b17023SJohn Marino goto out;
2165*e4b17023SJohn Marino attrs_ok = true;
2166*e4b17023SJohn Marino seen_type = true;
2167*e4b17023SJohn Marino t = c_parser_typeof_specifier (parser);
2168*e4b17023SJohn Marino declspecs_add_type (loc, specs, t);
2169*e4b17023SJohn Marino break;
2170*e4b17023SJohn Marino case RID_CONST:
2171*e4b17023SJohn Marino case RID_VOLATILE:
2172*e4b17023SJohn Marino case RID_RESTRICT:
2173*e4b17023SJohn Marino attrs_ok = true;
2174*e4b17023SJohn Marino declspecs_add_qual (specs, c_parser_peek_token (parser)->value);
2175*e4b17023SJohn Marino c_parser_consume_token (parser);
2176*e4b17023SJohn Marino break;
2177*e4b17023SJohn Marino case RID_ATTRIBUTE:
2178*e4b17023SJohn Marino if (!attrs_ok)
2179*e4b17023SJohn Marino goto out;
2180*e4b17023SJohn Marino attrs = c_parser_attributes (parser);
2181*e4b17023SJohn Marino declspecs_add_attrs (specs, attrs);
2182*e4b17023SJohn Marino break;
2183*e4b17023SJohn Marino case RID_ALIGNAS:
2184*e4b17023SJohn Marino align = c_parser_alignas_specifier (parser);
2185*e4b17023SJohn Marino declspecs_add_alignas (specs, align);
2186*e4b17023SJohn Marino break;
2187*e4b17023SJohn Marino default:
2188*e4b17023SJohn Marino goto out;
2189*e4b17023SJohn Marino }
2190*e4b17023SJohn Marino }
2191*e4b17023SJohn Marino out: ;
2192*e4b17023SJohn Marino }
2193*e4b17023SJohn Marino
2194*e4b17023SJohn Marino /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2).
2195*e4b17023SJohn Marino
2196*e4b17023SJohn Marino enum-specifier:
2197*e4b17023SJohn Marino enum attributes[opt] identifier[opt] { enumerator-list } attributes[opt]
2198*e4b17023SJohn Marino enum attributes[opt] identifier[opt] { enumerator-list , } attributes[opt]
2199*e4b17023SJohn Marino enum attributes[opt] identifier
2200*e4b17023SJohn Marino
2201*e4b17023SJohn Marino The form with trailing comma is new in C99. The forms with
2202*e4b17023SJohn Marino attributes are GNU extensions. In GNU C, we accept any expression
2203*e4b17023SJohn Marino without commas in the syntax (assignment expressions, not just
2204*e4b17023SJohn Marino conditional expressions); assignment expressions will be diagnosed
2205*e4b17023SJohn Marino as non-constant.
2206*e4b17023SJohn Marino
2207*e4b17023SJohn Marino enumerator-list:
2208*e4b17023SJohn Marino enumerator
2209*e4b17023SJohn Marino enumerator-list , enumerator
2210*e4b17023SJohn Marino
2211*e4b17023SJohn Marino enumerator:
2212*e4b17023SJohn Marino enumeration-constant
2213*e4b17023SJohn Marino enumeration-constant = constant-expression
2214*e4b17023SJohn Marino */
2215*e4b17023SJohn Marino
2216*e4b17023SJohn Marino static struct c_typespec
c_parser_enum_specifier(c_parser * parser)2217*e4b17023SJohn Marino c_parser_enum_specifier (c_parser *parser)
2218*e4b17023SJohn Marino {
2219*e4b17023SJohn Marino struct c_typespec ret;
2220*e4b17023SJohn Marino tree attrs;
2221*e4b17023SJohn Marino tree ident = NULL_TREE;
2222*e4b17023SJohn Marino location_t enum_loc;
2223*e4b17023SJohn Marino location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
2224*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
2225*e4b17023SJohn Marino enum_loc = c_parser_peek_token (parser)->location;
2226*e4b17023SJohn Marino c_parser_consume_token (parser);
2227*e4b17023SJohn Marino attrs = c_parser_attributes (parser);
2228*e4b17023SJohn Marino enum_loc = c_parser_peek_token (parser)->location;
2229*e4b17023SJohn Marino /* Set the location in case we create a decl now. */
2230*e4b17023SJohn Marino c_parser_set_source_position_from_token (c_parser_peek_token (parser));
2231*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
2232*e4b17023SJohn Marino {
2233*e4b17023SJohn Marino ident = c_parser_peek_token (parser)->value;
2234*e4b17023SJohn Marino ident_loc = c_parser_peek_token (parser)->location;
2235*e4b17023SJohn Marino enum_loc = ident_loc;
2236*e4b17023SJohn Marino c_parser_consume_token (parser);
2237*e4b17023SJohn Marino }
2238*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2239*e4b17023SJohn Marino {
2240*e4b17023SJohn Marino /* Parse an enum definition. */
2241*e4b17023SJohn Marino struct c_enum_contents the_enum;
2242*e4b17023SJohn Marino tree type;
2243*e4b17023SJohn Marino tree postfix_attrs;
2244*e4b17023SJohn Marino /* We chain the enumerators in reverse order, then put them in
2245*e4b17023SJohn Marino forward order at the end. */
2246*e4b17023SJohn Marino tree values;
2247*e4b17023SJohn Marino timevar_push (TV_PARSE_ENUM);
2248*e4b17023SJohn Marino type = start_enum (enum_loc, &the_enum, ident);
2249*e4b17023SJohn Marino values = NULL_TREE;
2250*e4b17023SJohn Marino c_parser_consume_token (parser);
2251*e4b17023SJohn Marino while (true)
2252*e4b17023SJohn Marino {
2253*e4b17023SJohn Marino tree enum_id;
2254*e4b17023SJohn Marino tree enum_value;
2255*e4b17023SJohn Marino tree enum_decl;
2256*e4b17023SJohn Marino bool seen_comma;
2257*e4b17023SJohn Marino c_token *token;
2258*e4b17023SJohn Marino location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
2259*e4b17023SJohn Marino location_t decl_loc, value_loc;
2260*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
2261*e4b17023SJohn Marino {
2262*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
2263*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
2264*e4b17023SJohn Marino values = error_mark_node;
2265*e4b17023SJohn Marino break;
2266*e4b17023SJohn Marino }
2267*e4b17023SJohn Marino token = c_parser_peek_token (parser);
2268*e4b17023SJohn Marino enum_id = token->value;
2269*e4b17023SJohn Marino /* Set the location in case we create a decl now. */
2270*e4b17023SJohn Marino c_parser_set_source_position_from_token (token);
2271*e4b17023SJohn Marino decl_loc = value_loc = token->location;
2272*e4b17023SJohn Marino c_parser_consume_token (parser);
2273*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_EQ))
2274*e4b17023SJohn Marino {
2275*e4b17023SJohn Marino c_parser_consume_token (parser);
2276*e4b17023SJohn Marino value_loc = c_parser_peek_token (parser)->location;
2277*e4b17023SJohn Marino enum_value = c_parser_expr_no_commas (parser, NULL).value;
2278*e4b17023SJohn Marino }
2279*e4b17023SJohn Marino else
2280*e4b17023SJohn Marino enum_value = NULL_TREE;
2281*e4b17023SJohn Marino enum_decl = build_enumerator (decl_loc, value_loc,
2282*e4b17023SJohn Marino &the_enum, enum_id, enum_value);
2283*e4b17023SJohn Marino TREE_CHAIN (enum_decl) = values;
2284*e4b17023SJohn Marino values = enum_decl;
2285*e4b17023SJohn Marino seen_comma = false;
2286*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
2287*e4b17023SJohn Marino {
2288*e4b17023SJohn Marino comma_loc = c_parser_peek_token (parser)->location;
2289*e4b17023SJohn Marino seen_comma = true;
2290*e4b17023SJohn Marino c_parser_consume_token (parser);
2291*e4b17023SJohn Marino }
2292*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2293*e4b17023SJohn Marino {
2294*e4b17023SJohn Marino if (seen_comma && !flag_isoc99)
2295*e4b17023SJohn Marino pedwarn (comma_loc, OPT_pedantic, "comma at end of enumerator list");
2296*e4b17023SJohn Marino c_parser_consume_token (parser);
2297*e4b17023SJohn Marino break;
2298*e4b17023SJohn Marino }
2299*e4b17023SJohn Marino if (!seen_comma)
2300*e4b17023SJohn Marino {
2301*e4b17023SJohn Marino c_parser_error (parser, "expected %<,%> or %<}%>");
2302*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
2303*e4b17023SJohn Marino values = error_mark_node;
2304*e4b17023SJohn Marino break;
2305*e4b17023SJohn Marino }
2306*e4b17023SJohn Marino }
2307*e4b17023SJohn Marino postfix_attrs = c_parser_attributes (parser);
2308*e4b17023SJohn Marino ret.spec = finish_enum (type, nreverse (values),
2309*e4b17023SJohn Marino chainon (attrs, postfix_attrs));
2310*e4b17023SJohn Marino ret.kind = ctsk_tagdef;
2311*e4b17023SJohn Marino ret.expr = NULL_TREE;
2312*e4b17023SJohn Marino ret.expr_const_operands = true;
2313*e4b17023SJohn Marino timevar_pop (TV_PARSE_ENUM);
2314*e4b17023SJohn Marino return ret;
2315*e4b17023SJohn Marino }
2316*e4b17023SJohn Marino else if (!ident)
2317*e4b17023SJohn Marino {
2318*e4b17023SJohn Marino c_parser_error (parser, "expected %<{%>");
2319*e4b17023SJohn Marino ret.spec = error_mark_node;
2320*e4b17023SJohn Marino ret.kind = ctsk_tagref;
2321*e4b17023SJohn Marino ret.expr = NULL_TREE;
2322*e4b17023SJohn Marino ret.expr_const_operands = true;
2323*e4b17023SJohn Marino return ret;
2324*e4b17023SJohn Marino }
2325*e4b17023SJohn Marino ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident);
2326*e4b17023SJohn Marino /* In ISO C, enumerated types can be referred to only if already
2327*e4b17023SJohn Marino defined. */
2328*e4b17023SJohn Marino if (pedantic && !COMPLETE_TYPE_P (ret.spec))
2329*e4b17023SJohn Marino {
2330*e4b17023SJohn Marino gcc_assert (ident);
2331*e4b17023SJohn Marino pedwarn (enum_loc, OPT_pedantic,
2332*e4b17023SJohn Marino "ISO C forbids forward references to %<enum%> types");
2333*e4b17023SJohn Marino }
2334*e4b17023SJohn Marino return ret;
2335*e4b17023SJohn Marino }
2336*e4b17023SJohn Marino
2337*e4b17023SJohn Marino /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1).
2338*e4b17023SJohn Marino
2339*e4b17023SJohn Marino struct-or-union-specifier:
2340*e4b17023SJohn Marino struct-or-union attributes[opt] identifier[opt]
2341*e4b17023SJohn Marino { struct-contents } attributes[opt]
2342*e4b17023SJohn Marino struct-or-union attributes[opt] identifier
2343*e4b17023SJohn Marino
2344*e4b17023SJohn Marino struct-contents:
2345*e4b17023SJohn Marino struct-declaration-list
2346*e4b17023SJohn Marino
2347*e4b17023SJohn Marino struct-declaration-list:
2348*e4b17023SJohn Marino struct-declaration ;
2349*e4b17023SJohn Marino struct-declaration-list struct-declaration ;
2350*e4b17023SJohn Marino
2351*e4b17023SJohn Marino GNU extensions:
2352*e4b17023SJohn Marino
2353*e4b17023SJohn Marino struct-contents:
2354*e4b17023SJohn Marino empty
2355*e4b17023SJohn Marino struct-declaration
2356*e4b17023SJohn Marino struct-declaration-list struct-declaration
2357*e4b17023SJohn Marino
2358*e4b17023SJohn Marino struct-declaration-list:
2359*e4b17023SJohn Marino struct-declaration-list ;
2360*e4b17023SJohn Marino ;
2361*e4b17023SJohn Marino
2362*e4b17023SJohn Marino (Note that in the syntax here, unlike that in ISO C, the semicolons
2363*e4b17023SJohn Marino are included here rather than in struct-declaration, in order to
2364*e4b17023SJohn Marino describe the syntax with extra semicolons and missing semicolon at
2365*e4b17023SJohn Marino end.)
2366*e4b17023SJohn Marino
2367*e4b17023SJohn Marino Objective-C:
2368*e4b17023SJohn Marino
2369*e4b17023SJohn Marino struct-declaration-list:
2370*e4b17023SJohn Marino @defs ( class-name )
2371*e4b17023SJohn Marino
2372*e4b17023SJohn Marino (Note this does not include a trailing semicolon, but can be
2373*e4b17023SJohn Marino followed by further declarations, and gets a pedwarn-if-pedantic
2374*e4b17023SJohn Marino when followed by a semicolon.) */
2375*e4b17023SJohn Marino
2376*e4b17023SJohn Marino static struct c_typespec
c_parser_struct_or_union_specifier(c_parser * parser)2377*e4b17023SJohn Marino c_parser_struct_or_union_specifier (c_parser *parser)
2378*e4b17023SJohn Marino {
2379*e4b17023SJohn Marino struct c_typespec ret;
2380*e4b17023SJohn Marino tree attrs;
2381*e4b17023SJohn Marino tree ident = NULL_TREE;
2382*e4b17023SJohn Marino location_t struct_loc;
2383*e4b17023SJohn Marino location_t ident_loc = UNKNOWN_LOCATION;
2384*e4b17023SJohn Marino enum tree_code code;
2385*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->keyword)
2386*e4b17023SJohn Marino {
2387*e4b17023SJohn Marino case RID_STRUCT:
2388*e4b17023SJohn Marino code = RECORD_TYPE;
2389*e4b17023SJohn Marino break;
2390*e4b17023SJohn Marino case RID_UNION:
2391*e4b17023SJohn Marino code = UNION_TYPE;
2392*e4b17023SJohn Marino break;
2393*e4b17023SJohn Marino default:
2394*e4b17023SJohn Marino gcc_unreachable ();
2395*e4b17023SJohn Marino }
2396*e4b17023SJohn Marino struct_loc = c_parser_peek_token (parser)->location;
2397*e4b17023SJohn Marino c_parser_consume_token (parser);
2398*e4b17023SJohn Marino attrs = c_parser_attributes (parser);
2399*e4b17023SJohn Marino
2400*e4b17023SJohn Marino /* Set the location in case we create a decl now. */
2401*e4b17023SJohn Marino c_parser_set_source_position_from_token (c_parser_peek_token (parser));
2402*e4b17023SJohn Marino
2403*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
2404*e4b17023SJohn Marino {
2405*e4b17023SJohn Marino ident = c_parser_peek_token (parser)->value;
2406*e4b17023SJohn Marino ident_loc = c_parser_peek_token (parser)->location;
2407*e4b17023SJohn Marino struct_loc = ident_loc;
2408*e4b17023SJohn Marino c_parser_consume_token (parser);
2409*e4b17023SJohn Marino }
2410*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2411*e4b17023SJohn Marino {
2412*e4b17023SJohn Marino /* Parse a struct or union definition. Start the scope of the
2413*e4b17023SJohn Marino tag before parsing components. */
2414*e4b17023SJohn Marino struct c_struct_parse_info *struct_info;
2415*e4b17023SJohn Marino tree type = start_struct (struct_loc, code, ident, &struct_info);
2416*e4b17023SJohn Marino tree postfix_attrs;
2417*e4b17023SJohn Marino /* We chain the components in reverse order, then put them in
2418*e4b17023SJohn Marino forward order at the end. Each struct-declaration may
2419*e4b17023SJohn Marino declare multiple components (comma-separated), so we must use
2420*e4b17023SJohn Marino chainon to join them, although when parsing each
2421*e4b17023SJohn Marino struct-declaration we can use TREE_CHAIN directly.
2422*e4b17023SJohn Marino
2423*e4b17023SJohn Marino The theory behind all this is that there will be more
2424*e4b17023SJohn Marino semicolon separated fields than comma separated fields, and
2425*e4b17023SJohn Marino so we'll be minimizing the number of node traversals required
2426*e4b17023SJohn Marino by chainon. */
2427*e4b17023SJohn Marino tree contents;
2428*e4b17023SJohn Marino timevar_push (TV_PARSE_STRUCT);
2429*e4b17023SJohn Marino contents = NULL_TREE;
2430*e4b17023SJohn Marino c_parser_consume_token (parser);
2431*e4b17023SJohn Marino /* Handle the Objective-C @defs construct,
2432*e4b17023SJohn Marino e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
2433*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
2434*e4b17023SJohn Marino {
2435*e4b17023SJohn Marino tree name;
2436*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
2437*e4b17023SJohn Marino c_parser_consume_token (parser);
2438*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2439*e4b17023SJohn Marino goto end_at_defs;
2440*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME)
2441*e4b17023SJohn Marino && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
2442*e4b17023SJohn Marino {
2443*e4b17023SJohn Marino name = c_parser_peek_token (parser)->value;
2444*e4b17023SJohn Marino c_parser_consume_token (parser);
2445*e4b17023SJohn Marino }
2446*e4b17023SJohn Marino else
2447*e4b17023SJohn Marino {
2448*e4b17023SJohn Marino c_parser_error (parser, "expected class name");
2449*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
2450*e4b17023SJohn Marino goto end_at_defs;
2451*e4b17023SJohn Marino }
2452*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2453*e4b17023SJohn Marino "expected %<)%>");
2454*e4b17023SJohn Marino contents = nreverse (objc_get_class_ivars (name));
2455*e4b17023SJohn Marino }
2456*e4b17023SJohn Marino end_at_defs:
2457*e4b17023SJohn Marino /* Parse the struct-declarations and semicolons. Problems with
2458*e4b17023SJohn Marino semicolons are diagnosed here; empty structures are diagnosed
2459*e4b17023SJohn Marino elsewhere. */
2460*e4b17023SJohn Marino while (true)
2461*e4b17023SJohn Marino {
2462*e4b17023SJohn Marino tree decls;
2463*e4b17023SJohn Marino /* Parse any stray semicolon. */
2464*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2465*e4b17023SJohn Marino {
2466*e4b17023SJohn Marino pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
2467*e4b17023SJohn Marino "extra semicolon in struct or union specified");
2468*e4b17023SJohn Marino c_parser_consume_token (parser);
2469*e4b17023SJohn Marino continue;
2470*e4b17023SJohn Marino }
2471*e4b17023SJohn Marino /* Stop if at the end of the struct or union contents. */
2472*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2473*e4b17023SJohn Marino {
2474*e4b17023SJohn Marino c_parser_consume_token (parser);
2475*e4b17023SJohn Marino break;
2476*e4b17023SJohn Marino }
2477*e4b17023SJohn Marino /* Accept #pragmas at struct scope. */
2478*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_PRAGMA))
2479*e4b17023SJohn Marino {
2480*e4b17023SJohn Marino c_parser_pragma (parser, pragma_external);
2481*e4b17023SJohn Marino continue;
2482*e4b17023SJohn Marino }
2483*e4b17023SJohn Marino /* Parse some comma-separated declarations, but not the
2484*e4b17023SJohn Marino trailing semicolon if any. */
2485*e4b17023SJohn Marino decls = c_parser_struct_declaration (parser);
2486*e4b17023SJohn Marino contents = chainon (decls, contents);
2487*e4b17023SJohn Marino /* If no semicolon follows, either we have a parse error or
2488*e4b17023SJohn Marino are at the end of the struct or union and should
2489*e4b17023SJohn Marino pedwarn. */
2490*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2491*e4b17023SJohn Marino c_parser_consume_token (parser);
2492*e4b17023SJohn Marino else
2493*e4b17023SJohn Marino {
2494*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2495*e4b17023SJohn Marino pedwarn (c_parser_peek_token (parser)->location, 0,
2496*e4b17023SJohn Marino "no semicolon at end of struct or union");
2497*e4b17023SJohn Marino else if (parser->error
2498*e4b17023SJohn Marino || !c_parser_next_token_starts_declspecs (parser))
2499*e4b17023SJohn Marino {
2500*e4b17023SJohn Marino c_parser_error (parser, "expected %<;%>");
2501*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
2502*e4b17023SJohn Marino break;
2503*e4b17023SJohn Marino }
2504*e4b17023SJohn Marino
2505*e4b17023SJohn Marino /* If we come here, we have already emitted an error
2506*e4b17023SJohn Marino for an expected `;', identifier or `(', and we also
2507*e4b17023SJohn Marino recovered already. Go on with the next field. */
2508*e4b17023SJohn Marino }
2509*e4b17023SJohn Marino }
2510*e4b17023SJohn Marino postfix_attrs = c_parser_attributes (parser);
2511*e4b17023SJohn Marino ret.spec = finish_struct (struct_loc, type, nreverse (contents),
2512*e4b17023SJohn Marino chainon (attrs, postfix_attrs), struct_info);
2513*e4b17023SJohn Marino ret.kind = ctsk_tagdef;
2514*e4b17023SJohn Marino ret.expr = NULL_TREE;
2515*e4b17023SJohn Marino ret.expr_const_operands = true;
2516*e4b17023SJohn Marino timevar_pop (TV_PARSE_STRUCT);
2517*e4b17023SJohn Marino return ret;
2518*e4b17023SJohn Marino }
2519*e4b17023SJohn Marino else if (!ident)
2520*e4b17023SJohn Marino {
2521*e4b17023SJohn Marino c_parser_error (parser, "expected %<{%>");
2522*e4b17023SJohn Marino ret.spec = error_mark_node;
2523*e4b17023SJohn Marino ret.kind = ctsk_tagref;
2524*e4b17023SJohn Marino ret.expr = NULL_TREE;
2525*e4b17023SJohn Marino ret.expr_const_operands = true;
2526*e4b17023SJohn Marino return ret;
2527*e4b17023SJohn Marino }
2528*e4b17023SJohn Marino ret = parser_xref_tag (ident_loc, code, ident);
2529*e4b17023SJohn Marino return ret;
2530*e4b17023SJohn Marino }
2531*e4b17023SJohn Marino
2532*e4b17023SJohn Marino /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1), *without*
2533*e4b17023SJohn Marino the trailing semicolon.
2534*e4b17023SJohn Marino
2535*e4b17023SJohn Marino struct-declaration:
2536*e4b17023SJohn Marino specifier-qualifier-list struct-declarator-list
2537*e4b17023SJohn Marino static_assert-declaration-no-semi
2538*e4b17023SJohn Marino
2539*e4b17023SJohn Marino specifier-qualifier-list:
2540*e4b17023SJohn Marino type-specifier specifier-qualifier-list[opt]
2541*e4b17023SJohn Marino type-qualifier specifier-qualifier-list[opt]
2542*e4b17023SJohn Marino attributes specifier-qualifier-list[opt]
2543*e4b17023SJohn Marino
2544*e4b17023SJohn Marino struct-declarator-list:
2545*e4b17023SJohn Marino struct-declarator
2546*e4b17023SJohn Marino struct-declarator-list , attributes[opt] struct-declarator
2547*e4b17023SJohn Marino
2548*e4b17023SJohn Marino struct-declarator:
2549*e4b17023SJohn Marino declarator attributes[opt]
2550*e4b17023SJohn Marino declarator[opt] : constant-expression attributes[opt]
2551*e4b17023SJohn Marino
2552*e4b17023SJohn Marino GNU extensions:
2553*e4b17023SJohn Marino
2554*e4b17023SJohn Marino struct-declaration:
2555*e4b17023SJohn Marino __extension__ struct-declaration
2556*e4b17023SJohn Marino specifier-qualifier-list
2557*e4b17023SJohn Marino
2558*e4b17023SJohn Marino Unlike the ISO C syntax, semicolons are handled elsewhere. The use
2559*e4b17023SJohn Marino of attributes where shown is a GNU extension. In GNU C, we accept
2560*e4b17023SJohn Marino any expression without commas in the syntax (assignment
2561*e4b17023SJohn Marino expressions, not just conditional expressions); assignment
2562*e4b17023SJohn Marino expressions will be diagnosed as non-constant. */
2563*e4b17023SJohn Marino
2564*e4b17023SJohn Marino static tree
c_parser_struct_declaration(c_parser * parser)2565*e4b17023SJohn Marino c_parser_struct_declaration (c_parser *parser)
2566*e4b17023SJohn Marino {
2567*e4b17023SJohn Marino struct c_declspecs *specs;
2568*e4b17023SJohn Marino tree prefix_attrs;
2569*e4b17023SJohn Marino tree all_prefix_attrs;
2570*e4b17023SJohn Marino tree decls;
2571*e4b17023SJohn Marino location_t decl_loc;
2572*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
2573*e4b17023SJohn Marino {
2574*e4b17023SJohn Marino int ext;
2575*e4b17023SJohn Marino tree decl;
2576*e4b17023SJohn Marino ext = disable_extension_diagnostics ();
2577*e4b17023SJohn Marino c_parser_consume_token (parser);
2578*e4b17023SJohn Marino decl = c_parser_struct_declaration (parser);
2579*e4b17023SJohn Marino restore_extension_diagnostics (ext);
2580*e4b17023SJohn Marino return decl;
2581*e4b17023SJohn Marino }
2582*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
2583*e4b17023SJohn Marino {
2584*e4b17023SJohn Marino c_parser_static_assert_declaration_no_semi (parser);
2585*e4b17023SJohn Marino return NULL_TREE;
2586*e4b17023SJohn Marino }
2587*e4b17023SJohn Marino specs = build_null_declspecs ();
2588*e4b17023SJohn Marino decl_loc = c_parser_peek_token (parser)->location;
2589*e4b17023SJohn Marino c_parser_declspecs (parser, specs, false, true, true, cla_nonabstract_decl);
2590*e4b17023SJohn Marino if (parser->error)
2591*e4b17023SJohn Marino return NULL_TREE;
2592*e4b17023SJohn Marino if (!specs->declspecs_seen_p)
2593*e4b17023SJohn Marino {
2594*e4b17023SJohn Marino c_parser_error (parser, "expected specifier-qualifier-list");
2595*e4b17023SJohn Marino return NULL_TREE;
2596*e4b17023SJohn Marino }
2597*e4b17023SJohn Marino finish_declspecs (specs);
2598*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON)
2599*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2600*e4b17023SJohn Marino {
2601*e4b17023SJohn Marino tree ret;
2602*e4b17023SJohn Marino if (specs->typespec_kind == ctsk_none)
2603*e4b17023SJohn Marino {
2604*e4b17023SJohn Marino pedwarn (decl_loc, OPT_pedantic,
2605*e4b17023SJohn Marino "ISO C forbids member declarations with no members");
2606*e4b17023SJohn Marino shadow_tag_warned (specs, pedantic);
2607*e4b17023SJohn Marino ret = NULL_TREE;
2608*e4b17023SJohn Marino }
2609*e4b17023SJohn Marino else
2610*e4b17023SJohn Marino {
2611*e4b17023SJohn Marino /* Support for unnamed structs or unions as members of
2612*e4b17023SJohn Marino structs or unions (which is [a] useful and [b] supports
2613*e4b17023SJohn Marino MS P-SDK). */
2614*e4b17023SJohn Marino tree attrs = NULL;
2615*e4b17023SJohn Marino
2616*e4b17023SJohn Marino ret = grokfield (c_parser_peek_token (parser)->location,
2617*e4b17023SJohn Marino build_id_declarator (NULL_TREE), specs,
2618*e4b17023SJohn Marino NULL_TREE, &attrs);
2619*e4b17023SJohn Marino if (ret)
2620*e4b17023SJohn Marino decl_attributes (&ret, attrs, 0);
2621*e4b17023SJohn Marino }
2622*e4b17023SJohn Marino return ret;
2623*e4b17023SJohn Marino }
2624*e4b17023SJohn Marino
2625*e4b17023SJohn Marino /* Provide better error recovery. Note that a type name here is valid,
2626*e4b17023SJohn Marino and will be treated as a field name. */
2627*e4b17023SJohn Marino if (specs->typespec_kind == ctsk_tagdef
2628*e4b17023SJohn Marino && TREE_CODE (specs->type) != ENUMERAL_TYPE
2629*e4b17023SJohn Marino && c_parser_next_token_starts_declspecs (parser)
2630*e4b17023SJohn Marino && !c_parser_next_token_is (parser, CPP_NAME))
2631*e4b17023SJohn Marino {
2632*e4b17023SJohn Marino c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2633*e4b17023SJohn Marino parser->error = false;
2634*e4b17023SJohn Marino return NULL_TREE;
2635*e4b17023SJohn Marino }
2636*e4b17023SJohn Marino
2637*e4b17023SJohn Marino pending_xref_error ();
2638*e4b17023SJohn Marino prefix_attrs = specs->attrs;
2639*e4b17023SJohn Marino all_prefix_attrs = prefix_attrs;
2640*e4b17023SJohn Marino specs->attrs = NULL_TREE;
2641*e4b17023SJohn Marino decls = NULL_TREE;
2642*e4b17023SJohn Marino while (true)
2643*e4b17023SJohn Marino {
2644*e4b17023SJohn Marino /* Declaring one or more declarators or un-named bit-fields. */
2645*e4b17023SJohn Marino struct c_declarator *declarator;
2646*e4b17023SJohn Marino bool dummy = false;
2647*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COLON))
2648*e4b17023SJohn Marino declarator = build_id_declarator (NULL_TREE);
2649*e4b17023SJohn Marino else
2650*e4b17023SJohn Marino declarator = c_parser_declarator (parser,
2651*e4b17023SJohn Marino specs->typespec_kind != ctsk_none,
2652*e4b17023SJohn Marino C_DTR_NORMAL, &dummy);
2653*e4b17023SJohn Marino if (declarator == NULL)
2654*e4b17023SJohn Marino {
2655*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
2656*e4b17023SJohn Marino break;
2657*e4b17023SJohn Marino }
2658*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COLON)
2659*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_COMMA)
2660*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_SEMICOLON)
2661*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
2662*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2663*e4b17023SJohn Marino {
2664*e4b17023SJohn Marino tree postfix_attrs = NULL_TREE;
2665*e4b17023SJohn Marino tree width = NULL_TREE;
2666*e4b17023SJohn Marino tree d;
2667*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COLON))
2668*e4b17023SJohn Marino {
2669*e4b17023SJohn Marino c_parser_consume_token (parser);
2670*e4b17023SJohn Marino width = c_parser_expr_no_commas (parser, NULL).value;
2671*e4b17023SJohn Marino }
2672*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2673*e4b17023SJohn Marino postfix_attrs = c_parser_attributes (parser);
2674*e4b17023SJohn Marino d = grokfield (c_parser_peek_token (parser)->location,
2675*e4b17023SJohn Marino declarator, specs, width, &all_prefix_attrs);
2676*e4b17023SJohn Marino decl_attributes (&d, chainon (postfix_attrs,
2677*e4b17023SJohn Marino all_prefix_attrs), 0);
2678*e4b17023SJohn Marino DECL_CHAIN (d) = decls;
2679*e4b17023SJohn Marino decls = d;
2680*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2681*e4b17023SJohn Marino all_prefix_attrs = chainon (c_parser_attributes (parser),
2682*e4b17023SJohn Marino prefix_attrs);
2683*e4b17023SJohn Marino else
2684*e4b17023SJohn Marino all_prefix_attrs = prefix_attrs;
2685*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
2686*e4b17023SJohn Marino c_parser_consume_token (parser);
2687*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
2688*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
2689*e4b17023SJohn Marino {
2690*e4b17023SJohn Marino /* Semicolon consumed in caller. */
2691*e4b17023SJohn Marino break;
2692*e4b17023SJohn Marino }
2693*e4b17023SJohn Marino else
2694*e4b17023SJohn Marino {
2695*e4b17023SJohn Marino c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
2696*e4b17023SJohn Marino break;
2697*e4b17023SJohn Marino }
2698*e4b17023SJohn Marino }
2699*e4b17023SJohn Marino else
2700*e4b17023SJohn Marino {
2701*e4b17023SJohn Marino c_parser_error (parser,
2702*e4b17023SJohn Marino "expected %<:%>, %<,%>, %<;%>, %<}%> or "
2703*e4b17023SJohn Marino "%<__attribute__%>");
2704*e4b17023SJohn Marino break;
2705*e4b17023SJohn Marino }
2706*e4b17023SJohn Marino }
2707*e4b17023SJohn Marino return decls;
2708*e4b17023SJohn Marino }
2709*e4b17023SJohn Marino
2710*e4b17023SJohn Marino /* Parse a typeof specifier (a GNU extension).
2711*e4b17023SJohn Marino
2712*e4b17023SJohn Marino typeof-specifier:
2713*e4b17023SJohn Marino typeof ( expression )
2714*e4b17023SJohn Marino typeof ( type-name )
2715*e4b17023SJohn Marino */
2716*e4b17023SJohn Marino
2717*e4b17023SJohn Marino static struct c_typespec
c_parser_typeof_specifier(c_parser * parser)2718*e4b17023SJohn Marino c_parser_typeof_specifier (c_parser *parser)
2719*e4b17023SJohn Marino {
2720*e4b17023SJohn Marino struct c_typespec ret;
2721*e4b17023SJohn Marino ret.kind = ctsk_typeof;
2722*e4b17023SJohn Marino ret.spec = error_mark_node;
2723*e4b17023SJohn Marino ret.expr = NULL_TREE;
2724*e4b17023SJohn Marino ret.expr_const_operands = true;
2725*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
2726*e4b17023SJohn Marino c_parser_consume_token (parser);
2727*e4b17023SJohn Marino c_inhibit_evaluation_warnings++;
2728*e4b17023SJohn Marino in_typeof++;
2729*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2730*e4b17023SJohn Marino {
2731*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
2732*e4b17023SJohn Marino in_typeof--;
2733*e4b17023SJohn Marino return ret;
2734*e4b17023SJohn Marino }
2735*e4b17023SJohn Marino if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
2736*e4b17023SJohn Marino {
2737*e4b17023SJohn Marino struct c_type_name *type = c_parser_type_name (parser);
2738*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
2739*e4b17023SJohn Marino in_typeof--;
2740*e4b17023SJohn Marino if (type != NULL)
2741*e4b17023SJohn Marino {
2742*e4b17023SJohn Marino ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
2743*e4b17023SJohn Marino pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
2744*e4b17023SJohn Marino }
2745*e4b17023SJohn Marino }
2746*e4b17023SJohn Marino else
2747*e4b17023SJohn Marino {
2748*e4b17023SJohn Marino bool was_vm;
2749*e4b17023SJohn Marino location_t here = c_parser_peek_token (parser)->location;
2750*e4b17023SJohn Marino struct c_expr expr = c_parser_expression (parser);
2751*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
2752*e4b17023SJohn Marino in_typeof--;
2753*e4b17023SJohn Marino if (TREE_CODE (expr.value) == COMPONENT_REF
2754*e4b17023SJohn Marino && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
2755*e4b17023SJohn Marino error_at (here, "%<typeof%> applied to a bit-field");
2756*e4b17023SJohn Marino mark_exp_read (expr.value);
2757*e4b17023SJohn Marino ret.spec = TREE_TYPE (expr.value);
2758*e4b17023SJohn Marino was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
2759*e4b17023SJohn Marino /* This is returned with the type so that when the type is
2760*e4b17023SJohn Marino evaluated, this can be evaluated. */
2761*e4b17023SJohn Marino if (was_vm)
2762*e4b17023SJohn Marino ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
2763*e4b17023SJohn Marino pop_maybe_used (was_vm);
2764*e4b17023SJohn Marino }
2765*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
2766*e4b17023SJohn Marino return ret;
2767*e4b17023SJohn Marino }
2768*e4b17023SJohn Marino
2769*e4b17023SJohn Marino /* Parse an alignment-specifier.
2770*e4b17023SJohn Marino
2771*e4b17023SJohn Marino C11 6.7.5:
2772*e4b17023SJohn Marino
2773*e4b17023SJohn Marino alignment-specifier:
2774*e4b17023SJohn Marino _Alignas ( type-name )
2775*e4b17023SJohn Marino _Alignas ( constant-expression )
2776*e4b17023SJohn Marino */
2777*e4b17023SJohn Marino
2778*e4b17023SJohn Marino static tree
c_parser_alignas_specifier(c_parser * parser)2779*e4b17023SJohn Marino c_parser_alignas_specifier (c_parser * parser)
2780*e4b17023SJohn Marino {
2781*e4b17023SJohn Marino tree ret = error_mark_node;
2782*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
2783*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
2784*e4b17023SJohn Marino c_parser_consume_token (parser);
2785*e4b17023SJohn Marino if (!flag_isoc11)
2786*e4b17023SJohn Marino {
2787*e4b17023SJohn Marino if (flag_isoc99)
2788*e4b17023SJohn Marino pedwarn (loc, OPT_pedantic,
2789*e4b17023SJohn Marino "ISO C99 does not support %<_Alignas%>");
2790*e4b17023SJohn Marino else
2791*e4b17023SJohn Marino pedwarn (loc, OPT_pedantic,
2792*e4b17023SJohn Marino "ISO C90 does not support %<_Alignas%>");
2793*e4b17023SJohn Marino }
2794*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
2795*e4b17023SJohn Marino return ret;
2796*e4b17023SJohn Marino if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
2797*e4b17023SJohn Marino {
2798*e4b17023SJohn Marino struct c_type_name *type = c_parser_type_name (parser);
2799*e4b17023SJohn Marino if (type != NULL)
2800*e4b17023SJohn Marino ret = c_alignof (loc, groktypename (type, NULL, NULL));
2801*e4b17023SJohn Marino }
2802*e4b17023SJohn Marino else
2803*e4b17023SJohn Marino ret = c_parser_expr_no_commas (parser, NULL).value;
2804*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
2805*e4b17023SJohn Marino return ret;
2806*e4b17023SJohn Marino }
2807*e4b17023SJohn Marino
2808*e4b17023SJohn Marino /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
2809*e4b17023SJohn Marino 6.5.5, C99 6.7.5, 6.7.6). If TYPE_SEEN_P then a typedef name may
2810*e4b17023SJohn Marino be redeclared; otherwise it may not. KIND indicates which kind of
2811*e4b17023SJohn Marino declarator is wanted. Returns a valid declarator except in the
2812*e4b17023SJohn Marino case of a syntax error in which case NULL is returned. *SEEN_ID is
2813*e4b17023SJohn Marino set to true if an identifier being declared is seen; this is used
2814*e4b17023SJohn Marino to diagnose bad forms of abstract array declarators and to
2815*e4b17023SJohn Marino determine whether an identifier list is syntactically permitted.
2816*e4b17023SJohn Marino
2817*e4b17023SJohn Marino declarator:
2818*e4b17023SJohn Marino pointer[opt] direct-declarator
2819*e4b17023SJohn Marino
2820*e4b17023SJohn Marino direct-declarator:
2821*e4b17023SJohn Marino identifier
2822*e4b17023SJohn Marino ( attributes[opt] declarator )
2823*e4b17023SJohn Marino direct-declarator array-declarator
2824*e4b17023SJohn Marino direct-declarator ( parameter-type-list )
2825*e4b17023SJohn Marino direct-declarator ( identifier-list[opt] )
2826*e4b17023SJohn Marino
2827*e4b17023SJohn Marino pointer:
2828*e4b17023SJohn Marino * type-qualifier-list[opt]
2829*e4b17023SJohn Marino * type-qualifier-list[opt] pointer
2830*e4b17023SJohn Marino
2831*e4b17023SJohn Marino type-qualifier-list:
2832*e4b17023SJohn Marino type-qualifier
2833*e4b17023SJohn Marino attributes
2834*e4b17023SJohn Marino type-qualifier-list type-qualifier
2835*e4b17023SJohn Marino type-qualifier-list attributes
2836*e4b17023SJohn Marino
2837*e4b17023SJohn Marino parameter-type-list:
2838*e4b17023SJohn Marino parameter-list
2839*e4b17023SJohn Marino parameter-list , ...
2840*e4b17023SJohn Marino
2841*e4b17023SJohn Marino parameter-list:
2842*e4b17023SJohn Marino parameter-declaration
2843*e4b17023SJohn Marino parameter-list , parameter-declaration
2844*e4b17023SJohn Marino
2845*e4b17023SJohn Marino parameter-declaration:
2846*e4b17023SJohn Marino declaration-specifiers declarator attributes[opt]
2847*e4b17023SJohn Marino declaration-specifiers abstract-declarator[opt] attributes[opt]
2848*e4b17023SJohn Marino
2849*e4b17023SJohn Marino identifier-list:
2850*e4b17023SJohn Marino identifier
2851*e4b17023SJohn Marino identifier-list , identifier
2852*e4b17023SJohn Marino
2853*e4b17023SJohn Marino abstract-declarator:
2854*e4b17023SJohn Marino pointer
2855*e4b17023SJohn Marino pointer[opt] direct-abstract-declarator
2856*e4b17023SJohn Marino
2857*e4b17023SJohn Marino direct-abstract-declarator:
2858*e4b17023SJohn Marino ( attributes[opt] abstract-declarator )
2859*e4b17023SJohn Marino direct-abstract-declarator[opt] array-declarator
2860*e4b17023SJohn Marino direct-abstract-declarator[opt] ( parameter-type-list[opt] )
2861*e4b17023SJohn Marino
2862*e4b17023SJohn Marino GNU extensions:
2863*e4b17023SJohn Marino
2864*e4b17023SJohn Marino direct-declarator:
2865*e4b17023SJohn Marino direct-declarator ( parameter-forward-declarations
2866*e4b17023SJohn Marino parameter-type-list[opt] )
2867*e4b17023SJohn Marino
2868*e4b17023SJohn Marino direct-abstract-declarator:
2869*e4b17023SJohn Marino direct-abstract-declarator[opt] ( parameter-forward-declarations
2870*e4b17023SJohn Marino parameter-type-list[opt] )
2871*e4b17023SJohn Marino
2872*e4b17023SJohn Marino parameter-forward-declarations:
2873*e4b17023SJohn Marino parameter-list ;
2874*e4b17023SJohn Marino parameter-forward-declarations parameter-list ;
2875*e4b17023SJohn Marino
2876*e4b17023SJohn Marino The uses of attributes shown above are GNU extensions.
2877*e4b17023SJohn Marino
2878*e4b17023SJohn Marino Some forms of array declarator are not included in C99 in the
2879*e4b17023SJohn Marino syntax for abstract declarators; these are disallowed elsewhere.
2880*e4b17023SJohn Marino This may be a defect (DR#289).
2881*e4b17023SJohn Marino
2882*e4b17023SJohn Marino This function also accepts an omitted abstract declarator as being
2883*e4b17023SJohn Marino an abstract declarator, although not part of the formal syntax. */
2884*e4b17023SJohn Marino
2885*e4b17023SJohn Marino static struct c_declarator *
c_parser_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)2886*e4b17023SJohn Marino c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
2887*e4b17023SJohn Marino bool *seen_id)
2888*e4b17023SJohn Marino {
2889*e4b17023SJohn Marino /* Parse any initial pointer part. */
2890*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_MULT))
2891*e4b17023SJohn Marino {
2892*e4b17023SJohn Marino struct c_declspecs *quals_attrs = build_null_declspecs ();
2893*e4b17023SJohn Marino struct c_declarator *inner;
2894*e4b17023SJohn Marino c_parser_consume_token (parser);
2895*e4b17023SJohn Marino c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id);
2896*e4b17023SJohn Marino inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
2897*e4b17023SJohn Marino if (inner == NULL)
2898*e4b17023SJohn Marino return NULL;
2899*e4b17023SJohn Marino else
2900*e4b17023SJohn Marino return make_pointer_declarator (quals_attrs, inner);
2901*e4b17023SJohn Marino }
2902*e4b17023SJohn Marino /* Now we have a direct declarator, direct abstract declarator or
2903*e4b17023SJohn Marino nothing (which counts as a direct abstract declarator here). */
2904*e4b17023SJohn Marino return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
2905*e4b17023SJohn Marino }
2906*e4b17023SJohn Marino
2907*e4b17023SJohn Marino /* Parse a direct declarator or direct abstract declarator; arguments
2908*e4b17023SJohn Marino as c_parser_declarator. */
2909*e4b17023SJohn Marino
2910*e4b17023SJohn Marino static struct c_declarator *
c_parser_direct_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)2911*e4b17023SJohn Marino c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
2912*e4b17023SJohn Marino bool *seen_id)
2913*e4b17023SJohn Marino {
2914*e4b17023SJohn Marino /* The direct declarator must start with an identifier (possibly
2915*e4b17023SJohn Marino omitted) or a parenthesized declarator (possibly abstract). In
2916*e4b17023SJohn Marino an ordinary declarator, initial parentheses must start a
2917*e4b17023SJohn Marino parenthesized declarator. In an abstract declarator or parameter
2918*e4b17023SJohn Marino declarator, they could start a parenthesized declarator or a
2919*e4b17023SJohn Marino parameter list. To tell which, the open parenthesis and any
2920*e4b17023SJohn Marino following attributes must be read. If a declaration specifier
2921*e4b17023SJohn Marino follows, then it is a parameter list; if the specifier is a
2922*e4b17023SJohn Marino typedef name, there might be an ambiguity about redeclaring it,
2923*e4b17023SJohn Marino which is resolved in the direction of treating it as a typedef
2924*e4b17023SJohn Marino name. If a close parenthesis follows, it is also an empty
2925*e4b17023SJohn Marino parameter list, as the syntax does not permit empty abstract
2926*e4b17023SJohn Marino declarators. Otherwise, it is a parenthesized declarator (in
2927*e4b17023SJohn Marino which case the analysis may be repeated inside it, recursively).
2928*e4b17023SJohn Marino
2929*e4b17023SJohn Marino ??? There is an ambiguity in a parameter declaration "int
2930*e4b17023SJohn Marino (__attribute__((foo)) x)", where x is not a typedef name: it
2931*e4b17023SJohn Marino could be an abstract declarator for a function, or declare x with
2932*e4b17023SJohn Marino parentheses. The proper resolution of this ambiguity needs
2933*e4b17023SJohn Marino documenting. At present we follow an accident of the old
2934*e4b17023SJohn Marino parser's implementation, whereby the first parameter must have
2935*e4b17023SJohn Marino some declaration specifiers other than just attributes. Thus as
2936*e4b17023SJohn Marino a parameter declaration it is treated as a parenthesized
2937*e4b17023SJohn Marino parameter named x, and as an abstract declarator it is
2938*e4b17023SJohn Marino rejected.
2939*e4b17023SJohn Marino
2940*e4b17023SJohn Marino ??? Also following the old parser, attributes inside an empty
2941*e4b17023SJohn Marino parameter list are ignored, making it a list not yielding a
2942*e4b17023SJohn Marino prototype, rather than giving an error or making it have one
2943*e4b17023SJohn Marino parameter with implicit type int.
2944*e4b17023SJohn Marino
2945*e4b17023SJohn Marino ??? Also following the old parser, typedef names may be
2946*e4b17023SJohn Marino redeclared in declarators, but not Objective-C class names. */
2947*e4b17023SJohn Marino
2948*e4b17023SJohn Marino if (kind != C_DTR_ABSTRACT
2949*e4b17023SJohn Marino && c_parser_next_token_is (parser, CPP_NAME)
2950*e4b17023SJohn Marino && ((type_seen_p
2951*e4b17023SJohn Marino && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
2952*e4b17023SJohn Marino || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
2953*e4b17023SJohn Marino || c_parser_peek_token (parser)->id_kind == C_ID_ID))
2954*e4b17023SJohn Marino {
2955*e4b17023SJohn Marino struct c_declarator *inner
2956*e4b17023SJohn Marino = build_id_declarator (c_parser_peek_token (parser)->value);
2957*e4b17023SJohn Marino *seen_id = true;
2958*e4b17023SJohn Marino inner->id_loc = c_parser_peek_token (parser)->location;
2959*e4b17023SJohn Marino c_parser_consume_token (parser);
2960*e4b17023SJohn Marino return c_parser_direct_declarator_inner (parser, *seen_id, inner);
2961*e4b17023SJohn Marino }
2962*e4b17023SJohn Marino
2963*e4b17023SJohn Marino if (kind != C_DTR_NORMAL
2964*e4b17023SJohn Marino && c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
2965*e4b17023SJohn Marino {
2966*e4b17023SJohn Marino struct c_declarator *inner = build_id_declarator (NULL_TREE);
2967*e4b17023SJohn Marino return c_parser_direct_declarator_inner (parser, *seen_id, inner);
2968*e4b17023SJohn Marino }
2969*e4b17023SJohn Marino
2970*e4b17023SJohn Marino /* Either we are at the end of an abstract declarator, or we have
2971*e4b17023SJohn Marino parentheses. */
2972*e4b17023SJohn Marino
2973*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2974*e4b17023SJohn Marino {
2975*e4b17023SJohn Marino tree attrs;
2976*e4b17023SJohn Marino struct c_declarator *inner;
2977*e4b17023SJohn Marino c_parser_consume_token (parser);
2978*e4b17023SJohn Marino attrs = c_parser_attributes (parser);
2979*e4b17023SJohn Marino if (kind != C_DTR_NORMAL
2980*e4b17023SJohn Marino && (c_parser_next_token_starts_declspecs (parser)
2981*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
2982*e4b17023SJohn Marino {
2983*e4b17023SJohn Marino struct c_arg_info *args
2984*e4b17023SJohn Marino = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
2985*e4b17023SJohn Marino attrs);
2986*e4b17023SJohn Marino if (args == NULL)
2987*e4b17023SJohn Marino return NULL;
2988*e4b17023SJohn Marino else
2989*e4b17023SJohn Marino {
2990*e4b17023SJohn Marino inner
2991*e4b17023SJohn Marino = build_function_declarator (args,
2992*e4b17023SJohn Marino build_id_declarator (NULL_TREE));
2993*e4b17023SJohn Marino return c_parser_direct_declarator_inner (parser, *seen_id,
2994*e4b17023SJohn Marino inner);
2995*e4b17023SJohn Marino }
2996*e4b17023SJohn Marino }
2997*e4b17023SJohn Marino /* A parenthesized declarator. */
2998*e4b17023SJohn Marino inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
2999*e4b17023SJohn Marino if (inner != NULL && attrs != NULL)
3000*e4b17023SJohn Marino inner = build_attrs_declarator (attrs, inner);
3001*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3002*e4b17023SJohn Marino {
3003*e4b17023SJohn Marino c_parser_consume_token (parser);
3004*e4b17023SJohn Marino if (inner == NULL)
3005*e4b17023SJohn Marino return NULL;
3006*e4b17023SJohn Marino else
3007*e4b17023SJohn Marino return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3008*e4b17023SJohn Marino }
3009*e4b17023SJohn Marino else
3010*e4b17023SJohn Marino {
3011*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3012*e4b17023SJohn Marino "expected %<)%>");
3013*e4b17023SJohn Marino return NULL;
3014*e4b17023SJohn Marino }
3015*e4b17023SJohn Marino }
3016*e4b17023SJohn Marino else
3017*e4b17023SJohn Marino {
3018*e4b17023SJohn Marino if (kind == C_DTR_NORMAL)
3019*e4b17023SJohn Marino {
3020*e4b17023SJohn Marino c_parser_error (parser, "expected identifier or %<(%>");
3021*e4b17023SJohn Marino return NULL;
3022*e4b17023SJohn Marino }
3023*e4b17023SJohn Marino else
3024*e4b17023SJohn Marino return build_id_declarator (NULL_TREE);
3025*e4b17023SJohn Marino }
3026*e4b17023SJohn Marino }
3027*e4b17023SJohn Marino
3028*e4b17023SJohn Marino /* Parse part of a direct declarator or direct abstract declarator,
3029*e4b17023SJohn Marino given that some (in INNER) has already been parsed; ID_PRESENT is
3030*e4b17023SJohn Marino true if an identifier is present, false for an abstract
3031*e4b17023SJohn Marino declarator. */
3032*e4b17023SJohn Marino
3033*e4b17023SJohn Marino static struct c_declarator *
c_parser_direct_declarator_inner(c_parser * parser,bool id_present,struct c_declarator * inner)3034*e4b17023SJohn Marino c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
3035*e4b17023SJohn Marino struct c_declarator *inner)
3036*e4b17023SJohn Marino {
3037*e4b17023SJohn Marino /* Parse a sequence of array declarators and parameter lists. */
3038*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
3039*e4b17023SJohn Marino {
3040*e4b17023SJohn Marino location_t brace_loc = c_parser_peek_token (parser)->location;
3041*e4b17023SJohn Marino struct c_declarator *declarator;
3042*e4b17023SJohn Marino struct c_declspecs *quals_attrs = build_null_declspecs ();
3043*e4b17023SJohn Marino bool static_seen;
3044*e4b17023SJohn Marino bool star_seen;
3045*e4b17023SJohn Marino tree dimen;
3046*e4b17023SJohn Marino c_parser_consume_token (parser);
3047*e4b17023SJohn Marino c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id);
3048*e4b17023SJohn Marino static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
3049*e4b17023SJohn Marino if (static_seen)
3050*e4b17023SJohn Marino c_parser_consume_token (parser);
3051*e4b17023SJohn Marino if (static_seen && !quals_attrs->declspecs_seen_p)
3052*e4b17023SJohn Marino c_parser_declspecs (parser, quals_attrs, false, false, true, cla_prefer_id);
3053*e4b17023SJohn Marino if (!quals_attrs->declspecs_seen_p)
3054*e4b17023SJohn Marino quals_attrs = NULL;
3055*e4b17023SJohn Marino /* If "static" is present, there must be an array dimension.
3056*e4b17023SJohn Marino Otherwise, there may be a dimension, "*", or no
3057*e4b17023SJohn Marino dimension. */
3058*e4b17023SJohn Marino if (static_seen)
3059*e4b17023SJohn Marino {
3060*e4b17023SJohn Marino star_seen = false;
3061*e4b17023SJohn Marino dimen = c_parser_expr_no_commas (parser, NULL).value;
3062*e4b17023SJohn Marino }
3063*e4b17023SJohn Marino else
3064*e4b17023SJohn Marino {
3065*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3066*e4b17023SJohn Marino {
3067*e4b17023SJohn Marino dimen = NULL_TREE;
3068*e4b17023SJohn Marino star_seen = false;
3069*e4b17023SJohn Marino }
3070*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_MULT))
3071*e4b17023SJohn Marino {
3072*e4b17023SJohn Marino if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
3073*e4b17023SJohn Marino {
3074*e4b17023SJohn Marino dimen = NULL_TREE;
3075*e4b17023SJohn Marino star_seen = true;
3076*e4b17023SJohn Marino c_parser_consume_token (parser);
3077*e4b17023SJohn Marino }
3078*e4b17023SJohn Marino else
3079*e4b17023SJohn Marino {
3080*e4b17023SJohn Marino star_seen = false;
3081*e4b17023SJohn Marino dimen = c_parser_expr_no_commas (parser, NULL).value;
3082*e4b17023SJohn Marino }
3083*e4b17023SJohn Marino }
3084*e4b17023SJohn Marino else
3085*e4b17023SJohn Marino {
3086*e4b17023SJohn Marino star_seen = false;
3087*e4b17023SJohn Marino dimen = c_parser_expr_no_commas (parser, NULL).value;
3088*e4b17023SJohn Marino }
3089*e4b17023SJohn Marino }
3090*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3091*e4b17023SJohn Marino c_parser_consume_token (parser);
3092*e4b17023SJohn Marino else
3093*e4b17023SJohn Marino {
3094*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3095*e4b17023SJohn Marino "expected %<]%>");
3096*e4b17023SJohn Marino return NULL;
3097*e4b17023SJohn Marino }
3098*e4b17023SJohn Marino if (dimen)
3099*e4b17023SJohn Marino mark_exp_read (dimen);
3100*e4b17023SJohn Marino declarator = build_array_declarator (brace_loc, dimen, quals_attrs,
3101*e4b17023SJohn Marino static_seen, star_seen);
3102*e4b17023SJohn Marino if (declarator == NULL)
3103*e4b17023SJohn Marino return NULL;
3104*e4b17023SJohn Marino inner = set_array_declarator_inner (declarator, inner);
3105*e4b17023SJohn Marino return c_parser_direct_declarator_inner (parser, id_present, inner);
3106*e4b17023SJohn Marino }
3107*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3108*e4b17023SJohn Marino {
3109*e4b17023SJohn Marino tree attrs;
3110*e4b17023SJohn Marino struct c_arg_info *args;
3111*e4b17023SJohn Marino c_parser_consume_token (parser);
3112*e4b17023SJohn Marino attrs = c_parser_attributes (parser);
3113*e4b17023SJohn Marino args = c_parser_parms_declarator (parser, id_present, attrs);
3114*e4b17023SJohn Marino if (args == NULL)
3115*e4b17023SJohn Marino return NULL;
3116*e4b17023SJohn Marino else
3117*e4b17023SJohn Marino {
3118*e4b17023SJohn Marino inner = build_function_declarator (args, inner);
3119*e4b17023SJohn Marino return c_parser_direct_declarator_inner (parser, id_present, inner);
3120*e4b17023SJohn Marino }
3121*e4b17023SJohn Marino }
3122*e4b17023SJohn Marino return inner;
3123*e4b17023SJohn Marino }
3124*e4b17023SJohn Marino
3125*e4b17023SJohn Marino /* Parse a parameter list or identifier list, including the closing
3126*e4b17023SJohn Marino parenthesis but not the opening one. ATTRS are the attributes at
3127*e4b17023SJohn Marino the start of the list. ID_LIST_OK is true if an identifier list is
3128*e4b17023SJohn Marino acceptable; such a list must not have attributes at the start. */
3129*e4b17023SJohn Marino
3130*e4b17023SJohn Marino static struct c_arg_info *
c_parser_parms_declarator(c_parser * parser,bool id_list_ok,tree attrs)3131*e4b17023SJohn Marino c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs)
3132*e4b17023SJohn Marino {
3133*e4b17023SJohn Marino push_scope ();
3134*e4b17023SJohn Marino declare_parm_level ();
3135*e4b17023SJohn Marino /* If the list starts with an identifier, it is an identifier list.
3136*e4b17023SJohn Marino Otherwise, it is either a prototype list or an empty list. */
3137*e4b17023SJohn Marino if (id_list_ok
3138*e4b17023SJohn Marino && !attrs
3139*e4b17023SJohn Marino && c_parser_next_token_is (parser, CPP_NAME)
3140*e4b17023SJohn Marino && c_parser_peek_token (parser)->id_kind == C_ID_ID
3141*e4b17023SJohn Marino
3142*e4b17023SJohn Marino /* Look ahead to detect typos in type names. */
3143*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type != CPP_NAME
3144*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type != CPP_MULT
3145*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
3146*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE)
3147*e4b17023SJohn Marino {
3148*e4b17023SJohn Marino tree list = NULL_TREE, *nextp = &list;
3149*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_NAME)
3150*e4b17023SJohn Marino && c_parser_peek_token (parser)->id_kind == C_ID_ID)
3151*e4b17023SJohn Marino {
3152*e4b17023SJohn Marino *nextp = build_tree_list (NULL_TREE,
3153*e4b17023SJohn Marino c_parser_peek_token (parser)->value);
3154*e4b17023SJohn Marino nextp = & TREE_CHAIN (*nextp);
3155*e4b17023SJohn Marino c_parser_consume_token (parser);
3156*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_COMMA))
3157*e4b17023SJohn Marino break;
3158*e4b17023SJohn Marino c_parser_consume_token (parser);
3159*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3160*e4b17023SJohn Marino {
3161*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
3162*e4b17023SJohn Marino break;
3163*e4b17023SJohn Marino }
3164*e4b17023SJohn Marino }
3165*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3166*e4b17023SJohn Marino {
3167*e4b17023SJohn Marino struct c_arg_info *ret = build_arg_info ();
3168*e4b17023SJohn Marino ret->types = list;
3169*e4b17023SJohn Marino c_parser_consume_token (parser);
3170*e4b17023SJohn Marino pop_scope ();
3171*e4b17023SJohn Marino return ret;
3172*e4b17023SJohn Marino }
3173*e4b17023SJohn Marino else
3174*e4b17023SJohn Marino {
3175*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3176*e4b17023SJohn Marino "expected %<)%>");
3177*e4b17023SJohn Marino pop_scope ();
3178*e4b17023SJohn Marino return NULL;
3179*e4b17023SJohn Marino }
3180*e4b17023SJohn Marino }
3181*e4b17023SJohn Marino else
3182*e4b17023SJohn Marino {
3183*e4b17023SJohn Marino struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs,
3184*e4b17023SJohn Marino NULL);
3185*e4b17023SJohn Marino pop_scope ();
3186*e4b17023SJohn Marino return ret;
3187*e4b17023SJohn Marino }
3188*e4b17023SJohn Marino }
3189*e4b17023SJohn Marino
3190*e4b17023SJohn Marino /* Parse a parameter list (possibly empty), including the closing
3191*e4b17023SJohn Marino parenthesis but not the opening one. ATTRS are the attributes at
3192*e4b17023SJohn Marino the start of the list. EXPR is NULL or an expression that needs to
3193*e4b17023SJohn Marino be evaluated for the side effects of array size expressions in the
3194*e4b17023SJohn Marino parameters. */
3195*e4b17023SJohn Marino
3196*e4b17023SJohn Marino static struct c_arg_info *
c_parser_parms_list_declarator(c_parser * parser,tree attrs,tree expr)3197*e4b17023SJohn Marino c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr)
3198*e4b17023SJohn Marino {
3199*e4b17023SJohn Marino bool bad_parm = false;
3200*e4b17023SJohn Marino
3201*e4b17023SJohn Marino /* ??? Following the old parser, forward parameter declarations may
3202*e4b17023SJohn Marino use abstract declarators, and if no real parameter declarations
3203*e4b17023SJohn Marino follow the forward declarations then this is not diagnosed. Also
3204*e4b17023SJohn Marino note as above that attributes are ignored as the only contents of
3205*e4b17023SJohn Marino the parentheses, or as the only contents after forward
3206*e4b17023SJohn Marino declarations. */
3207*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3208*e4b17023SJohn Marino {
3209*e4b17023SJohn Marino struct c_arg_info *ret = build_arg_info ();
3210*e4b17023SJohn Marino c_parser_consume_token (parser);
3211*e4b17023SJohn Marino return ret;
3212*e4b17023SJohn Marino }
3213*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3214*e4b17023SJohn Marino {
3215*e4b17023SJohn Marino struct c_arg_info *ret = build_arg_info ();
3216*e4b17023SJohn Marino
3217*e4b17023SJohn Marino if (flag_allow_parameterless_variadic_functions)
3218*e4b17023SJohn Marino {
3219*e4b17023SJohn Marino /* F (...) is allowed. */
3220*e4b17023SJohn Marino ret->types = NULL_TREE;
3221*e4b17023SJohn Marino }
3222*e4b17023SJohn Marino else
3223*e4b17023SJohn Marino {
3224*e4b17023SJohn Marino /* Suppress -Wold-style-definition for this case. */
3225*e4b17023SJohn Marino ret->types = error_mark_node;
3226*e4b17023SJohn Marino error_at (c_parser_peek_token (parser)->location,
3227*e4b17023SJohn Marino "ISO C requires a named argument before %<...%>");
3228*e4b17023SJohn Marino }
3229*e4b17023SJohn Marino c_parser_consume_token (parser);
3230*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3231*e4b17023SJohn Marino {
3232*e4b17023SJohn Marino c_parser_consume_token (parser);
3233*e4b17023SJohn Marino return ret;
3234*e4b17023SJohn Marino }
3235*e4b17023SJohn Marino else
3236*e4b17023SJohn Marino {
3237*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3238*e4b17023SJohn Marino "expected %<)%>");
3239*e4b17023SJohn Marino return NULL;
3240*e4b17023SJohn Marino }
3241*e4b17023SJohn Marino }
3242*e4b17023SJohn Marino /* Nonempty list of parameters, either terminated with semicolon
3243*e4b17023SJohn Marino (forward declarations; recurse) or with close parenthesis (normal
3244*e4b17023SJohn Marino function) or with ", ... )" (variadic function). */
3245*e4b17023SJohn Marino while (true)
3246*e4b17023SJohn Marino {
3247*e4b17023SJohn Marino /* Parse a parameter. */
3248*e4b17023SJohn Marino struct c_parm *parm = c_parser_parameter_declaration (parser, attrs);
3249*e4b17023SJohn Marino attrs = NULL_TREE;
3250*e4b17023SJohn Marino if (parm == NULL)
3251*e4b17023SJohn Marino bad_parm = true;
3252*e4b17023SJohn Marino else
3253*e4b17023SJohn Marino push_parm_decl (parm, &expr);
3254*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3255*e4b17023SJohn Marino {
3256*e4b17023SJohn Marino tree new_attrs;
3257*e4b17023SJohn Marino c_parser_consume_token (parser);
3258*e4b17023SJohn Marino mark_forward_parm_decls ();
3259*e4b17023SJohn Marino new_attrs = c_parser_attributes (parser);
3260*e4b17023SJohn Marino return c_parser_parms_list_declarator (parser, new_attrs, expr);
3261*e4b17023SJohn Marino }
3262*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3263*e4b17023SJohn Marino {
3264*e4b17023SJohn Marino c_parser_consume_token (parser);
3265*e4b17023SJohn Marino if (bad_parm)
3266*e4b17023SJohn Marino return NULL;
3267*e4b17023SJohn Marino else
3268*e4b17023SJohn Marino return get_parm_info (false, expr);
3269*e4b17023SJohn Marino }
3270*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COMMA,
3271*e4b17023SJohn Marino "expected %<;%>, %<,%> or %<)%>"))
3272*e4b17023SJohn Marino {
3273*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3274*e4b17023SJohn Marino return NULL;
3275*e4b17023SJohn Marino }
3276*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3277*e4b17023SJohn Marino {
3278*e4b17023SJohn Marino c_parser_consume_token (parser);
3279*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3280*e4b17023SJohn Marino {
3281*e4b17023SJohn Marino c_parser_consume_token (parser);
3282*e4b17023SJohn Marino if (bad_parm)
3283*e4b17023SJohn Marino return NULL;
3284*e4b17023SJohn Marino else
3285*e4b17023SJohn Marino return get_parm_info (true, expr);
3286*e4b17023SJohn Marino }
3287*e4b17023SJohn Marino else
3288*e4b17023SJohn Marino {
3289*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3290*e4b17023SJohn Marino "expected %<)%>");
3291*e4b17023SJohn Marino return NULL;
3292*e4b17023SJohn Marino }
3293*e4b17023SJohn Marino }
3294*e4b17023SJohn Marino }
3295*e4b17023SJohn Marino }
3296*e4b17023SJohn Marino
3297*e4b17023SJohn Marino /* Parse a parameter declaration. ATTRS are the attributes at the
3298*e4b17023SJohn Marino start of the declaration if it is the first parameter. */
3299*e4b17023SJohn Marino
3300*e4b17023SJohn Marino static struct c_parm *
c_parser_parameter_declaration(c_parser * parser,tree attrs)3301*e4b17023SJohn Marino c_parser_parameter_declaration (c_parser *parser, tree attrs)
3302*e4b17023SJohn Marino {
3303*e4b17023SJohn Marino struct c_declspecs *specs;
3304*e4b17023SJohn Marino struct c_declarator *declarator;
3305*e4b17023SJohn Marino tree prefix_attrs;
3306*e4b17023SJohn Marino tree postfix_attrs = NULL_TREE;
3307*e4b17023SJohn Marino bool dummy = false;
3308*e4b17023SJohn Marino if (!c_parser_next_token_starts_declspecs (parser))
3309*e4b17023SJohn Marino {
3310*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
3311*e4b17023SJohn Marino if (parser->error)
3312*e4b17023SJohn Marino return NULL;
3313*e4b17023SJohn Marino c_parser_set_source_position_from_token (token);
3314*e4b17023SJohn Marino if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
3315*e4b17023SJohn Marino {
3316*e4b17023SJohn Marino error ("unknown type name %qE", token->value);
3317*e4b17023SJohn Marino parser->error = true;
3318*e4b17023SJohn Marino }
3319*e4b17023SJohn Marino /* ??? In some Objective-C cases '...' isn't applicable so there
3320*e4b17023SJohn Marino should be a different message. */
3321*e4b17023SJohn Marino else
3322*e4b17023SJohn Marino c_parser_error (parser,
3323*e4b17023SJohn Marino "expected declaration specifiers or %<...%>");
3324*e4b17023SJohn Marino c_parser_skip_to_end_of_parameter (parser);
3325*e4b17023SJohn Marino return NULL;
3326*e4b17023SJohn Marino }
3327*e4b17023SJohn Marino specs = build_null_declspecs ();
3328*e4b17023SJohn Marino if (attrs)
3329*e4b17023SJohn Marino {
3330*e4b17023SJohn Marino declspecs_add_attrs (specs, attrs);
3331*e4b17023SJohn Marino attrs = NULL_TREE;
3332*e4b17023SJohn Marino }
3333*e4b17023SJohn Marino c_parser_declspecs (parser, specs, true, true, true, cla_nonabstract_decl);
3334*e4b17023SJohn Marino finish_declspecs (specs);
3335*e4b17023SJohn Marino pending_xref_error ();
3336*e4b17023SJohn Marino prefix_attrs = specs->attrs;
3337*e4b17023SJohn Marino specs->attrs = NULL_TREE;
3338*e4b17023SJohn Marino declarator = c_parser_declarator (parser,
3339*e4b17023SJohn Marino specs->typespec_kind != ctsk_none,
3340*e4b17023SJohn Marino C_DTR_PARM, &dummy);
3341*e4b17023SJohn Marino if (declarator == NULL)
3342*e4b17023SJohn Marino {
3343*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_COMMA, NULL);
3344*e4b17023SJohn Marino return NULL;
3345*e4b17023SJohn Marino }
3346*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3347*e4b17023SJohn Marino postfix_attrs = c_parser_attributes (parser);
3348*e4b17023SJohn Marino return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
3349*e4b17023SJohn Marino declarator);
3350*e4b17023SJohn Marino }
3351*e4b17023SJohn Marino
3352*e4b17023SJohn Marino /* Parse a string literal in an asm expression. It should not be
3353*e4b17023SJohn Marino translated, and wide string literals are an error although
3354*e4b17023SJohn Marino permitted by the syntax. This is a GNU extension.
3355*e4b17023SJohn Marino
3356*e4b17023SJohn Marino asm-string-literal:
3357*e4b17023SJohn Marino string-literal
3358*e4b17023SJohn Marino
3359*e4b17023SJohn Marino ??? At present, following the old parser, the caller needs to have
3360*e4b17023SJohn Marino set lex_untranslated_string to 1. It would be better to follow the
3361*e4b17023SJohn Marino C++ parser rather than using this kludge. */
3362*e4b17023SJohn Marino
3363*e4b17023SJohn Marino static tree
c_parser_asm_string_literal(c_parser * parser)3364*e4b17023SJohn Marino c_parser_asm_string_literal (c_parser *parser)
3365*e4b17023SJohn Marino {
3366*e4b17023SJohn Marino tree str;
3367*e4b17023SJohn Marino int save_flag = warn_overlength_strings;
3368*e4b17023SJohn Marino warn_overlength_strings = 0;
3369*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_STRING))
3370*e4b17023SJohn Marino {
3371*e4b17023SJohn Marino str = c_parser_peek_token (parser)->value;
3372*e4b17023SJohn Marino c_parser_consume_token (parser);
3373*e4b17023SJohn Marino }
3374*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_WSTRING))
3375*e4b17023SJohn Marino {
3376*e4b17023SJohn Marino error_at (c_parser_peek_token (parser)->location,
3377*e4b17023SJohn Marino "wide string literal in %<asm%>");
3378*e4b17023SJohn Marino str = build_string (1, "");
3379*e4b17023SJohn Marino c_parser_consume_token (parser);
3380*e4b17023SJohn Marino }
3381*e4b17023SJohn Marino else
3382*e4b17023SJohn Marino {
3383*e4b17023SJohn Marino c_parser_error (parser, "expected string literal");
3384*e4b17023SJohn Marino str = NULL_TREE;
3385*e4b17023SJohn Marino }
3386*e4b17023SJohn Marino warn_overlength_strings = save_flag;
3387*e4b17023SJohn Marino return str;
3388*e4b17023SJohn Marino }
3389*e4b17023SJohn Marino
3390*e4b17023SJohn Marino /* Parse a simple asm expression. This is used in restricted
3391*e4b17023SJohn Marino contexts, where a full expression with inputs and outputs does not
3392*e4b17023SJohn Marino make sense. This is a GNU extension.
3393*e4b17023SJohn Marino
3394*e4b17023SJohn Marino simple-asm-expr:
3395*e4b17023SJohn Marino asm ( asm-string-literal )
3396*e4b17023SJohn Marino */
3397*e4b17023SJohn Marino
3398*e4b17023SJohn Marino static tree
c_parser_simple_asm_expr(c_parser * parser)3399*e4b17023SJohn Marino c_parser_simple_asm_expr (c_parser *parser)
3400*e4b17023SJohn Marino {
3401*e4b17023SJohn Marino tree str;
3402*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
3403*e4b17023SJohn Marino /* ??? Follow the C++ parser rather than using the
3404*e4b17023SJohn Marino lex_untranslated_string kludge. */
3405*e4b17023SJohn Marino parser->lex_untranslated_string = true;
3406*e4b17023SJohn Marino c_parser_consume_token (parser);
3407*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
3408*e4b17023SJohn Marino {
3409*e4b17023SJohn Marino parser->lex_untranslated_string = false;
3410*e4b17023SJohn Marino return NULL_TREE;
3411*e4b17023SJohn Marino }
3412*e4b17023SJohn Marino str = c_parser_asm_string_literal (parser);
3413*e4b17023SJohn Marino parser->lex_untranslated_string = false;
3414*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
3415*e4b17023SJohn Marino {
3416*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3417*e4b17023SJohn Marino return NULL_TREE;
3418*e4b17023SJohn Marino }
3419*e4b17023SJohn Marino return str;
3420*e4b17023SJohn Marino }
3421*e4b17023SJohn Marino
3422*e4b17023SJohn Marino static tree
c_parser_attribute_any_word(c_parser * parser)3423*e4b17023SJohn Marino c_parser_attribute_any_word (c_parser *parser)
3424*e4b17023SJohn Marino {
3425*e4b17023SJohn Marino tree attr_name = NULL_TREE;
3426*e4b17023SJohn Marino
3427*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_KEYWORD))
3428*e4b17023SJohn Marino {
3429*e4b17023SJohn Marino /* ??? See comment above about what keywords are accepted here. */
3430*e4b17023SJohn Marino bool ok;
3431*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->keyword)
3432*e4b17023SJohn Marino {
3433*e4b17023SJohn Marino case RID_STATIC:
3434*e4b17023SJohn Marino case RID_UNSIGNED:
3435*e4b17023SJohn Marino case RID_LONG:
3436*e4b17023SJohn Marino case RID_INT128:
3437*e4b17023SJohn Marino case RID_CONST:
3438*e4b17023SJohn Marino case RID_EXTERN:
3439*e4b17023SJohn Marino case RID_REGISTER:
3440*e4b17023SJohn Marino case RID_TYPEDEF:
3441*e4b17023SJohn Marino case RID_SHORT:
3442*e4b17023SJohn Marino case RID_INLINE:
3443*e4b17023SJohn Marino case RID_NORETURN:
3444*e4b17023SJohn Marino case RID_VOLATILE:
3445*e4b17023SJohn Marino case RID_SIGNED:
3446*e4b17023SJohn Marino case RID_AUTO:
3447*e4b17023SJohn Marino case RID_RESTRICT:
3448*e4b17023SJohn Marino case RID_COMPLEX:
3449*e4b17023SJohn Marino case RID_THREAD:
3450*e4b17023SJohn Marino case RID_INT:
3451*e4b17023SJohn Marino case RID_CHAR:
3452*e4b17023SJohn Marino case RID_FLOAT:
3453*e4b17023SJohn Marino case RID_DOUBLE:
3454*e4b17023SJohn Marino case RID_VOID:
3455*e4b17023SJohn Marino case RID_DFLOAT32:
3456*e4b17023SJohn Marino case RID_DFLOAT64:
3457*e4b17023SJohn Marino case RID_DFLOAT128:
3458*e4b17023SJohn Marino case RID_BOOL:
3459*e4b17023SJohn Marino case RID_FRACT:
3460*e4b17023SJohn Marino case RID_ACCUM:
3461*e4b17023SJohn Marino case RID_SAT:
3462*e4b17023SJohn Marino case RID_TRANSACTION_ATOMIC:
3463*e4b17023SJohn Marino case RID_TRANSACTION_CANCEL:
3464*e4b17023SJohn Marino ok = true;
3465*e4b17023SJohn Marino break;
3466*e4b17023SJohn Marino default:
3467*e4b17023SJohn Marino ok = false;
3468*e4b17023SJohn Marino break;
3469*e4b17023SJohn Marino }
3470*e4b17023SJohn Marino if (!ok)
3471*e4b17023SJohn Marino return NULL_TREE;
3472*e4b17023SJohn Marino
3473*e4b17023SJohn Marino /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
3474*e4b17023SJohn Marino attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
3475*e4b17023SJohn Marino }
3476*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_NAME))
3477*e4b17023SJohn Marino attr_name = c_parser_peek_token (parser)->value;
3478*e4b17023SJohn Marino
3479*e4b17023SJohn Marino return attr_name;
3480*e4b17023SJohn Marino }
3481*e4b17023SJohn Marino
3482*e4b17023SJohn Marino /* Parse (possibly empty) attributes. This is a GNU extension.
3483*e4b17023SJohn Marino
3484*e4b17023SJohn Marino attributes:
3485*e4b17023SJohn Marino empty
3486*e4b17023SJohn Marino attributes attribute
3487*e4b17023SJohn Marino
3488*e4b17023SJohn Marino attribute:
3489*e4b17023SJohn Marino __attribute__ ( ( attribute-list ) )
3490*e4b17023SJohn Marino
3491*e4b17023SJohn Marino attribute-list:
3492*e4b17023SJohn Marino attrib
3493*e4b17023SJohn Marino attribute_list , attrib
3494*e4b17023SJohn Marino
3495*e4b17023SJohn Marino attrib:
3496*e4b17023SJohn Marino empty
3497*e4b17023SJohn Marino any-word
3498*e4b17023SJohn Marino any-word ( identifier )
3499*e4b17023SJohn Marino any-word ( identifier , nonempty-expr-list )
3500*e4b17023SJohn Marino any-word ( expr-list )
3501*e4b17023SJohn Marino
3502*e4b17023SJohn Marino where the "identifier" must not be declared as a type, and
3503*e4b17023SJohn Marino "any-word" may be any identifier (including one declared as a
3504*e4b17023SJohn Marino type), a reserved word storage class specifier, type specifier or
3505*e4b17023SJohn Marino type qualifier. ??? This still leaves out most reserved keywords
3506*e4b17023SJohn Marino (following the old parser), shouldn't we include them, and why not
3507*e4b17023SJohn Marino allow identifiers declared as types to start the arguments? */
3508*e4b17023SJohn Marino
3509*e4b17023SJohn Marino static tree
c_parser_attributes(c_parser * parser)3510*e4b17023SJohn Marino c_parser_attributes (c_parser *parser)
3511*e4b17023SJohn Marino {
3512*e4b17023SJohn Marino tree attrs = NULL_TREE;
3513*e4b17023SJohn Marino while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3514*e4b17023SJohn Marino {
3515*e4b17023SJohn Marino /* ??? Follow the C++ parser rather than using the
3516*e4b17023SJohn Marino lex_untranslated_string kludge. */
3517*e4b17023SJohn Marino parser->lex_untranslated_string = true;
3518*e4b17023SJohn Marino c_parser_consume_token (parser);
3519*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
3520*e4b17023SJohn Marino {
3521*e4b17023SJohn Marino parser->lex_untranslated_string = false;
3522*e4b17023SJohn Marino return attrs;
3523*e4b17023SJohn Marino }
3524*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
3525*e4b17023SJohn Marino {
3526*e4b17023SJohn Marino parser->lex_untranslated_string = false;
3527*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3528*e4b17023SJohn Marino return attrs;
3529*e4b17023SJohn Marino }
3530*e4b17023SJohn Marino /* Parse the attribute list. */
3531*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_COMMA)
3532*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_NAME)
3533*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_KEYWORD))
3534*e4b17023SJohn Marino {
3535*e4b17023SJohn Marino tree attr, attr_name, attr_args;
3536*e4b17023SJohn Marino VEC(tree,gc) *expr_list;
3537*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
3538*e4b17023SJohn Marino {
3539*e4b17023SJohn Marino c_parser_consume_token (parser);
3540*e4b17023SJohn Marino continue;
3541*e4b17023SJohn Marino }
3542*e4b17023SJohn Marino
3543*e4b17023SJohn Marino attr_name = c_parser_attribute_any_word (parser);
3544*e4b17023SJohn Marino if (attr_name == NULL)
3545*e4b17023SJohn Marino break;
3546*e4b17023SJohn Marino c_parser_consume_token (parser);
3547*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
3548*e4b17023SJohn Marino {
3549*e4b17023SJohn Marino attr = build_tree_list (attr_name, NULL_TREE);
3550*e4b17023SJohn Marino attrs = chainon (attrs, attr);
3551*e4b17023SJohn Marino continue;
3552*e4b17023SJohn Marino }
3553*e4b17023SJohn Marino c_parser_consume_token (parser);
3554*e4b17023SJohn Marino /* Parse the attribute contents. If they start with an
3555*e4b17023SJohn Marino identifier which is followed by a comma or close
3556*e4b17023SJohn Marino parenthesis, then the arguments start with that
3557*e4b17023SJohn Marino identifier; otherwise they are an expression list.
3558*e4b17023SJohn Marino In objective-c the identifier may be a classname. */
3559*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME)
3560*e4b17023SJohn Marino && (c_parser_peek_token (parser)->id_kind == C_ID_ID
3561*e4b17023SJohn Marino || (c_dialect_objc ()
3562*e4b17023SJohn Marino && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3563*e4b17023SJohn Marino && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
3564*e4b17023SJohn Marino || (c_parser_peek_2nd_token (parser)->type
3565*e4b17023SJohn Marino == CPP_CLOSE_PAREN)))
3566*e4b17023SJohn Marino {
3567*e4b17023SJohn Marino tree arg1 = c_parser_peek_token (parser)->value;
3568*e4b17023SJohn Marino c_parser_consume_token (parser);
3569*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3570*e4b17023SJohn Marino attr_args = build_tree_list (NULL_TREE, arg1);
3571*e4b17023SJohn Marino else
3572*e4b17023SJohn Marino {
3573*e4b17023SJohn Marino tree tree_list;
3574*e4b17023SJohn Marino c_parser_consume_token (parser);
3575*e4b17023SJohn Marino expr_list = c_parser_expr_list (parser, false, true, NULL);
3576*e4b17023SJohn Marino tree_list = build_tree_list_vec (expr_list);
3577*e4b17023SJohn Marino attr_args = tree_cons (NULL_TREE, arg1, tree_list);
3578*e4b17023SJohn Marino release_tree_vector (expr_list);
3579*e4b17023SJohn Marino }
3580*e4b17023SJohn Marino }
3581*e4b17023SJohn Marino else
3582*e4b17023SJohn Marino {
3583*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3584*e4b17023SJohn Marino attr_args = NULL_TREE;
3585*e4b17023SJohn Marino else
3586*e4b17023SJohn Marino {
3587*e4b17023SJohn Marino expr_list = c_parser_expr_list (parser, false, true, NULL);
3588*e4b17023SJohn Marino attr_args = build_tree_list_vec (expr_list);
3589*e4b17023SJohn Marino release_tree_vector (expr_list);
3590*e4b17023SJohn Marino }
3591*e4b17023SJohn Marino }
3592*e4b17023SJohn Marino attr = build_tree_list (attr_name, attr_args);
3593*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3594*e4b17023SJohn Marino c_parser_consume_token (parser);
3595*e4b17023SJohn Marino else
3596*e4b17023SJohn Marino {
3597*e4b17023SJohn Marino parser->lex_untranslated_string = false;
3598*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3599*e4b17023SJohn Marino "expected %<)%>");
3600*e4b17023SJohn Marino return attrs;
3601*e4b17023SJohn Marino }
3602*e4b17023SJohn Marino attrs = chainon (attrs, attr);
3603*e4b17023SJohn Marino }
3604*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3605*e4b17023SJohn Marino c_parser_consume_token (parser);
3606*e4b17023SJohn Marino else
3607*e4b17023SJohn Marino {
3608*e4b17023SJohn Marino parser->lex_untranslated_string = false;
3609*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3610*e4b17023SJohn Marino "expected %<)%>");
3611*e4b17023SJohn Marino return attrs;
3612*e4b17023SJohn Marino }
3613*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3614*e4b17023SJohn Marino c_parser_consume_token (parser);
3615*e4b17023SJohn Marino else
3616*e4b17023SJohn Marino {
3617*e4b17023SJohn Marino parser->lex_untranslated_string = false;
3618*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3619*e4b17023SJohn Marino "expected %<)%>");
3620*e4b17023SJohn Marino return attrs;
3621*e4b17023SJohn Marino }
3622*e4b17023SJohn Marino parser->lex_untranslated_string = false;
3623*e4b17023SJohn Marino }
3624*e4b17023SJohn Marino return attrs;
3625*e4b17023SJohn Marino }
3626*e4b17023SJohn Marino
3627*e4b17023SJohn Marino /* Parse a type name (C90 6.5.5, C99 6.7.6).
3628*e4b17023SJohn Marino
3629*e4b17023SJohn Marino type-name:
3630*e4b17023SJohn Marino specifier-qualifier-list abstract-declarator[opt]
3631*e4b17023SJohn Marino */
3632*e4b17023SJohn Marino
3633*e4b17023SJohn Marino static struct c_type_name *
c_parser_type_name(c_parser * parser)3634*e4b17023SJohn Marino c_parser_type_name (c_parser *parser)
3635*e4b17023SJohn Marino {
3636*e4b17023SJohn Marino struct c_declspecs *specs = build_null_declspecs ();
3637*e4b17023SJohn Marino struct c_declarator *declarator;
3638*e4b17023SJohn Marino struct c_type_name *ret;
3639*e4b17023SJohn Marino bool dummy = false;
3640*e4b17023SJohn Marino c_parser_declspecs (parser, specs, false, true, true, cla_prefer_type);
3641*e4b17023SJohn Marino if (!specs->declspecs_seen_p)
3642*e4b17023SJohn Marino {
3643*e4b17023SJohn Marino c_parser_error (parser, "expected specifier-qualifier-list");
3644*e4b17023SJohn Marino return NULL;
3645*e4b17023SJohn Marino }
3646*e4b17023SJohn Marino if (specs->type != error_mark_node)
3647*e4b17023SJohn Marino {
3648*e4b17023SJohn Marino pending_xref_error ();
3649*e4b17023SJohn Marino finish_declspecs (specs);
3650*e4b17023SJohn Marino }
3651*e4b17023SJohn Marino declarator = c_parser_declarator (parser,
3652*e4b17023SJohn Marino specs->typespec_kind != ctsk_none,
3653*e4b17023SJohn Marino C_DTR_ABSTRACT, &dummy);
3654*e4b17023SJohn Marino if (declarator == NULL)
3655*e4b17023SJohn Marino return NULL;
3656*e4b17023SJohn Marino ret = XOBNEW (&parser_obstack, struct c_type_name);
3657*e4b17023SJohn Marino ret->specs = specs;
3658*e4b17023SJohn Marino ret->declarator = declarator;
3659*e4b17023SJohn Marino return ret;
3660*e4b17023SJohn Marino }
3661*e4b17023SJohn Marino
3662*e4b17023SJohn Marino /* Parse an initializer (C90 6.5.7, C99 6.7.8).
3663*e4b17023SJohn Marino
3664*e4b17023SJohn Marino initializer:
3665*e4b17023SJohn Marino assignment-expression
3666*e4b17023SJohn Marino { initializer-list }
3667*e4b17023SJohn Marino { initializer-list , }
3668*e4b17023SJohn Marino
3669*e4b17023SJohn Marino initializer-list:
3670*e4b17023SJohn Marino designation[opt] initializer
3671*e4b17023SJohn Marino initializer-list , designation[opt] initializer
3672*e4b17023SJohn Marino
3673*e4b17023SJohn Marino designation:
3674*e4b17023SJohn Marino designator-list =
3675*e4b17023SJohn Marino
3676*e4b17023SJohn Marino designator-list:
3677*e4b17023SJohn Marino designator
3678*e4b17023SJohn Marino designator-list designator
3679*e4b17023SJohn Marino
3680*e4b17023SJohn Marino designator:
3681*e4b17023SJohn Marino array-designator
3682*e4b17023SJohn Marino . identifier
3683*e4b17023SJohn Marino
3684*e4b17023SJohn Marino array-designator:
3685*e4b17023SJohn Marino [ constant-expression ]
3686*e4b17023SJohn Marino
3687*e4b17023SJohn Marino GNU extensions:
3688*e4b17023SJohn Marino
3689*e4b17023SJohn Marino initializer:
3690*e4b17023SJohn Marino { }
3691*e4b17023SJohn Marino
3692*e4b17023SJohn Marino designation:
3693*e4b17023SJohn Marino array-designator
3694*e4b17023SJohn Marino identifier :
3695*e4b17023SJohn Marino
3696*e4b17023SJohn Marino array-designator:
3697*e4b17023SJohn Marino [ constant-expression ... constant-expression ]
3698*e4b17023SJohn Marino
3699*e4b17023SJohn Marino Any expression without commas is accepted in the syntax for the
3700*e4b17023SJohn Marino constant-expressions, with non-constant expressions rejected later.
3701*e4b17023SJohn Marino
3702*e4b17023SJohn Marino This function is only used for top-level initializers; for nested
3703*e4b17023SJohn Marino ones, see c_parser_initval. */
3704*e4b17023SJohn Marino
3705*e4b17023SJohn Marino static struct c_expr
c_parser_initializer(c_parser * parser)3706*e4b17023SJohn Marino c_parser_initializer (c_parser *parser)
3707*e4b17023SJohn Marino {
3708*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3709*e4b17023SJohn Marino return c_parser_braced_init (parser, NULL_TREE, false);
3710*e4b17023SJohn Marino else
3711*e4b17023SJohn Marino {
3712*e4b17023SJohn Marino struct c_expr ret;
3713*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
3714*e4b17023SJohn Marino ret = c_parser_expr_no_commas (parser, NULL);
3715*e4b17023SJohn Marino if (TREE_CODE (ret.value) != STRING_CST
3716*e4b17023SJohn Marino && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
3717*e4b17023SJohn Marino ret = default_function_array_read_conversion (loc, ret);
3718*e4b17023SJohn Marino return ret;
3719*e4b17023SJohn Marino }
3720*e4b17023SJohn Marino }
3721*e4b17023SJohn Marino
3722*e4b17023SJohn Marino /* Parse a braced initializer list. TYPE is the type specified for a
3723*e4b17023SJohn Marino compound literal, and NULL_TREE for other initializers and for
3724*e4b17023SJohn Marino nested braced lists. NESTED_P is true for nested braced lists,
3725*e4b17023SJohn Marino false for the list of a compound literal or the list that is the
3726*e4b17023SJohn Marino top-level initializer in a declaration. */
3727*e4b17023SJohn Marino
3728*e4b17023SJohn Marino static struct c_expr
c_parser_braced_init(c_parser * parser,tree type,bool nested_p)3729*e4b17023SJohn Marino c_parser_braced_init (c_parser *parser, tree type, bool nested_p)
3730*e4b17023SJohn Marino {
3731*e4b17023SJohn Marino struct c_expr ret;
3732*e4b17023SJohn Marino struct obstack braced_init_obstack;
3733*e4b17023SJohn Marino location_t brace_loc = c_parser_peek_token (parser)->location;
3734*e4b17023SJohn Marino gcc_obstack_init (&braced_init_obstack);
3735*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
3736*e4b17023SJohn Marino c_parser_consume_token (parser);
3737*e4b17023SJohn Marino if (nested_p)
3738*e4b17023SJohn Marino push_init_level (0, &braced_init_obstack);
3739*e4b17023SJohn Marino else
3740*e4b17023SJohn Marino really_start_incremental_init (type);
3741*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3742*e4b17023SJohn Marino {
3743*e4b17023SJohn Marino pedwarn (brace_loc, OPT_pedantic, "ISO C forbids empty initializer braces");
3744*e4b17023SJohn Marino }
3745*e4b17023SJohn Marino else
3746*e4b17023SJohn Marino {
3747*e4b17023SJohn Marino /* Parse a non-empty initializer list, possibly with a trailing
3748*e4b17023SJohn Marino comma. */
3749*e4b17023SJohn Marino while (true)
3750*e4b17023SJohn Marino {
3751*e4b17023SJohn Marino c_parser_initelt (parser, &braced_init_obstack);
3752*e4b17023SJohn Marino if (parser->error)
3753*e4b17023SJohn Marino break;
3754*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
3755*e4b17023SJohn Marino c_parser_consume_token (parser);
3756*e4b17023SJohn Marino else
3757*e4b17023SJohn Marino break;
3758*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3759*e4b17023SJohn Marino break;
3760*e4b17023SJohn Marino }
3761*e4b17023SJohn Marino }
3762*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
3763*e4b17023SJohn Marino {
3764*e4b17023SJohn Marino ret.value = error_mark_node;
3765*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
3766*e4b17023SJohn Marino ret.original_type = NULL;
3767*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>");
3768*e4b17023SJohn Marino pop_init_level (0, &braced_init_obstack);
3769*e4b17023SJohn Marino obstack_free (&braced_init_obstack, NULL);
3770*e4b17023SJohn Marino return ret;
3771*e4b17023SJohn Marino }
3772*e4b17023SJohn Marino c_parser_consume_token (parser);
3773*e4b17023SJohn Marino ret = pop_init_level (0, &braced_init_obstack);
3774*e4b17023SJohn Marino obstack_free (&braced_init_obstack, NULL);
3775*e4b17023SJohn Marino return ret;
3776*e4b17023SJohn Marino }
3777*e4b17023SJohn Marino
3778*e4b17023SJohn Marino /* Parse a nested initializer, including designators. */
3779*e4b17023SJohn Marino
3780*e4b17023SJohn Marino static void
c_parser_initelt(c_parser * parser,struct obstack * braced_init_obstack)3781*e4b17023SJohn Marino c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
3782*e4b17023SJohn Marino {
3783*e4b17023SJohn Marino /* Parse any designator or designator list. A single array
3784*e4b17023SJohn Marino designator may have the subsequent "=" omitted in GNU C, but a
3785*e4b17023SJohn Marino longer list or a structure member designator may not. */
3786*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME)
3787*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
3788*e4b17023SJohn Marino {
3789*e4b17023SJohn Marino /* Old-style structure member designator. */
3790*e4b17023SJohn Marino set_init_label (c_parser_peek_token (parser)->value,
3791*e4b17023SJohn Marino braced_init_obstack);
3792*e4b17023SJohn Marino /* Use the colon as the error location. */
3793*e4b17023SJohn Marino pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic,
3794*e4b17023SJohn Marino "obsolete use of designated initializer with %<:%>");
3795*e4b17023SJohn Marino c_parser_consume_token (parser);
3796*e4b17023SJohn Marino c_parser_consume_token (parser);
3797*e4b17023SJohn Marino }
3798*e4b17023SJohn Marino else
3799*e4b17023SJohn Marino {
3800*e4b17023SJohn Marino /* des_seen is 0 if there have been no designators, 1 if there
3801*e4b17023SJohn Marino has been a single array designator and 2 otherwise. */
3802*e4b17023SJohn Marino int des_seen = 0;
3803*e4b17023SJohn Marino /* Location of a designator. */
3804*e4b17023SJohn Marino location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3805*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3806*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_DOT))
3807*e4b17023SJohn Marino {
3808*e4b17023SJohn Marino int des_prev = des_seen;
3809*e4b17023SJohn Marino if (!des_seen)
3810*e4b17023SJohn Marino des_loc = c_parser_peek_token (parser)->location;
3811*e4b17023SJohn Marino if (des_seen < 2)
3812*e4b17023SJohn Marino des_seen++;
3813*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_DOT))
3814*e4b17023SJohn Marino {
3815*e4b17023SJohn Marino des_seen = 2;
3816*e4b17023SJohn Marino c_parser_consume_token (parser);
3817*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
3818*e4b17023SJohn Marino {
3819*e4b17023SJohn Marino set_init_label (c_parser_peek_token (parser)->value,
3820*e4b17023SJohn Marino braced_init_obstack);
3821*e4b17023SJohn Marino c_parser_consume_token (parser);
3822*e4b17023SJohn Marino }
3823*e4b17023SJohn Marino else
3824*e4b17023SJohn Marino {
3825*e4b17023SJohn Marino struct c_expr init;
3826*e4b17023SJohn Marino init.value = error_mark_node;
3827*e4b17023SJohn Marino init.original_code = ERROR_MARK;
3828*e4b17023SJohn Marino init.original_type = NULL;
3829*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
3830*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_COMMA, NULL);
3831*e4b17023SJohn Marino process_init_element (init, false, braced_init_obstack);
3832*e4b17023SJohn Marino return;
3833*e4b17023SJohn Marino }
3834*e4b17023SJohn Marino }
3835*e4b17023SJohn Marino else
3836*e4b17023SJohn Marino {
3837*e4b17023SJohn Marino tree first, second;
3838*e4b17023SJohn Marino location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3839*e4b17023SJohn Marino /* ??? Following the old parser, [ objc-receiver
3840*e4b17023SJohn Marino objc-message-args ] is accepted as an initializer,
3841*e4b17023SJohn Marino being distinguished from a designator by what follows
3842*e4b17023SJohn Marino the first assignment expression inside the square
3843*e4b17023SJohn Marino brackets, but after a first array designator a
3844*e4b17023SJohn Marino subsequent square bracket is for Objective-C taken to
3845*e4b17023SJohn Marino start an expression, using the obsolete form of
3846*e4b17023SJohn Marino designated initializer without '=', rather than
3847*e4b17023SJohn Marino possibly being a second level of designation: in LALR
3848*e4b17023SJohn Marino terms, the '[' is shifted rather than reducing
3849*e4b17023SJohn Marino designator to designator-list. */
3850*e4b17023SJohn Marino if (des_prev == 1 && c_dialect_objc ())
3851*e4b17023SJohn Marino {
3852*e4b17023SJohn Marino des_seen = des_prev;
3853*e4b17023SJohn Marino break;
3854*e4b17023SJohn Marino }
3855*e4b17023SJohn Marino if (des_prev == 0 && c_dialect_objc ())
3856*e4b17023SJohn Marino {
3857*e4b17023SJohn Marino /* This might be an array designator or an
3858*e4b17023SJohn Marino Objective-C message expression. If the former,
3859*e4b17023SJohn Marino continue parsing here; if the latter, parse the
3860*e4b17023SJohn Marino remainder of the initializer given the starting
3861*e4b17023SJohn Marino primary-expression. ??? It might make sense to
3862*e4b17023SJohn Marino distinguish when des_prev == 1 as well; see
3863*e4b17023SJohn Marino previous comment. */
3864*e4b17023SJohn Marino tree rec, args;
3865*e4b17023SJohn Marino struct c_expr mexpr;
3866*e4b17023SJohn Marino c_parser_consume_token (parser);
3867*e4b17023SJohn Marino if (c_parser_peek_token (parser)->type == CPP_NAME
3868*e4b17023SJohn Marino && ((c_parser_peek_token (parser)->id_kind
3869*e4b17023SJohn Marino == C_ID_TYPENAME)
3870*e4b17023SJohn Marino || (c_parser_peek_token (parser)->id_kind
3871*e4b17023SJohn Marino == C_ID_CLASSNAME)))
3872*e4b17023SJohn Marino {
3873*e4b17023SJohn Marino /* Type name receiver. */
3874*e4b17023SJohn Marino tree id = c_parser_peek_token (parser)->value;
3875*e4b17023SJohn Marino c_parser_consume_token (parser);
3876*e4b17023SJohn Marino rec = objc_get_class_reference (id);
3877*e4b17023SJohn Marino goto parse_message_args;
3878*e4b17023SJohn Marino }
3879*e4b17023SJohn Marino first = c_parser_expr_no_commas (parser, NULL).value;
3880*e4b17023SJohn Marino mark_exp_read (first);
3881*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
3882*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3883*e4b17023SJohn Marino goto array_desig_after_first;
3884*e4b17023SJohn Marino /* Expression receiver. So far only one part
3885*e4b17023SJohn Marino without commas has been parsed; there might be
3886*e4b17023SJohn Marino more of the expression. */
3887*e4b17023SJohn Marino rec = first;
3888*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_COMMA))
3889*e4b17023SJohn Marino {
3890*e4b17023SJohn Marino struct c_expr next;
3891*e4b17023SJohn Marino location_t comma_loc, exp_loc;
3892*e4b17023SJohn Marino comma_loc = c_parser_peek_token (parser)->location;
3893*e4b17023SJohn Marino c_parser_consume_token (parser);
3894*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
3895*e4b17023SJohn Marino next = c_parser_expr_no_commas (parser, NULL);
3896*e4b17023SJohn Marino next = default_function_array_read_conversion (exp_loc,
3897*e4b17023SJohn Marino next);
3898*e4b17023SJohn Marino rec = build_compound_expr (comma_loc, rec, next.value);
3899*e4b17023SJohn Marino }
3900*e4b17023SJohn Marino parse_message_args:
3901*e4b17023SJohn Marino /* Now parse the objc-message-args. */
3902*e4b17023SJohn Marino args = c_parser_objc_message_args (parser);
3903*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3904*e4b17023SJohn Marino "expected %<]%>");
3905*e4b17023SJohn Marino mexpr.value
3906*e4b17023SJohn Marino = objc_build_message_expr (rec, args);
3907*e4b17023SJohn Marino mexpr.original_code = ERROR_MARK;
3908*e4b17023SJohn Marino mexpr.original_type = NULL;
3909*e4b17023SJohn Marino /* Now parse and process the remainder of the
3910*e4b17023SJohn Marino initializer, starting with this message
3911*e4b17023SJohn Marino expression as a primary-expression. */
3912*e4b17023SJohn Marino c_parser_initval (parser, &mexpr, braced_init_obstack);
3913*e4b17023SJohn Marino return;
3914*e4b17023SJohn Marino }
3915*e4b17023SJohn Marino c_parser_consume_token (parser);
3916*e4b17023SJohn Marino first = c_parser_expr_no_commas (parser, NULL).value;
3917*e4b17023SJohn Marino mark_exp_read (first);
3918*e4b17023SJohn Marino array_desig_after_first:
3919*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
3920*e4b17023SJohn Marino {
3921*e4b17023SJohn Marino ellipsis_loc = c_parser_peek_token (parser)->location;
3922*e4b17023SJohn Marino c_parser_consume_token (parser);
3923*e4b17023SJohn Marino second = c_parser_expr_no_commas (parser, NULL).value;
3924*e4b17023SJohn Marino mark_exp_read (second);
3925*e4b17023SJohn Marino }
3926*e4b17023SJohn Marino else
3927*e4b17023SJohn Marino second = NULL_TREE;
3928*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3929*e4b17023SJohn Marino {
3930*e4b17023SJohn Marino c_parser_consume_token (parser);
3931*e4b17023SJohn Marino set_init_index (first, second, braced_init_obstack);
3932*e4b17023SJohn Marino if (second)
3933*e4b17023SJohn Marino pedwarn (ellipsis_loc, OPT_pedantic,
3934*e4b17023SJohn Marino "ISO C forbids specifying range of elements to initialize");
3935*e4b17023SJohn Marino }
3936*e4b17023SJohn Marino else
3937*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3938*e4b17023SJohn Marino "expected %<]%>");
3939*e4b17023SJohn Marino }
3940*e4b17023SJohn Marino }
3941*e4b17023SJohn Marino if (des_seen >= 1)
3942*e4b17023SJohn Marino {
3943*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_EQ))
3944*e4b17023SJohn Marino {
3945*e4b17023SJohn Marino if (!flag_isoc99)
3946*e4b17023SJohn Marino pedwarn (des_loc, OPT_pedantic,
3947*e4b17023SJohn Marino "ISO C90 forbids specifying subobject to initialize");
3948*e4b17023SJohn Marino c_parser_consume_token (parser);
3949*e4b17023SJohn Marino }
3950*e4b17023SJohn Marino else
3951*e4b17023SJohn Marino {
3952*e4b17023SJohn Marino if (des_seen == 1)
3953*e4b17023SJohn Marino pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
3954*e4b17023SJohn Marino "obsolete use of designated initializer without %<=%>");
3955*e4b17023SJohn Marino else
3956*e4b17023SJohn Marino {
3957*e4b17023SJohn Marino struct c_expr init;
3958*e4b17023SJohn Marino init.value = error_mark_node;
3959*e4b17023SJohn Marino init.original_code = ERROR_MARK;
3960*e4b17023SJohn Marino init.original_type = NULL;
3961*e4b17023SJohn Marino c_parser_error (parser, "expected %<=%>");
3962*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_COMMA, NULL);
3963*e4b17023SJohn Marino process_init_element (init, false, braced_init_obstack);
3964*e4b17023SJohn Marino return;
3965*e4b17023SJohn Marino }
3966*e4b17023SJohn Marino }
3967*e4b17023SJohn Marino }
3968*e4b17023SJohn Marino }
3969*e4b17023SJohn Marino c_parser_initval (parser, NULL, braced_init_obstack);
3970*e4b17023SJohn Marino }
3971*e4b17023SJohn Marino
3972*e4b17023SJohn Marino /* Parse a nested initializer; as c_parser_initializer but parses
3973*e4b17023SJohn Marino initializers within braced lists, after any designators have been
3974*e4b17023SJohn Marino applied. If AFTER is not NULL then it is an Objective-C message
3975*e4b17023SJohn Marino expression which is the primary-expression starting the
3976*e4b17023SJohn Marino initializer. */
3977*e4b17023SJohn Marino
3978*e4b17023SJohn Marino static void
c_parser_initval(c_parser * parser,struct c_expr * after,struct obstack * braced_init_obstack)3979*e4b17023SJohn Marino c_parser_initval (c_parser *parser, struct c_expr *after,
3980*e4b17023SJohn Marino struct obstack * braced_init_obstack)
3981*e4b17023SJohn Marino {
3982*e4b17023SJohn Marino struct c_expr init;
3983*e4b17023SJohn Marino gcc_assert (!after || c_dialect_objc ());
3984*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
3985*e4b17023SJohn Marino init = c_parser_braced_init (parser, NULL_TREE, true);
3986*e4b17023SJohn Marino else
3987*e4b17023SJohn Marino {
3988*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
3989*e4b17023SJohn Marino init = c_parser_expr_no_commas (parser, after);
3990*e4b17023SJohn Marino if (init.value != NULL_TREE
3991*e4b17023SJohn Marino && TREE_CODE (init.value) != STRING_CST
3992*e4b17023SJohn Marino && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
3993*e4b17023SJohn Marino init = default_function_array_read_conversion (loc, init);
3994*e4b17023SJohn Marino }
3995*e4b17023SJohn Marino process_init_element (init, false, braced_init_obstack);
3996*e4b17023SJohn Marino }
3997*e4b17023SJohn Marino
3998*e4b17023SJohn Marino /* Parse a compound statement (possibly a function body) (C90 6.6.2,
3999*e4b17023SJohn Marino C99 6.8.2).
4000*e4b17023SJohn Marino
4001*e4b17023SJohn Marino compound-statement:
4002*e4b17023SJohn Marino { block-item-list[opt] }
4003*e4b17023SJohn Marino { label-declarations block-item-list }
4004*e4b17023SJohn Marino
4005*e4b17023SJohn Marino block-item-list:
4006*e4b17023SJohn Marino block-item
4007*e4b17023SJohn Marino block-item-list block-item
4008*e4b17023SJohn Marino
4009*e4b17023SJohn Marino block-item:
4010*e4b17023SJohn Marino nested-declaration
4011*e4b17023SJohn Marino statement
4012*e4b17023SJohn Marino
4013*e4b17023SJohn Marino nested-declaration:
4014*e4b17023SJohn Marino declaration
4015*e4b17023SJohn Marino
4016*e4b17023SJohn Marino GNU extensions:
4017*e4b17023SJohn Marino
4018*e4b17023SJohn Marino compound-statement:
4019*e4b17023SJohn Marino { label-declarations block-item-list }
4020*e4b17023SJohn Marino
4021*e4b17023SJohn Marino nested-declaration:
4022*e4b17023SJohn Marino __extension__ nested-declaration
4023*e4b17023SJohn Marino nested-function-definition
4024*e4b17023SJohn Marino
4025*e4b17023SJohn Marino label-declarations:
4026*e4b17023SJohn Marino label-declaration
4027*e4b17023SJohn Marino label-declarations label-declaration
4028*e4b17023SJohn Marino
4029*e4b17023SJohn Marino label-declaration:
4030*e4b17023SJohn Marino __label__ identifier-list ;
4031*e4b17023SJohn Marino
4032*e4b17023SJohn Marino Allowing the mixing of declarations and code is new in C99. The
4033*e4b17023SJohn Marino GNU syntax also permits (not shown above) labels at the end of
4034*e4b17023SJohn Marino compound statements, which yield an error. We don't allow labels
4035*e4b17023SJohn Marino on declarations; this might seem like a natural extension, but
4036*e4b17023SJohn Marino there would be a conflict between attributes on the label and
4037*e4b17023SJohn Marino prefix attributes on the declaration. ??? The syntax follows the
4038*e4b17023SJohn Marino old parser in requiring something after label declarations.
4039*e4b17023SJohn Marino Although they are erroneous if the labels declared aren't defined,
4040*e4b17023SJohn Marino is it useful for the syntax to be this way?
4041*e4b17023SJohn Marino
4042*e4b17023SJohn Marino OpenMP:
4043*e4b17023SJohn Marino
4044*e4b17023SJohn Marino block-item:
4045*e4b17023SJohn Marino openmp-directive
4046*e4b17023SJohn Marino
4047*e4b17023SJohn Marino openmp-directive:
4048*e4b17023SJohn Marino barrier-directive
4049*e4b17023SJohn Marino flush-directive */
4050*e4b17023SJohn Marino
4051*e4b17023SJohn Marino static tree
c_parser_compound_statement(c_parser * parser)4052*e4b17023SJohn Marino c_parser_compound_statement (c_parser *parser)
4053*e4b17023SJohn Marino {
4054*e4b17023SJohn Marino tree stmt;
4055*e4b17023SJohn Marino location_t brace_loc;
4056*e4b17023SJohn Marino brace_loc = c_parser_peek_token (parser)->location;
4057*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
4058*e4b17023SJohn Marino {
4059*e4b17023SJohn Marino /* Ensure a scope is entered and left anyway to avoid confusion
4060*e4b17023SJohn Marino if we have just prepared to enter a function body. */
4061*e4b17023SJohn Marino stmt = c_begin_compound_stmt (true);
4062*e4b17023SJohn Marino c_end_compound_stmt (brace_loc, stmt, true);
4063*e4b17023SJohn Marino return error_mark_node;
4064*e4b17023SJohn Marino }
4065*e4b17023SJohn Marino stmt = c_begin_compound_stmt (true);
4066*e4b17023SJohn Marino c_parser_compound_statement_nostart (parser);
4067*e4b17023SJohn Marino return c_end_compound_stmt (brace_loc, stmt, true);
4068*e4b17023SJohn Marino }
4069*e4b17023SJohn Marino
4070*e4b17023SJohn Marino /* Parse a compound statement except for the opening brace. This is
4071*e4b17023SJohn Marino used for parsing both compound statements and statement expressions
4072*e4b17023SJohn Marino (which follow different paths to handling the opening). */
4073*e4b17023SJohn Marino
4074*e4b17023SJohn Marino static void
c_parser_compound_statement_nostart(c_parser * parser)4075*e4b17023SJohn Marino c_parser_compound_statement_nostart (c_parser *parser)
4076*e4b17023SJohn Marino {
4077*e4b17023SJohn Marino bool last_stmt = false;
4078*e4b17023SJohn Marino bool last_label = false;
4079*e4b17023SJohn Marino bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
4080*e4b17023SJohn Marino location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
4081*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4082*e4b17023SJohn Marino {
4083*e4b17023SJohn Marino c_parser_consume_token (parser);
4084*e4b17023SJohn Marino return;
4085*e4b17023SJohn Marino }
4086*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (true);
4087*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_LABEL))
4088*e4b17023SJohn Marino {
4089*e4b17023SJohn Marino /* Read zero or more forward-declarations for labels that nested
4090*e4b17023SJohn Marino functions can jump to. */
4091*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (false);
4092*e4b17023SJohn Marino while (c_parser_next_token_is_keyword (parser, RID_LABEL))
4093*e4b17023SJohn Marino {
4094*e4b17023SJohn Marino label_loc = c_parser_peek_token (parser)->location;
4095*e4b17023SJohn Marino c_parser_consume_token (parser);
4096*e4b17023SJohn Marino /* Any identifiers, including those declared as type names,
4097*e4b17023SJohn Marino are OK here. */
4098*e4b17023SJohn Marino while (true)
4099*e4b17023SJohn Marino {
4100*e4b17023SJohn Marino tree label;
4101*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
4102*e4b17023SJohn Marino {
4103*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
4104*e4b17023SJohn Marino break;
4105*e4b17023SJohn Marino }
4106*e4b17023SJohn Marino label
4107*e4b17023SJohn Marino = declare_label (c_parser_peek_token (parser)->value);
4108*e4b17023SJohn Marino C_DECLARED_LABEL_FLAG (label) = 1;
4109*e4b17023SJohn Marino add_stmt (build_stmt (label_loc, DECL_EXPR, label));
4110*e4b17023SJohn Marino c_parser_consume_token (parser);
4111*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
4112*e4b17023SJohn Marino c_parser_consume_token (parser);
4113*e4b17023SJohn Marino else
4114*e4b17023SJohn Marino break;
4115*e4b17023SJohn Marino }
4116*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4117*e4b17023SJohn Marino }
4118*e4b17023SJohn Marino pedwarn (label_loc, OPT_pedantic, "ISO C forbids label declarations");
4119*e4b17023SJohn Marino }
4120*e4b17023SJohn Marino /* We must now have at least one statement, label or declaration. */
4121*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4122*e4b17023SJohn Marino {
4123*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4124*e4b17023SJohn Marino c_parser_error (parser, "expected declaration or statement");
4125*e4b17023SJohn Marino c_parser_consume_token (parser);
4126*e4b17023SJohn Marino return;
4127*e4b17023SJohn Marino }
4128*e4b17023SJohn Marino while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
4129*e4b17023SJohn Marino {
4130*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
4131*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_CASE)
4132*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4133*e4b17023SJohn Marino || (c_parser_next_token_is (parser, CPP_NAME)
4134*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4135*e4b17023SJohn Marino {
4136*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_CASE))
4137*e4b17023SJohn Marino label_loc = c_parser_peek_2nd_token (parser)->location;
4138*e4b17023SJohn Marino else
4139*e4b17023SJohn Marino label_loc = c_parser_peek_token (parser)->location;
4140*e4b17023SJohn Marino last_label = true;
4141*e4b17023SJohn Marino last_stmt = false;
4142*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (false);
4143*e4b17023SJohn Marino c_parser_label (parser);
4144*e4b17023SJohn Marino }
4145*e4b17023SJohn Marino else if (!last_label
4146*e4b17023SJohn Marino && c_parser_next_tokens_start_declaration (parser))
4147*e4b17023SJohn Marino {
4148*e4b17023SJohn Marino last_label = false;
4149*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (false);
4150*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, true, true, true, true, true, NULL);
4151*e4b17023SJohn Marino if (last_stmt)
4152*e4b17023SJohn Marino pedwarn_c90 (loc,
4153*e4b17023SJohn Marino (pedantic && !flag_isoc99)
4154*e4b17023SJohn Marino ? OPT_pedantic
4155*e4b17023SJohn Marino : OPT_Wdeclaration_after_statement,
4156*e4b17023SJohn Marino "ISO C90 forbids mixed declarations and code");
4157*e4b17023SJohn Marino last_stmt = false;
4158*e4b17023SJohn Marino }
4159*e4b17023SJohn Marino else if (!last_label
4160*e4b17023SJohn Marino && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
4161*e4b17023SJohn Marino {
4162*e4b17023SJohn Marino /* __extension__ can start a declaration, but is also an
4163*e4b17023SJohn Marino unary operator that can start an expression. Consume all
4164*e4b17023SJohn Marino but the last of a possible series of __extension__ to
4165*e4b17023SJohn Marino determine which. */
4166*e4b17023SJohn Marino while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
4167*e4b17023SJohn Marino && (c_parser_peek_2nd_token (parser)->keyword
4168*e4b17023SJohn Marino == RID_EXTENSION))
4169*e4b17023SJohn Marino c_parser_consume_token (parser);
4170*e4b17023SJohn Marino if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
4171*e4b17023SJohn Marino {
4172*e4b17023SJohn Marino int ext;
4173*e4b17023SJohn Marino ext = disable_extension_diagnostics ();
4174*e4b17023SJohn Marino c_parser_consume_token (parser);
4175*e4b17023SJohn Marino last_label = false;
4176*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (false);
4177*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, true, true, true, true,
4178*e4b17023SJohn Marino true, NULL);
4179*e4b17023SJohn Marino /* Following the old parser, __extension__ does not
4180*e4b17023SJohn Marino disable this diagnostic. */
4181*e4b17023SJohn Marino restore_extension_diagnostics (ext);
4182*e4b17023SJohn Marino if (last_stmt)
4183*e4b17023SJohn Marino pedwarn_c90 (loc, (pedantic && !flag_isoc99)
4184*e4b17023SJohn Marino ? OPT_pedantic
4185*e4b17023SJohn Marino : OPT_Wdeclaration_after_statement,
4186*e4b17023SJohn Marino "ISO C90 forbids mixed declarations and code");
4187*e4b17023SJohn Marino last_stmt = false;
4188*e4b17023SJohn Marino }
4189*e4b17023SJohn Marino else
4190*e4b17023SJohn Marino goto statement;
4191*e4b17023SJohn Marino }
4192*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_PRAGMA))
4193*e4b17023SJohn Marino {
4194*e4b17023SJohn Marino /* External pragmas, and some omp pragmas, are not associated
4195*e4b17023SJohn Marino with regular c code, and so are not to be considered statements
4196*e4b17023SJohn Marino syntactically. This ensures that the user doesn't put them
4197*e4b17023SJohn Marino places that would turn into syntax errors if the directive
4198*e4b17023SJohn Marino were ignored. */
4199*e4b17023SJohn Marino if (c_parser_pragma (parser, pragma_compound))
4200*e4b17023SJohn Marino last_label = false, last_stmt = true;
4201*e4b17023SJohn Marino }
4202*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_EOF))
4203*e4b17023SJohn Marino {
4204*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4205*e4b17023SJohn Marino c_parser_error (parser, "expected declaration or statement");
4206*e4b17023SJohn Marino return;
4207*e4b17023SJohn Marino }
4208*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
4209*e4b17023SJohn Marino {
4210*e4b17023SJohn Marino if (parser->in_if_block)
4211*e4b17023SJohn Marino {
4212*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4213*e4b17023SJohn Marino error_at (loc, """expected %<}%> before %<else%>");
4214*e4b17023SJohn Marino return;
4215*e4b17023SJohn Marino }
4216*e4b17023SJohn Marino else
4217*e4b17023SJohn Marino {
4218*e4b17023SJohn Marino error_at (loc, "%<else%> without a previous %<if%>");
4219*e4b17023SJohn Marino c_parser_consume_token (parser);
4220*e4b17023SJohn Marino continue;
4221*e4b17023SJohn Marino }
4222*e4b17023SJohn Marino }
4223*e4b17023SJohn Marino else
4224*e4b17023SJohn Marino {
4225*e4b17023SJohn Marino statement:
4226*e4b17023SJohn Marino last_label = false;
4227*e4b17023SJohn Marino last_stmt = true;
4228*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (false);
4229*e4b17023SJohn Marino c_parser_statement_after_labels (parser);
4230*e4b17023SJohn Marino }
4231*e4b17023SJohn Marino
4232*e4b17023SJohn Marino parser->error = false;
4233*e4b17023SJohn Marino }
4234*e4b17023SJohn Marino if (last_label)
4235*e4b17023SJohn Marino error_at (label_loc, "label at end of compound statement");
4236*e4b17023SJohn Marino c_parser_consume_token (parser);
4237*e4b17023SJohn Marino /* Restore the value we started with. */
4238*e4b17023SJohn Marino mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
4239*e4b17023SJohn Marino }
4240*e4b17023SJohn Marino
4241*e4b17023SJohn Marino /* Parse a label (C90 6.6.1, C99 6.8.1).
4242*e4b17023SJohn Marino
4243*e4b17023SJohn Marino label:
4244*e4b17023SJohn Marino identifier : attributes[opt]
4245*e4b17023SJohn Marino case constant-expression :
4246*e4b17023SJohn Marino default :
4247*e4b17023SJohn Marino
4248*e4b17023SJohn Marino GNU extensions:
4249*e4b17023SJohn Marino
4250*e4b17023SJohn Marino label:
4251*e4b17023SJohn Marino case constant-expression ... constant-expression :
4252*e4b17023SJohn Marino
4253*e4b17023SJohn Marino The use of attributes on labels is a GNU extension. The syntax in
4254*e4b17023SJohn Marino GNU C accepts any expressions without commas, non-constant
4255*e4b17023SJohn Marino expressions being rejected later. */
4256*e4b17023SJohn Marino
4257*e4b17023SJohn Marino static void
c_parser_label(c_parser * parser)4258*e4b17023SJohn Marino c_parser_label (c_parser *parser)
4259*e4b17023SJohn Marino {
4260*e4b17023SJohn Marino location_t loc1 = c_parser_peek_token (parser)->location;
4261*e4b17023SJohn Marino tree label = NULL_TREE;
4262*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_CASE))
4263*e4b17023SJohn Marino {
4264*e4b17023SJohn Marino tree exp1, exp2;
4265*e4b17023SJohn Marino c_parser_consume_token (parser);
4266*e4b17023SJohn Marino exp1 = c_parser_expr_no_commas (parser, NULL).value;
4267*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COLON))
4268*e4b17023SJohn Marino {
4269*e4b17023SJohn Marino c_parser_consume_token (parser);
4270*e4b17023SJohn Marino label = do_case (loc1, exp1, NULL_TREE);
4271*e4b17023SJohn Marino }
4272*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4273*e4b17023SJohn Marino {
4274*e4b17023SJohn Marino c_parser_consume_token (parser);
4275*e4b17023SJohn Marino exp2 = c_parser_expr_no_commas (parser, NULL).value;
4276*e4b17023SJohn Marino if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
4277*e4b17023SJohn Marino label = do_case (loc1, exp1, exp2);
4278*e4b17023SJohn Marino }
4279*e4b17023SJohn Marino else
4280*e4b17023SJohn Marino c_parser_error (parser, "expected %<:%> or %<...%>");
4281*e4b17023SJohn Marino }
4282*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
4283*e4b17023SJohn Marino {
4284*e4b17023SJohn Marino c_parser_consume_token (parser);
4285*e4b17023SJohn Marino if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
4286*e4b17023SJohn Marino label = do_case (loc1, NULL_TREE, NULL_TREE);
4287*e4b17023SJohn Marino }
4288*e4b17023SJohn Marino else
4289*e4b17023SJohn Marino {
4290*e4b17023SJohn Marino tree name = c_parser_peek_token (parser)->value;
4291*e4b17023SJohn Marino tree tlab;
4292*e4b17023SJohn Marino tree attrs;
4293*e4b17023SJohn Marino location_t loc2 = c_parser_peek_token (parser)->location;
4294*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
4295*e4b17023SJohn Marino c_parser_consume_token (parser);
4296*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
4297*e4b17023SJohn Marino c_parser_consume_token (parser);
4298*e4b17023SJohn Marino attrs = c_parser_attributes (parser);
4299*e4b17023SJohn Marino tlab = define_label (loc2, name);
4300*e4b17023SJohn Marino if (tlab)
4301*e4b17023SJohn Marino {
4302*e4b17023SJohn Marino decl_attributes (&tlab, attrs, 0);
4303*e4b17023SJohn Marino label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
4304*e4b17023SJohn Marino }
4305*e4b17023SJohn Marino }
4306*e4b17023SJohn Marino if (label)
4307*e4b17023SJohn Marino {
4308*e4b17023SJohn Marino if (c_parser_next_tokens_start_declaration (parser))
4309*e4b17023SJohn Marino {
4310*e4b17023SJohn Marino error_at (c_parser_peek_token (parser)->location,
4311*e4b17023SJohn Marino "a label can only be part of a statement and "
4312*e4b17023SJohn Marino "a declaration is not a statement");
4313*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
4314*e4b17023SJohn Marino /*static_assert_ok*/ true,
4315*e4b17023SJohn Marino /*nested*/ true, /*empty_ok*/ false,
4316*e4b17023SJohn Marino /*start_attr_ok*/ true, NULL);
4317*e4b17023SJohn Marino }
4318*e4b17023SJohn Marino }
4319*e4b17023SJohn Marino }
4320*e4b17023SJohn Marino
4321*e4b17023SJohn Marino /* Parse a statement (C90 6.6, C99 6.8).
4322*e4b17023SJohn Marino
4323*e4b17023SJohn Marino statement:
4324*e4b17023SJohn Marino labeled-statement
4325*e4b17023SJohn Marino compound-statement
4326*e4b17023SJohn Marino expression-statement
4327*e4b17023SJohn Marino selection-statement
4328*e4b17023SJohn Marino iteration-statement
4329*e4b17023SJohn Marino jump-statement
4330*e4b17023SJohn Marino
4331*e4b17023SJohn Marino labeled-statement:
4332*e4b17023SJohn Marino label statement
4333*e4b17023SJohn Marino
4334*e4b17023SJohn Marino expression-statement:
4335*e4b17023SJohn Marino expression[opt] ;
4336*e4b17023SJohn Marino
4337*e4b17023SJohn Marino selection-statement:
4338*e4b17023SJohn Marino if-statement
4339*e4b17023SJohn Marino switch-statement
4340*e4b17023SJohn Marino
4341*e4b17023SJohn Marino iteration-statement:
4342*e4b17023SJohn Marino while-statement
4343*e4b17023SJohn Marino do-statement
4344*e4b17023SJohn Marino for-statement
4345*e4b17023SJohn Marino
4346*e4b17023SJohn Marino jump-statement:
4347*e4b17023SJohn Marino goto identifier ;
4348*e4b17023SJohn Marino continue ;
4349*e4b17023SJohn Marino break ;
4350*e4b17023SJohn Marino return expression[opt] ;
4351*e4b17023SJohn Marino
4352*e4b17023SJohn Marino GNU extensions:
4353*e4b17023SJohn Marino
4354*e4b17023SJohn Marino statement:
4355*e4b17023SJohn Marino asm-statement
4356*e4b17023SJohn Marino
4357*e4b17023SJohn Marino jump-statement:
4358*e4b17023SJohn Marino goto * expression ;
4359*e4b17023SJohn Marino
4360*e4b17023SJohn Marino Objective-C:
4361*e4b17023SJohn Marino
4362*e4b17023SJohn Marino statement:
4363*e4b17023SJohn Marino objc-throw-statement
4364*e4b17023SJohn Marino objc-try-catch-statement
4365*e4b17023SJohn Marino objc-synchronized-statement
4366*e4b17023SJohn Marino
4367*e4b17023SJohn Marino objc-throw-statement:
4368*e4b17023SJohn Marino @throw expression ;
4369*e4b17023SJohn Marino @throw ;
4370*e4b17023SJohn Marino
4371*e4b17023SJohn Marino OpenMP:
4372*e4b17023SJohn Marino
4373*e4b17023SJohn Marino statement:
4374*e4b17023SJohn Marino openmp-construct
4375*e4b17023SJohn Marino
4376*e4b17023SJohn Marino openmp-construct:
4377*e4b17023SJohn Marino parallel-construct
4378*e4b17023SJohn Marino for-construct
4379*e4b17023SJohn Marino sections-construct
4380*e4b17023SJohn Marino single-construct
4381*e4b17023SJohn Marino parallel-for-construct
4382*e4b17023SJohn Marino parallel-sections-construct
4383*e4b17023SJohn Marino master-construct
4384*e4b17023SJohn Marino critical-construct
4385*e4b17023SJohn Marino atomic-construct
4386*e4b17023SJohn Marino ordered-construct
4387*e4b17023SJohn Marino
4388*e4b17023SJohn Marino parallel-construct:
4389*e4b17023SJohn Marino parallel-directive structured-block
4390*e4b17023SJohn Marino
4391*e4b17023SJohn Marino for-construct:
4392*e4b17023SJohn Marino for-directive iteration-statement
4393*e4b17023SJohn Marino
4394*e4b17023SJohn Marino sections-construct:
4395*e4b17023SJohn Marino sections-directive section-scope
4396*e4b17023SJohn Marino
4397*e4b17023SJohn Marino single-construct:
4398*e4b17023SJohn Marino single-directive structured-block
4399*e4b17023SJohn Marino
4400*e4b17023SJohn Marino parallel-for-construct:
4401*e4b17023SJohn Marino parallel-for-directive iteration-statement
4402*e4b17023SJohn Marino
4403*e4b17023SJohn Marino parallel-sections-construct:
4404*e4b17023SJohn Marino parallel-sections-directive section-scope
4405*e4b17023SJohn Marino
4406*e4b17023SJohn Marino master-construct:
4407*e4b17023SJohn Marino master-directive structured-block
4408*e4b17023SJohn Marino
4409*e4b17023SJohn Marino critical-construct:
4410*e4b17023SJohn Marino critical-directive structured-block
4411*e4b17023SJohn Marino
4412*e4b17023SJohn Marino atomic-construct:
4413*e4b17023SJohn Marino atomic-directive expression-statement
4414*e4b17023SJohn Marino
4415*e4b17023SJohn Marino ordered-construct:
4416*e4b17023SJohn Marino ordered-directive structured-block
4417*e4b17023SJohn Marino
4418*e4b17023SJohn Marino Transactional Memory:
4419*e4b17023SJohn Marino
4420*e4b17023SJohn Marino statement:
4421*e4b17023SJohn Marino transaction-statement
4422*e4b17023SJohn Marino transaction-cancel-statement
4423*e4b17023SJohn Marino */
4424*e4b17023SJohn Marino
4425*e4b17023SJohn Marino static void
c_parser_statement(c_parser * parser)4426*e4b17023SJohn Marino c_parser_statement (c_parser *parser)
4427*e4b17023SJohn Marino {
4428*e4b17023SJohn Marino while (c_parser_next_token_is_keyword (parser, RID_CASE)
4429*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4430*e4b17023SJohn Marino || (c_parser_next_token_is (parser, CPP_NAME)
4431*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4432*e4b17023SJohn Marino c_parser_label (parser);
4433*e4b17023SJohn Marino c_parser_statement_after_labels (parser);
4434*e4b17023SJohn Marino }
4435*e4b17023SJohn Marino
4436*e4b17023SJohn Marino /* Parse a statement, other than a labeled statement. */
4437*e4b17023SJohn Marino
4438*e4b17023SJohn Marino static void
c_parser_statement_after_labels(c_parser * parser)4439*e4b17023SJohn Marino c_parser_statement_after_labels (c_parser *parser)
4440*e4b17023SJohn Marino {
4441*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
4442*e4b17023SJohn Marino tree stmt = NULL_TREE;
4443*e4b17023SJohn Marino bool in_if_block = parser->in_if_block;
4444*e4b17023SJohn Marino parser->in_if_block = false;
4445*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
4446*e4b17023SJohn Marino {
4447*e4b17023SJohn Marino case CPP_OPEN_BRACE:
4448*e4b17023SJohn Marino add_stmt (c_parser_compound_statement (parser));
4449*e4b17023SJohn Marino break;
4450*e4b17023SJohn Marino case CPP_KEYWORD:
4451*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->keyword)
4452*e4b17023SJohn Marino {
4453*e4b17023SJohn Marino case RID_IF:
4454*e4b17023SJohn Marino c_parser_if_statement (parser);
4455*e4b17023SJohn Marino break;
4456*e4b17023SJohn Marino case RID_SWITCH:
4457*e4b17023SJohn Marino c_parser_switch_statement (parser);
4458*e4b17023SJohn Marino break;
4459*e4b17023SJohn Marino case RID_WHILE:
4460*e4b17023SJohn Marino c_parser_while_statement (parser);
4461*e4b17023SJohn Marino break;
4462*e4b17023SJohn Marino case RID_DO:
4463*e4b17023SJohn Marino c_parser_do_statement (parser);
4464*e4b17023SJohn Marino break;
4465*e4b17023SJohn Marino case RID_FOR:
4466*e4b17023SJohn Marino c_parser_for_statement (parser);
4467*e4b17023SJohn Marino break;
4468*e4b17023SJohn Marino case RID_GOTO:
4469*e4b17023SJohn Marino c_parser_consume_token (parser);
4470*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
4471*e4b17023SJohn Marino {
4472*e4b17023SJohn Marino stmt = c_finish_goto_label (loc,
4473*e4b17023SJohn Marino c_parser_peek_token (parser)->value);
4474*e4b17023SJohn Marino c_parser_consume_token (parser);
4475*e4b17023SJohn Marino }
4476*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_MULT))
4477*e4b17023SJohn Marino {
4478*e4b17023SJohn Marino tree val;
4479*e4b17023SJohn Marino
4480*e4b17023SJohn Marino c_parser_consume_token (parser);
4481*e4b17023SJohn Marino val = c_parser_expression (parser).value;
4482*e4b17023SJohn Marino mark_exp_read (val);
4483*e4b17023SJohn Marino stmt = c_finish_goto_ptr (loc, val);
4484*e4b17023SJohn Marino }
4485*e4b17023SJohn Marino else
4486*e4b17023SJohn Marino c_parser_error (parser, "expected identifier or %<*%>");
4487*e4b17023SJohn Marino goto expect_semicolon;
4488*e4b17023SJohn Marino case RID_CONTINUE:
4489*e4b17023SJohn Marino c_parser_consume_token (parser);
4490*e4b17023SJohn Marino stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
4491*e4b17023SJohn Marino goto expect_semicolon;
4492*e4b17023SJohn Marino case RID_BREAK:
4493*e4b17023SJohn Marino c_parser_consume_token (parser);
4494*e4b17023SJohn Marino stmt = c_finish_bc_stmt (loc, &c_break_label, true);
4495*e4b17023SJohn Marino goto expect_semicolon;
4496*e4b17023SJohn Marino case RID_RETURN:
4497*e4b17023SJohn Marino c_parser_consume_token (parser);
4498*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4499*e4b17023SJohn Marino {
4500*e4b17023SJohn Marino stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
4501*e4b17023SJohn Marino c_parser_consume_token (parser);
4502*e4b17023SJohn Marino }
4503*e4b17023SJohn Marino else
4504*e4b17023SJohn Marino {
4505*e4b17023SJohn Marino struct c_expr expr = c_parser_expression_conv (parser);
4506*e4b17023SJohn Marino mark_exp_read (expr.value);
4507*e4b17023SJohn Marino stmt = c_finish_return (loc, expr.value, expr.original_type);
4508*e4b17023SJohn Marino goto expect_semicolon;
4509*e4b17023SJohn Marino }
4510*e4b17023SJohn Marino break;
4511*e4b17023SJohn Marino case RID_ASM:
4512*e4b17023SJohn Marino stmt = c_parser_asm_statement (parser);
4513*e4b17023SJohn Marino break;
4514*e4b17023SJohn Marino case RID_TRANSACTION_ATOMIC:
4515*e4b17023SJohn Marino case RID_TRANSACTION_RELAXED:
4516*e4b17023SJohn Marino stmt = c_parser_transaction (parser,
4517*e4b17023SJohn Marino c_parser_peek_token (parser)->keyword);
4518*e4b17023SJohn Marino break;
4519*e4b17023SJohn Marino case RID_TRANSACTION_CANCEL:
4520*e4b17023SJohn Marino stmt = c_parser_transaction_cancel (parser);
4521*e4b17023SJohn Marino goto expect_semicolon;
4522*e4b17023SJohn Marino case RID_AT_THROW:
4523*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
4524*e4b17023SJohn Marino c_parser_consume_token (parser);
4525*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4526*e4b17023SJohn Marino {
4527*e4b17023SJohn Marino stmt = objc_build_throw_stmt (loc, NULL_TREE);
4528*e4b17023SJohn Marino c_parser_consume_token (parser);
4529*e4b17023SJohn Marino }
4530*e4b17023SJohn Marino else
4531*e4b17023SJohn Marino {
4532*e4b17023SJohn Marino tree expr = c_parser_expression (parser).value;
4533*e4b17023SJohn Marino expr = c_fully_fold (expr, false, NULL);
4534*e4b17023SJohn Marino stmt = objc_build_throw_stmt (loc, expr);
4535*e4b17023SJohn Marino goto expect_semicolon;
4536*e4b17023SJohn Marino }
4537*e4b17023SJohn Marino break;
4538*e4b17023SJohn Marino case RID_AT_TRY:
4539*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
4540*e4b17023SJohn Marino c_parser_objc_try_catch_finally_statement (parser);
4541*e4b17023SJohn Marino break;
4542*e4b17023SJohn Marino case RID_AT_SYNCHRONIZED:
4543*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
4544*e4b17023SJohn Marino c_parser_objc_synchronized_statement (parser);
4545*e4b17023SJohn Marino break;
4546*e4b17023SJohn Marino default:
4547*e4b17023SJohn Marino goto expr_stmt;
4548*e4b17023SJohn Marino }
4549*e4b17023SJohn Marino break;
4550*e4b17023SJohn Marino case CPP_SEMICOLON:
4551*e4b17023SJohn Marino c_parser_consume_token (parser);
4552*e4b17023SJohn Marino break;
4553*e4b17023SJohn Marino case CPP_CLOSE_PAREN:
4554*e4b17023SJohn Marino case CPP_CLOSE_SQUARE:
4555*e4b17023SJohn Marino /* Avoid infinite loop in error recovery:
4556*e4b17023SJohn Marino c_parser_skip_until_found stops at a closing nesting
4557*e4b17023SJohn Marino delimiter without consuming it, but here we need to consume
4558*e4b17023SJohn Marino it to proceed further. */
4559*e4b17023SJohn Marino c_parser_error (parser, "expected statement");
4560*e4b17023SJohn Marino c_parser_consume_token (parser);
4561*e4b17023SJohn Marino break;
4562*e4b17023SJohn Marino case CPP_PRAGMA:
4563*e4b17023SJohn Marino c_parser_pragma (parser, pragma_stmt);
4564*e4b17023SJohn Marino break;
4565*e4b17023SJohn Marino default:
4566*e4b17023SJohn Marino expr_stmt:
4567*e4b17023SJohn Marino stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
4568*e4b17023SJohn Marino expect_semicolon:
4569*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4570*e4b17023SJohn Marino break;
4571*e4b17023SJohn Marino }
4572*e4b17023SJohn Marino /* Two cases cannot and do not have line numbers associated: If stmt
4573*e4b17023SJohn Marino is degenerate, such as "2;", then stmt is an INTEGER_CST, which
4574*e4b17023SJohn Marino cannot hold line numbers. But that's OK because the statement
4575*e4b17023SJohn Marino will either be changed to a MODIFY_EXPR during gimplification of
4576*e4b17023SJohn Marino the statement expr, or discarded. If stmt was compound, but
4577*e4b17023SJohn Marino without new variables, we will have skipped the creation of a
4578*e4b17023SJohn Marino BIND and will have a bare STATEMENT_LIST. But that's OK because
4579*e4b17023SJohn Marino (recursively) all of the component statements should already have
4580*e4b17023SJohn Marino line numbers assigned. ??? Can we discard no-op statements
4581*e4b17023SJohn Marino earlier? */
4582*e4b17023SJohn Marino if (CAN_HAVE_LOCATION_P (stmt)
4583*e4b17023SJohn Marino && EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
4584*e4b17023SJohn Marino SET_EXPR_LOCATION (stmt, loc);
4585*e4b17023SJohn Marino
4586*e4b17023SJohn Marino parser->in_if_block = in_if_block;
4587*e4b17023SJohn Marino }
4588*e4b17023SJohn Marino
4589*e4b17023SJohn Marino /* Parse the condition from an if, do, while or for statements. */
4590*e4b17023SJohn Marino
4591*e4b17023SJohn Marino static tree
c_parser_condition(c_parser * parser)4592*e4b17023SJohn Marino c_parser_condition (c_parser *parser)
4593*e4b17023SJohn Marino {
4594*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
4595*e4b17023SJohn Marino tree cond;
4596*e4b17023SJohn Marino cond = c_parser_expression_conv (parser).value;
4597*e4b17023SJohn Marino cond = c_objc_common_truthvalue_conversion (loc, cond);
4598*e4b17023SJohn Marino cond = c_fully_fold (cond, false, NULL);
4599*e4b17023SJohn Marino if (warn_sequence_point)
4600*e4b17023SJohn Marino verify_sequence_points (cond);
4601*e4b17023SJohn Marino return cond;
4602*e4b17023SJohn Marino }
4603*e4b17023SJohn Marino
4604*e4b17023SJohn Marino /* Parse a parenthesized condition from an if, do or while statement.
4605*e4b17023SJohn Marino
4606*e4b17023SJohn Marino condition:
4607*e4b17023SJohn Marino ( expression )
4608*e4b17023SJohn Marino */
4609*e4b17023SJohn Marino static tree
c_parser_paren_condition(c_parser * parser)4610*e4b17023SJohn Marino c_parser_paren_condition (c_parser *parser)
4611*e4b17023SJohn Marino {
4612*e4b17023SJohn Marino tree cond;
4613*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4614*e4b17023SJohn Marino return error_mark_node;
4615*e4b17023SJohn Marino cond = c_parser_condition (parser);
4616*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
4617*e4b17023SJohn Marino return cond;
4618*e4b17023SJohn Marino }
4619*e4b17023SJohn Marino
4620*e4b17023SJohn Marino /* Parse a statement which is a block in C99. */
4621*e4b17023SJohn Marino
4622*e4b17023SJohn Marino static tree
c_parser_c99_block_statement(c_parser * parser)4623*e4b17023SJohn Marino c_parser_c99_block_statement (c_parser *parser)
4624*e4b17023SJohn Marino {
4625*e4b17023SJohn Marino tree block = c_begin_compound_stmt (flag_isoc99);
4626*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
4627*e4b17023SJohn Marino c_parser_statement (parser);
4628*e4b17023SJohn Marino return c_end_compound_stmt (loc, block, flag_isoc99);
4629*e4b17023SJohn Marino }
4630*e4b17023SJohn Marino
4631*e4b17023SJohn Marino /* Parse the body of an if statement. This is just parsing a
4632*e4b17023SJohn Marino statement but (a) it is a block in C99, (b) we track whether the
4633*e4b17023SJohn Marino body is an if statement for the sake of -Wparentheses warnings, (c)
4634*e4b17023SJohn Marino we handle an empty body specially for the sake of -Wempty-body
4635*e4b17023SJohn Marino warnings, and (d) we call parser_compound_statement directly
4636*e4b17023SJohn Marino because c_parser_statement_after_labels resets
4637*e4b17023SJohn Marino parser->in_if_block. */
4638*e4b17023SJohn Marino
4639*e4b17023SJohn Marino static tree
c_parser_if_body(c_parser * parser,bool * if_p)4640*e4b17023SJohn Marino c_parser_if_body (c_parser *parser, bool *if_p)
4641*e4b17023SJohn Marino {
4642*e4b17023SJohn Marino tree block = c_begin_compound_stmt (flag_isoc99);
4643*e4b17023SJohn Marino location_t body_loc = c_parser_peek_token (parser)->location;
4644*e4b17023SJohn Marino while (c_parser_next_token_is_keyword (parser, RID_CASE)
4645*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4646*e4b17023SJohn Marino || (c_parser_next_token_is (parser, CPP_NAME)
4647*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4648*e4b17023SJohn Marino c_parser_label (parser);
4649*e4b17023SJohn Marino *if_p = c_parser_next_token_is_keyword (parser, RID_IF);
4650*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4651*e4b17023SJohn Marino {
4652*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
4653*e4b17023SJohn Marino add_stmt (build_empty_stmt (loc));
4654*e4b17023SJohn Marino c_parser_consume_token (parser);
4655*e4b17023SJohn Marino if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
4656*e4b17023SJohn Marino warning_at (loc, OPT_Wempty_body,
4657*e4b17023SJohn Marino "suggest braces around empty body in an %<if%> statement");
4658*e4b17023SJohn Marino }
4659*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
4660*e4b17023SJohn Marino add_stmt (c_parser_compound_statement (parser));
4661*e4b17023SJohn Marino else
4662*e4b17023SJohn Marino c_parser_statement_after_labels (parser);
4663*e4b17023SJohn Marino return c_end_compound_stmt (body_loc, block, flag_isoc99);
4664*e4b17023SJohn Marino }
4665*e4b17023SJohn Marino
4666*e4b17023SJohn Marino /* Parse the else body of an if statement. This is just parsing a
4667*e4b17023SJohn Marino statement but (a) it is a block in C99, (b) we handle an empty body
4668*e4b17023SJohn Marino specially for the sake of -Wempty-body warnings. */
4669*e4b17023SJohn Marino
4670*e4b17023SJohn Marino static tree
c_parser_else_body(c_parser * parser)4671*e4b17023SJohn Marino c_parser_else_body (c_parser *parser)
4672*e4b17023SJohn Marino {
4673*e4b17023SJohn Marino location_t else_loc = c_parser_peek_token (parser)->location;
4674*e4b17023SJohn Marino tree block = c_begin_compound_stmt (flag_isoc99);
4675*e4b17023SJohn Marino while (c_parser_next_token_is_keyword (parser, RID_CASE)
4676*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
4677*e4b17023SJohn Marino || (c_parser_next_token_is (parser, CPP_NAME)
4678*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
4679*e4b17023SJohn Marino c_parser_label (parser);
4680*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4681*e4b17023SJohn Marino {
4682*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
4683*e4b17023SJohn Marino warning_at (loc,
4684*e4b17023SJohn Marino OPT_Wempty_body,
4685*e4b17023SJohn Marino "suggest braces around empty body in an %<else%> statement");
4686*e4b17023SJohn Marino add_stmt (build_empty_stmt (loc));
4687*e4b17023SJohn Marino c_parser_consume_token (parser);
4688*e4b17023SJohn Marino }
4689*e4b17023SJohn Marino else
4690*e4b17023SJohn Marino c_parser_statement_after_labels (parser);
4691*e4b17023SJohn Marino return c_end_compound_stmt (else_loc, block, flag_isoc99);
4692*e4b17023SJohn Marino }
4693*e4b17023SJohn Marino
4694*e4b17023SJohn Marino /* Parse an if statement (C90 6.6.4, C99 6.8.4).
4695*e4b17023SJohn Marino
4696*e4b17023SJohn Marino if-statement:
4697*e4b17023SJohn Marino if ( expression ) statement
4698*e4b17023SJohn Marino if ( expression ) statement else statement
4699*e4b17023SJohn Marino */
4700*e4b17023SJohn Marino
4701*e4b17023SJohn Marino static void
c_parser_if_statement(c_parser * parser)4702*e4b17023SJohn Marino c_parser_if_statement (c_parser *parser)
4703*e4b17023SJohn Marino {
4704*e4b17023SJohn Marino tree block;
4705*e4b17023SJohn Marino location_t loc;
4706*e4b17023SJohn Marino tree cond;
4707*e4b17023SJohn Marino bool first_if = false;
4708*e4b17023SJohn Marino tree first_body, second_body;
4709*e4b17023SJohn Marino bool in_if_block;
4710*e4b17023SJohn Marino
4711*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
4712*e4b17023SJohn Marino c_parser_consume_token (parser);
4713*e4b17023SJohn Marino block = c_begin_compound_stmt (flag_isoc99);
4714*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
4715*e4b17023SJohn Marino cond = c_parser_paren_condition (parser);
4716*e4b17023SJohn Marino in_if_block = parser->in_if_block;
4717*e4b17023SJohn Marino parser->in_if_block = true;
4718*e4b17023SJohn Marino first_body = c_parser_if_body (parser, &first_if);
4719*e4b17023SJohn Marino parser->in_if_block = in_if_block;
4720*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ELSE))
4721*e4b17023SJohn Marino {
4722*e4b17023SJohn Marino c_parser_consume_token (parser);
4723*e4b17023SJohn Marino second_body = c_parser_else_body (parser);
4724*e4b17023SJohn Marino }
4725*e4b17023SJohn Marino else
4726*e4b17023SJohn Marino second_body = NULL_TREE;
4727*e4b17023SJohn Marino c_finish_if_stmt (loc, cond, first_body, second_body, first_if);
4728*e4b17023SJohn Marino add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
4729*e4b17023SJohn Marino }
4730*e4b17023SJohn Marino
4731*e4b17023SJohn Marino /* Parse a switch statement (C90 6.6.4, C99 6.8.4).
4732*e4b17023SJohn Marino
4733*e4b17023SJohn Marino switch-statement:
4734*e4b17023SJohn Marino switch (expression) statement
4735*e4b17023SJohn Marino */
4736*e4b17023SJohn Marino
4737*e4b17023SJohn Marino static void
c_parser_switch_statement(c_parser * parser)4738*e4b17023SJohn Marino c_parser_switch_statement (c_parser *parser)
4739*e4b17023SJohn Marino {
4740*e4b17023SJohn Marino tree block, expr, body, save_break;
4741*e4b17023SJohn Marino location_t switch_loc = c_parser_peek_token (parser)->location;
4742*e4b17023SJohn Marino location_t switch_cond_loc;
4743*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
4744*e4b17023SJohn Marino c_parser_consume_token (parser);
4745*e4b17023SJohn Marino block = c_begin_compound_stmt (flag_isoc99);
4746*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4747*e4b17023SJohn Marino {
4748*e4b17023SJohn Marino switch_cond_loc = c_parser_peek_token (parser)->location;
4749*e4b17023SJohn Marino expr = c_parser_expression (parser).value;
4750*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
4751*e4b17023SJohn Marino }
4752*e4b17023SJohn Marino else
4753*e4b17023SJohn Marino {
4754*e4b17023SJohn Marino switch_cond_loc = UNKNOWN_LOCATION;
4755*e4b17023SJohn Marino expr = error_mark_node;
4756*e4b17023SJohn Marino }
4757*e4b17023SJohn Marino c_start_case (switch_loc, switch_cond_loc, expr);
4758*e4b17023SJohn Marino save_break = c_break_label;
4759*e4b17023SJohn Marino c_break_label = NULL_TREE;
4760*e4b17023SJohn Marino body = c_parser_c99_block_statement (parser);
4761*e4b17023SJohn Marino c_finish_case (body);
4762*e4b17023SJohn Marino if (c_break_label)
4763*e4b17023SJohn Marino {
4764*e4b17023SJohn Marino location_t here = c_parser_peek_token (parser)->location;
4765*e4b17023SJohn Marino tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
4766*e4b17023SJohn Marino SET_EXPR_LOCATION (t, here);
4767*e4b17023SJohn Marino add_stmt (t);
4768*e4b17023SJohn Marino }
4769*e4b17023SJohn Marino c_break_label = save_break;
4770*e4b17023SJohn Marino add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
4771*e4b17023SJohn Marino }
4772*e4b17023SJohn Marino
4773*e4b17023SJohn Marino /* Parse a while statement (C90 6.6.5, C99 6.8.5).
4774*e4b17023SJohn Marino
4775*e4b17023SJohn Marino while-statement:
4776*e4b17023SJohn Marino while (expression) statement
4777*e4b17023SJohn Marino */
4778*e4b17023SJohn Marino
4779*e4b17023SJohn Marino static void
c_parser_while_statement(c_parser * parser)4780*e4b17023SJohn Marino c_parser_while_statement (c_parser *parser)
4781*e4b17023SJohn Marino {
4782*e4b17023SJohn Marino tree block, cond, body, save_break, save_cont;
4783*e4b17023SJohn Marino location_t loc;
4784*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
4785*e4b17023SJohn Marino c_parser_consume_token (parser);
4786*e4b17023SJohn Marino block = c_begin_compound_stmt (flag_isoc99);
4787*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
4788*e4b17023SJohn Marino cond = c_parser_paren_condition (parser);
4789*e4b17023SJohn Marino save_break = c_break_label;
4790*e4b17023SJohn Marino c_break_label = NULL_TREE;
4791*e4b17023SJohn Marino save_cont = c_cont_label;
4792*e4b17023SJohn Marino c_cont_label = NULL_TREE;
4793*e4b17023SJohn Marino body = c_parser_c99_block_statement (parser);
4794*e4b17023SJohn Marino c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
4795*e4b17023SJohn Marino add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
4796*e4b17023SJohn Marino c_break_label = save_break;
4797*e4b17023SJohn Marino c_cont_label = save_cont;
4798*e4b17023SJohn Marino }
4799*e4b17023SJohn Marino
4800*e4b17023SJohn Marino /* Parse a do statement (C90 6.6.5, C99 6.8.5).
4801*e4b17023SJohn Marino
4802*e4b17023SJohn Marino do-statement:
4803*e4b17023SJohn Marino do statement while ( expression ) ;
4804*e4b17023SJohn Marino */
4805*e4b17023SJohn Marino
4806*e4b17023SJohn Marino static void
c_parser_do_statement(c_parser * parser)4807*e4b17023SJohn Marino c_parser_do_statement (c_parser *parser)
4808*e4b17023SJohn Marino {
4809*e4b17023SJohn Marino tree block, cond, body, save_break, save_cont, new_break, new_cont;
4810*e4b17023SJohn Marino location_t loc;
4811*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
4812*e4b17023SJohn Marino c_parser_consume_token (parser);
4813*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4814*e4b17023SJohn Marino warning_at (c_parser_peek_token (parser)->location,
4815*e4b17023SJohn Marino OPT_Wempty_body,
4816*e4b17023SJohn Marino "suggest braces around empty body in %<do%> statement");
4817*e4b17023SJohn Marino block = c_begin_compound_stmt (flag_isoc99);
4818*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
4819*e4b17023SJohn Marino save_break = c_break_label;
4820*e4b17023SJohn Marino c_break_label = NULL_TREE;
4821*e4b17023SJohn Marino save_cont = c_cont_label;
4822*e4b17023SJohn Marino c_cont_label = NULL_TREE;
4823*e4b17023SJohn Marino body = c_parser_c99_block_statement (parser);
4824*e4b17023SJohn Marino c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
4825*e4b17023SJohn Marino new_break = c_break_label;
4826*e4b17023SJohn Marino c_break_label = save_break;
4827*e4b17023SJohn Marino new_cont = c_cont_label;
4828*e4b17023SJohn Marino c_cont_label = save_cont;
4829*e4b17023SJohn Marino cond = c_parser_paren_condition (parser);
4830*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
4831*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
4832*e4b17023SJohn Marino c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
4833*e4b17023SJohn Marino add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
4834*e4b17023SJohn Marino }
4835*e4b17023SJohn Marino
4836*e4b17023SJohn Marino /* Parse a for statement (C90 6.6.5, C99 6.8.5).
4837*e4b17023SJohn Marino
4838*e4b17023SJohn Marino for-statement:
4839*e4b17023SJohn Marino for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
4840*e4b17023SJohn Marino for ( nested-declaration expression[opt] ; expression[opt] ) statement
4841*e4b17023SJohn Marino
4842*e4b17023SJohn Marino The form with a declaration is new in C99.
4843*e4b17023SJohn Marino
4844*e4b17023SJohn Marino ??? In accordance with the old parser, the declaration may be a
4845*e4b17023SJohn Marino nested function, which is then rejected in check_for_loop_decls,
4846*e4b17023SJohn Marino but does it make any sense for this to be included in the grammar?
4847*e4b17023SJohn Marino Note in particular that the nested function does not include a
4848*e4b17023SJohn Marino trailing ';', whereas the "declaration" production includes one.
4849*e4b17023SJohn Marino Also, can we reject bad declarations earlier and cheaper than
4850*e4b17023SJohn Marino check_for_loop_decls?
4851*e4b17023SJohn Marino
4852*e4b17023SJohn Marino In Objective-C, there are two additional variants:
4853*e4b17023SJohn Marino
4854*e4b17023SJohn Marino foreach-statement:
4855*e4b17023SJohn Marino for ( expression in expresssion ) statement
4856*e4b17023SJohn Marino for ( declaration in expression ) statement
4857*e4b17023SJohn Marino
4858*e4b17023SJohn Marino This is inconsistent with C, because the second variant is allowed
4859*e4b17023SJohn Marino even if c99 is not enabled.
4860*e4b17023SJohn Marino
4861*e4b17023SJohn Marino The rest of the comment documents these Objective-C foreach-statement.
4862*e4b17023SJohn Marino
4863*e4b17023SJohn Marino Here is the canonical example of the first variant:
4864*e4b17023SJohn Marino for (object in array) { do something with object }
4865*e4b17023SJohn Marino we call the first expression ("object") the "object_expression" and
4866*e4b17023SJohn Marino the second expression ("array") the "collection_expression".
4867*e4b17023SJohn Marino object_expression must be an lvalue of type "id" (a generic Objective-C
4868*e4b17023SJohn Marino object) because the loop works by assigning to object_expression the
4869*e4b17023SJohn Marino various objects from the collection_expression. collection_expression
4870*e4b17023SJohn Marino must evaluate to something of type "id" which responds to the method
4871*e4b17023SJohn Marino countByEnumeratingWithState:objects:count:.
4872*e4b17023SJohn Marino
4873*e4b17023SJohn Marino The canonical example of the second variant is:
4874*e4b17023SJohn Marino for (id object in array) { do something with object }
4875*e4b17023SJohn Marino which is completely equivalent to
4876*e4b17023SJohn Marino {
4877*e4b17023SJohn Marino id object;
4878*e4b17023SJohn Marino for (object in array) { do something with object }
4879*e4b17023SJohn Marino }
4880*e4b17023SJohn Marino Note that initizializing 'object' in some way (eg, "for ((object =
4881*e4b17023SJohn Marino xxx) in array) { do something with object }") is possibly
4882*e4b17023SJohn Marino technically valid, but completely pointless as 'object' will be
4883*e4b17023SJohn Marino assigned to something else as soon as the loop starts. We should
4884*e4b17023SJohn Marino most likely reject it (TODO).
4885*e4b17023SJohn Marino
4886*e4b17023SJohn Marino The beginning of the Objective-C foreach-statement looks exactly
4887*e4b17023SJohn Marino like the beginning of the for-statement, and we can tell it is a
4888*e4b17023SJohn Marino foreach-statement only because the initial declaration or
4889*e4b17023SJohn Marino expression is terminated by 'in' instead of ';'.
4890*e4b17023SJohn Marino */
4891*e4b17023SJohn Marino
4892*e4b17023SJohn Marino static void
c_parser_for_statement(c_parser * parser)4893*e4b17023SJohn Marino c_parser_for_statement (c_parser *parser)
4894*e4b17023SJohn Marino {
4895*e4b17023SJohn Marino tree block, cond, incr, save_break, save_cont, body;
4896*e4b17023SJohn Marino /* The following are only used when parsing an ObjC foreach statement. */
4897*e4b17023SJohn Marino tree object_expression;
4898*e4b17023SJohn Marino /* Silence the bogus uninitialized warning. */
4899*e4b17023SJohn Marino tree collection_expression = NULL;
4900*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
4901*e4b17023SJohn Marino location_t for_loc = c_parser_peek_token (parser)->location;
4902*e4b17023SJohn Marino bool is_foreach_statement = false;
4903*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
4904*e4b17023SJohn Marino c_parser_consume_token (parser);
4905*e4b17023SJohn Marino /* Open a compound statement in Objective-C as well, just in case this is
4906*e4b17023SJohn Marino as foreach expression. */
4907*e4b17023SJohn Marino block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
4908*e4b17023SJohn Marino cond = error_mark_node;
4909*e4b17023SJohn Marino incr = error_mark_node;
4910*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4911*e4b17023SJohn Marino {
4912*e4b17023SJohn Marino /* Parse the initialization declaration or expression. */
4913*e4b17023SJohn Marino object_expression = error_mark_node;
4914*e4b17023SJohn Marino parser->objc_could_be_foreach_context = c_dialect_objc ();
4915*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4916*e4b17023SJohn Marino {
4917*e4b17023SJohn Marino parser->objc_could_be_foreach_context = false;
4918*e4b17023SJohn Marino c_parser_consume_token (parser);
4919*e4b17023SJohn Marino c_finish_expr_stmt (loc, NULL_TREE);
4920*e4b17023SJohn Marino }
4921*e4b17023SJohn Marino else if (c_parser_next_tokens_start_declaration (parser))
4922*e4b17023SJohn Marino {
4923*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, true, true, true, true, true,
4924*e4b17023SJohn Marino &object_expression);
4925*e4b17023SJohn Marino parser->objc_could_be_foreach_context = false;
4926*e4b17023SJohn Marino
4927*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_IN))
4928*e4b17023SJohn Marino {
4929*e4b17023SJohn Marino c_parser_consume_token (parser);
4930*e4b17023SJohn Marino is_foreach_statement = true;
4931*e4b17023SJohn Marino if (check_for_loop_decls (for_loc, true) == NULL_TREE)
4932*e4b17023SJohn Marino c_parser_error (parser, "multiple iterating variables in fast enumeration");
4933*e4b17023SJohn Marino }
4934*e4b17023SJohn Marino else
4935*e4b17023SJohn Marino check_for_loop_decls (for_loc, flag_isoc99);
4936*e4b17023SJohn Marino }
4937*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
4938*e4b17023SJohn Marino {
4939*e4b17023SJohn Marino /* __extension__ can start a declaration, but is also an
4940*e4b17023SJohn Marino unary operator that can start an expression. Consume all
4941*e4b17023SJohn Marino but the last of a possible series of __extension__ to
4942*e4b17023SJohn Marino determine which. */
4943*e4b17023SJohn Marino while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
4944*e4b17023SJohn Marino && (c_parser_peek_2nd_token (parser)->keyword
4945*e4b17023SJohn Marino == RID_EXTENSION))
4946*e4b17023SJohn Marino c_parser_consume_token (parser);
4947*e4b17023SJohn Marino if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
4948*e4b17023SJohn Marino {
4949*e4b17023SJohn Marino int ext;
4950*e4b17023SJohn Marino ext = disable_extension_diagnostics ();
4951*e4b17023SJohn Marino c_parser_consume_token (parser);
4952*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, true, true, true, true,
4953*e4b17023SJohn Marino true, &object_expression);
4954*e4b17023SJohn Marino parser->objc_could_be_foreach_context = false;
4955*e4b17023SJohn Marino
4956*e4b17023SJohn Marino restore_extension_diagnostics (ext);
4957*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_IN))
4958*e4b17023SJohn Marino {
4959*e4b17023SJohn Marino c_parser_consume_token (parser);
4960*e4b17023SJohn Marino is_foreach_statement = true;
4961*e4b17023SJohn Marino if (check_for_loop_decls (for_loc, true) == NULL_TREE)
4962*e4b17023SJohn Marino c_parser_error (parser, "multiple iterating variables in fast enumeration");
4963*e4b17023SJohn Marino }
4964*e4b17023SJohn Marino else
4965*e4b17023SJohn Marino check_for_loop_decls (for_loc, flag_isoc99);
4966*e4b17023SJohn Marino }
4967*e4b17023SJohn Marino else
4968*e4b17023SJohn Marino goto init_expr;
4969*e4b17023SJohn Marino }
4970*e4b17023SJohn Marino else
4971*e4b17023SJohn Marino {
4972*e4b17023SJohn Marino init_expr:
4973*e4b17023SJohn Marino {
4974*e4b17023SJohn Marino tree init_expression;
4975*e4b17023SJohn Marino init_expression = c_parser_expression (parser).value;
4976*e4b17023SJohn Marino parser->objc_could_be_foreach_context = false;
4977*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_IN))
4978*e4b17023SJohn Marino {
4979*e4b17023SJohn Marino c_parser_consume_token (parser);
4980*e4b17023SJohn Marino is_foreach_statement = true;
4981*e4b17023SJohn Marino if (! lvalue_p (init_expression))
4982*e4b17023SJohn Marino c_parser_error (parser, "invalid iterating variable in fast enumeration");
4983*e4b17023SJohn Marino object_expression = c_fully_fold (init_expression, false, NULL);
4984*e4b17023SJohn Marino }
4985*e4b17023SJohn Marino else
4986*e4b17023SJohn Marino {
4987*e4b17023SJohn Marino c_finish_expr_stmt (loc, init_expression);
4988*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
4989*e4b17023SJohn Marino }
4990*e4b17023SJohn Marino }
4991*e4b17023SJohn Marino }
4992*e4b17023SJohn Marino /* Parse the loop condition. In the case of a foreach
4993*e4b17023SJohn Marino statement, there is no loop condition. */
4994*e4b17023SJohn Marino gcc_assert (!parser->objc_could_be_foreach_context);
4995*e4b17023SJohn Marino if (!is_foreach_statement)
4996*e4b17023SJohn Marino {
4997*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4998*e4b17023SJohn Marino {
4999*e4b17023SJohn Marino c_parser_consume_token (parser);
5000*e4b17023SJohn Marino cond = NULL_TREE;
5001*e4b17023SJohn Marino }
5002*e4b17023SJohn Marino else
5003*e4b17023SJohn Marino {
5004*e4b17023SJohn Marino cond = c_parser_condition (parser);
5005*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5006*e4b17023SJohn Marino }
5007*e4b17023SJohn Marino }
5008*e4b17023SJohn Marino /* Parse the increment expression (the third expression in a
5009*e4b17023SJohn Marino for-statement). In the case of a foreach-statement, this is
5010*e4b17023SJohn Marino the expression that follows the 'in'. */
5011*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5012*e4b17023SJohn Marino {
5013*e4b17023SJohn Marino if (is_foreach_statement)
5014*e4b17023SJohn Marino {
5015*e4b17023SJohn Marino c_parser_error (parser, "missing collection in fast enumeration");
5016*e4b17023SJohn Marino collection_expression = error_mark_node;
5017*e4b17023SJohn Marino }
5018*e4b17023SJohn Marino else
5019*e4b17023SJohn Marino incr = c_process_expr_stmt (loc, NULL_TREE);
5020*e4b17023SJohn Marino }
5021*e4b17023SJohn Marino else
5022*e4b17023SJohn Marino {
5023*e4b17023SJohn Marino if (is_foreach_statement)
5024*e4b17023SJohn Marino collection_expression = c_fully_fold (c_parser_expression (parser).value,
5025*e4b17023SJohn Marino false, NULL);
5026*e4b17023SJohn Marino else
5027*e4b17023SJohn Marino incr = c_process_expr_stmt (loc, c_parser_expression (parser).value);
5028*e4b17023SJohn Marino }
5029*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5030*e4b17023SJohn Marino }
5031*e4b17023SJohn Marino save_break = c_break_label;
5032*e4b17023SJohn Marino c_break_label = NULL_TREE;
5033*e4b17023SJohn Marino save_cont = c_cont_label;
5034*e4b17023SJohn Marino c_cont_label = NULL_TREE;
5035*e4b17023SJohn Marino body = c_parser_c99_block_statement (parser);
5036*e4b17023SJohn Marino if (is_foreach_statement)
5037*e4b17023SJohn Marino objc_finish_foreach_loop (loc, object_expression, collection_expression, body, c_break_label, c_cont_label);
5038*e4b17023SJohn Marino else
5039*e4b17023SJohn Marino c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true);
5040*e4b17023SJohn Marino add_stmt (c_end_compound_stmt (loc, block, flag_isoc99 || c_dialect_objc ()));
5041*e4b17023SJohn Marino c_break_label = save_break;
5042*e4b17023SJohn Marino c_cont_label = save_cont;
5043*e4b17023SJohn Marino }
5044*e4b17023SJohn Marino
5045*e4b17023SJohn Marino /* Parse an asm statement, a GNU extension. This is a full-blown asm
5046*e4b17023SJohn Marino statement with inputs, outputs, clobbers, and volatile tag
5047*e4b17023SJohn Marino allowed.
5048*e4b17023SJohn Marino
5049*e4b17023SJohn Marino asm-statement:
5050*e4b17023SJohn Marino asm type-qualifier[opt] ( asm-argument ) ;
5051*e4b17023SJohn Marino asm type-qualifier[opt] goto ( asm-goto-argument ) ;
5052*e4b17023SJohn Marino
5053*e4b17023SJohn Marino asm-argument:
5054*e4b17023SJohn Marino asm-string-literal
5055*e4b17023SJohn Marino asm-string-literal : asm-operands[opt]
5056*e4b17023SJohn Marino asm-string-literal : asm-operands[opt] : asm-operands[opt]
5057*e4b17023SJohn Marino asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt]
5058*e4b17023SJohn Marino
5059*e4b17023SJohn Marino asm-goto-argument:
5060*e4b17023SJohn Marino asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
5061*e4b17023SJohn Marino : asm-goto-operands
5062*e4b17023SJohn Marino
5063*e4b17023SJohn Marino Qualifiers other than volatile are accepted in the syntax but
5064*e4b17023SJohn Marino warned for. */
5065*e4b17023SJohn Marino
5066*e4b17023SJohn Marino static tree
c_parser_asm_statement(c_parser * parser)5067*e4b17023SJohn Marino c_parser_asm_statement (c_parser *parser)
5068*e4b17023SJohn Marino {
5069*e4b17023SJohn Marino tree quals, str, outputs, inputs, clobbers, labels, ret;
5070*e4b17023SJohn Marino bool simple, is_goto;
5071*e4b17023SJohn Marino location_t asm_loc = c_parser_peek_token (parser)->location;
5072*e4b17023SJohn Marino int section, nsections;
5073*e4b17023SJohn Marino
5074*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
5075*e4b17023SJohn Marino c_parser_consume_token (parser);
5076*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
5077*e4b17023SJohn Marino {
5078*e4b17023SJohn Marino quals = c_parser_peek_token (parser)->value;
5079*e4b17023SJohn Marino c_parser_consume_token (parser);
5080*e4b17023SJohn Marino }
5081*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_CONST)
5082*e4b17023SJohn Marino || c_parser_next_token_is_keyword (parser, RID_RESTRICT))
5083*e4b17023SJohn Marino {
5084*e4b17023SJohn Marino warning_at (c_parser_peek_token (parser)->location,
5085*e4b17023SJohn Marino 0,
5086*e4b17023SJohn Marino "%E qualifier ignored on asm",
5087*e4b17023SJohn Marino c_parser_peek_token (parser)->value);
5088*e4b17023SJohn Marino quals = NULL_TREE;
5089*e4b17023SJohn Marino c_parser_consume_token (parser);
5090*e4b17023SJohn Marino }
5091*e4b17023SJohn Marino else
5092*e4b17023SJohn Marino quals = NULL_TREE;
5093*e4b17023SJohn Marino
5094*e4b17023SJohn Marino is_goto = false;
5095*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_GOTO))
5096*e4b17023SJohn Marino {
5097*e4b17023SJohn Marino c_parser_consume_token (parser);
5098*e4b17023SJohn Marino is_goto = true;
5099*e4b17023SJohn Marino }
5100*e4b17023SJohn Marino
5101*e4b17023SJohn Marino /* ??? Follow the C++ parser rather than using the
5102*e4b17023SJohn Marino lex_untranslated_string kludge. */
5103*e4b17023SJohn Marino parser->lex_untranslated_string = true;
5104*e4b17023SJohn Marino ret = NULL;
5105*e4b17023SJohn Marino
5106*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5107*e4b17023SJohn Marino goto error;
5108*e4b17023SJohn Marino
5109*e4b17023SJohn Marino str = c_parser_asm_string_literal (parser);
5110*e4b17023SJohn Marino if (str == NULL_TREE)
5111*e4b17023SJohn Marino goto error_close_paren;
5112*e4b17023SJohn Marino
5113*e4b17023SJohn Marino simple = true;
5114*e4b17023SJohn Marino outputs = NULL_TREE;
5115*e4b17023SJohn Marino inputs = NULL_TREE;
5116*e4b17023SJohn Marino clobbers = NULL_TREE;
5117*e4b17023SJohn Marino labels = NULL_TREE;
5118*e4b17023SJohn Marino
5119*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
5120*e4b17023SJohn Marino goto done_asm;
5121*e4b17023SJohn Marino
5122*e4b17023SJohn Marino /* Parse each colon-delimited section of operands. */
5123*e4b17023SJohn Marino nsections = 3 + is_goto;
5124*e4b17023SJohn Marino for (section = 0; section < nsections; ++section)
5125*e4b17023SJohn Marino {
5126*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COLON,
5127*e4b17023SJohn Marino is_goto
5128*e4b17023SJohn Marino ? "expected %<:%>"
5129*e4b17023SJohn Marino : "expected %<:%> or %<)%>"))
5130*e4b17023SJohn Marino goto error_close_paren;
5131*e4b17023SJohn Marino
5132*e4b17023SJohn Marino /* Once past any colon, we're no longer a simple asm. */
5133*e4b17023SJohn Marino simple = false;
5134*e4b17023SJohn Marino
5135*e4b17023SJohn Marino if ((!c_parser_next_token_is (parser, CPP_COLON)
5136*e4b17023SJohn Marino && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
5137*e4b17023SJohn Marino || section == 3)
5138*e4b17023SJohn Marino switch (section)
5139*e4b17023SJohn Marino {
5140*e4b17023SJohn Marino case 0:
5141*e4b17023SJohn Marino /* For asm goto, we don't allow output operands, but reserve
5142*e4b17023SJohn Marino the slot for a future extension that does allow them. */
5143*e4b17023SJohn Marino if (!is_goto)
5144*e4b17023SJohn Marino outputs = c_parser_asm_operands (parser, false);
5145*e4b17023SJohn Marino break;
5146*e4b17023SJohn Marino case 1:
5147*e4b17023SJohn Marino inputs = c_parser_asm_operands (parser, true);
5148*e4b17023SJohn Marino break;
5149*e4b17023SJohn Marino case 2:
5150*e4b17023SJohn Marino clobbers = c_parser_asm_clobbers (parser);
5151*e4b17023SJohn Marino break;
5152*e4b17023SJohn Marino case 3:
5153*e4b17023SJohn Marino labels = c_parser_asm_goto_operands (parser);
5154*e4b17023SJohn Marino break;
5155*e4b17023SJohn Marino default:
5156*e4b17023SJohn Marino gcc_unreachable ();
5157*e4b17023SJohn Marino }
5158*e4b17023SJohn Marino
5159*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
5160*e4b17023SJohn Marino goto done_asm;
5161*e4b17023SJohn Marino }
5162*e4b17023SJohn Marino
5163*e4b17023SJohn Marino done_asm:
5164*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
5165*e4b17023SJohn Marino {
5166*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5167*e4b17023SJohn Marino goto error;
5168*e4b17023SJohn Marino }
5169*e4b17023SJohn Marino
5170*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
5171*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
5172*e4b17023SJohn Marino
5173*e4b17023SJohn Marino ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
5174*e4b17023SJohn Marino clobbers, labels, simple));
5175*e4b17023SJohn Marino
5176*e4b17023SJohn Marino error:
5177*e4b17023SJohn Marino parser->lex_untranslated_string = false;
5178*e4b17023SJohn Marino return ret;
5179*e4b17023SJohn Marino
5180*e4b17023SJohn Marino error_close_paren:
5181*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5182*e4b17023SJohn Marino goto error;
5183*e4b17023SJohn Marino }
5184*e4b17023SJohn Marino
5185*e4b17023SJohn Marino /* Parse asm operands, a GNU extension. If CONVERT_P (for inputs but
5186*e4b17023SJohn Marino not outputs), apply the default conversion of functions and arrays
5187*e4b17023SJohn Marino to pointers.
5188*e4b17023SJohn Marino
5189*e4b17023SJohn Marino asm-operands:
5190*e4b17023SJohn Marino asm-operand
5191*e4b17023SJohn Marino asm-operands , asm-operand
5192*e4b17023SJohn Marino
5193*e4b17023SJohn Marino asm-operand:
5194*e4b17023SJohn Marino asm-string-literal ( expression )
5195*e4b17023SJohn Marino [ identifier ] asm-string-literal ( expression )
5196*e4b17023SJohn Marino */
5197*e4b17023SJohn Marino
5198*e4b17023SJohn Marino static tree
c_parser_asm_operands(c_parser * parser,bool convert_p)5199*e4b17023SJohn Marino c_parser_asm_operands (c_parser *parser, bool convert_p)
5200*e4b17023SJohn Marino {
5201*e4b17023SJohn Marino tree list = NULL_TREE;
5202*e4b17023SJohn Marino location_t loc;
5203*e4b17023SJohn Marino while (true)
5204*e4b17023SJohn Marino {
5205*e4b17023SJohn Marino tree name, str;
5206*e4b17023SJohn Marino struct c_expr expr;
5207*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
5208*e4b17023SJohn Marino {
5209*e4b17023SJohn Marino c_parser_consume_token (parser);
5210*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
5211*e4b17023SJohn Marino {
5212*e4b17023SJohn Marino tree id = c_parser_peek_token (parser)->value;
5213*e4b17023SJohn Marino c_parser_consume_token (parser);
5214*e4b17023SJohn Marino name = build_string (IDENTIFIER_LENGTH (id),
5215*e4b17023SJohn Marino IDENTIFIER_POINTER (id));
5216*e4b17023SJohn Marino }
5217*e4b17023SJohn Marino else
5218*e4b17023SJohn Marino {
5219*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
5220*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
5221*e4b17023SJohn Marino return NULL_TREE;
5222*e4b17023SJohn Marino }
5223*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5224*e4b17023SJohn Marino "expected %<]%>");
5225*e4b17023SJohn Marino }
5226*e4b17023SJohn Marino else
5227*e4b17023SJohn Marino name = NULL_TREE;
5228*e4b17023SJohn Marino str = c_parser_asm_string_literal (parser);
5229*e4b17023SJohn Marino if (str == NULL_TREE)
5230*e4b17023SJohn Marino return NULL_TREE;
5231*e4b17023SJohn Marino parser->lex_untranslated_string = false;
5232*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
5233*e4b17023SJohn Marino {
5234*e4b17023SJohn Marino parser->lex_untranslated_string = true;
5235*e4b17023SJohn Marino return NULL_TREE;
5236*e4b17023SJohn Marino }
5237*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
5238*e4b17023SJohn Marino expr = c_parser_expression (parser);
5239*e4b17023SJohn Marino mark_exp_read (expr.value);
5240*e4b17023SJohn Marino if (convert_p)
5241*e4b17023SJohn Marino expr = default_function_array_conversion (loc, expr);
5242*e4b17023SJohn Marino expr.value = c_fully_fold (expr.value, false, NULL);
5243*e4b17023SJohn Marino parser->lex_untranslated_string = true;
5244*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
5245*e4b17023SJohn Marino {
5246*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
5247*e4b17023SJohn Marino return NULL_TREE;
5248*e4b17023SJohn Marino }
5249*e4b17023SJohn Marino list = chainon (list, build_tree_list (build_tree_list (name, str),
5250*e4b17023SJohn Marino expr.value));
5251*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
5252*e4b17023SJohn Marino c_parser_consume_token (parser);
5253*e4b17023SJohn Marino else
5254*e4b17023SJohn Marino break;
5255*e4b17023SJohn Marino }
5256*e4b17023SJohn Marino return list;
5257*e4b17023SJohn Marino }
5258*e4b17023SJohn Marino
5259*e4b17023SJohn Marino /* Parse asm clobbers, a GNU extension.
5260*e4b17023SJohn Marino
5261*e4b17023SJohn Marino asm-clobbers:
5262*e4b17023SJohn Marino asm-string-literal
5263*e4b17023SJohn Marino asm-clobbers , asm-string-literal
5264*e4b17023SJohn Marino */
5265*e4b17023SJohn Marino
5266*e4b17023SJohn Marino static tree
c_parser_asm_clobbers(c_parser * parser)5267*e4b17023SJohn Marino c_parser_asm_clobbers (c_parser *parser)
5268*e4b17023SJohn Marino {
5269*e4b17023SJohn Marino tree list = NULL_TREE;
5270*e4b17023SJohn Marino while (true)
5271*e4b17023SJohn Marino {
5272*e4b17023SJohn Marino tree str = c_parser_asm_string_literal (parser);
5273*e4b17023SJohn Marino if (str)
5274*e4b17023SJohn Marino list = tree_cons (NULL_TREE, str, list);
5275*e4b17023SJohn Marino else
5276*e4b17023SJohn Marino return NULL_TREE;
5277*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
5278*e4b17023SJohn Marino c_parser_consume_token (parser);
5279*e4b17023SJohn Marino else
5280*e4b17023SJohn Marino break;
5281*e4b17023SJohn Marino }
5282*e4b17023SJohn Marino return list;
5283*e4b17023SJohn Marino }
5284*e4b17023SJohn Marino
5285*e4b17023SJohn Marino /* Parse asm goto labels, a GNU extension.
5286*e4b17023SJohn Marino
5287*e4b17023SJohn Marino asm-goto-operands:
5288*e4b17023SJohn Marino identifier
5289*e4b17023SJohn Marino asm-goto-operands , identifier
5290*e4b17023SJohn Marino */
5291*e4b17023SJohn Marino
5292*e4b17023SJohn Marino static tree
c_parser_asm_goto_operands(c_parser * parser)5293*e4b17023SJohn Marino c_parser_asm_goto_operands (c_parser *parser)
5294*e4b17023SJohn Marino {
5295*e4b17023SJohn Marino tree list = NULL_TREE;
5296*e4b17023SJohn Marino while (true)
5297*e4b17023SJohn Marino {
5298*e4b17023SJohn Marino tree name, label;
5299*e4b17023SJohn Marino
5300*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
5301*e4b17023SJohn Marino {
5302*e4b17023SJohn Marino c_token *tok = c_parser_peek_token (parser);
5303*e4b17023SJohn Marino name = tok->value;
5304*e4b17023SJohn Marino label = lookup_label_for_goto (tok->location, name);
5305*e4b17023SJohn Marino c_parser_consume_token (parser);
5306*e4b17023SJohn Marino TREE_USED (label) = 1;
5307*e4b17023SJohn Marino }
5308*e4b17023SJohn Marino else
5309*e4b17023SJohn Marino {
5310*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
5311*e4b17023SJohn Marino return NULL_TREE;
5312*e4b17023SJohn Marino }
5313*e4b17023SJohn Marino
5314*e4b17023SJohn Marino name = build_string (IDENTIFIER_LENGTH (name),
5315*e4b17023SJohn Marino IDENTIFIER_POINTER (name));
5316*e4b17023SJohn Marino list = tree_cons (name, label, list);
5317*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
5318*e4b17023SJohn Marino c_parser_consume_token (parser);
5319*e4b17023SJohn Marino else
5320*e4b17023SJohn Marino return nreverse (list);
5321*e4b17023SJohn Marino }
5322*e4b17023SJohn Marino }
5323*e4b17023SJohn Marino
5324*e4b17023SJohn Marino /* Parse an expression other than a compound expression; that is, an
5325*e4b17023SJohn Marino assignment expression (C90 6.3.16, C99 6.5.16). If AFTER is not
5326*e4b17023SJohn Marino NULL then it is an Objective-C message expression which is the
5327*e4b17023SJohn Marino primary-expression starting the expression as an initializer.
5328*e4b17023SJohn Marino
5329*e4b17023SJohn Marino assignment-expression:
5330*e4b17023SJohn Marino conditional-expression
5331*e4b17023SJohn Marino unary-expression assignment-operator assignment-expression
5332*e4b17023SJohn Marino
5333*e4b17023SJohn Marino assignment-operator: one of
5334*e4b17023SJohn Marino = *= /= %= += -= <<= >>= &= ^= |=
5335*e4b17023SJohn Marino
5336*e4b17023SJohn Marino In GNU C we accept any conditional expression on the LHS and
5337*e4b17023SJohn Marino diagnose the invalid lvalue rather than producing a syntax
5338*e4b17023SJohn Marino error. */
5339*e4b17023SJohn Marino
5340*e4b17023SJohn Marino static struct c_expr
c_parser_expr_no_commas(c_parser * parser,struct c_expr * after)5341*e4b17023SJohn Marino c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
5342*e4b17023SJohn Marino {
5343*e4b17023SJohn Marino struct c_expr lhs, rhs, ret;
5344*e4b17023SJohn Marino enum tree_code code;
5345*e4b17023SJohn Marino location_t op_location, exp_location;
5346*e4b17023SJohn Marino gcc_assert (!after || c_dialect_objc ());
5347*e4b17023SJohn Marino lhs = c_parser_conditional_expression (parser, after);
5348*e4b17023SJohn Marino op_location = c_parser_peek_token (parser)->location;
5349*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
5350*e4b17023SJohn Marino {
5351*e4b17023SJohn Marino case CPP_EQ:
5352*e4b17023SJohn Marino code = NOP_EXPR;
5353*e4b17023SJohn Marino break;
5354*e4b17023SJohn Marino case CPP_MULT_EQ:
5355*e4b17023SJohn Marino code = MULT_EXPR;
5356*e4b17023SJohn Marino break;
5357*e4b17023SJohn Marino case CPP_DIV_EQ:
5358*e4b17023SJohn Marino code = TRUNC_DIV_EXPR;
5359*e4b17023SJohn Marino break;
5360*e4b17023SJohn Marino case CPP_MOD_EQ:
5361*e4b17023SJohn Marino code = TRUNC_MOD_EXPR;
5362*e4b17023SJohn Marino break;
5363*e4b17023SJohn Marino case CPP_PLUS_EQ:
5364*e4b17023SJohn Marino code = PLUS_EXPR;
5365*e4b17023SJohn Marino break;
5366*e4b17023SJohn Marino case CPP_MINUS_EQ:
5367*e4b17023SJohn Marino code = MINUS_EXPR;
5368*e4b17023SJohn Marino break;
5369*e4b17023SJohn Marino case CPP_LSHIFT_EQ:
5370*e4b17023SJohn Marino code = LSHIFT_EXPR;
5371*e4b17023SJohn Marino break;
5372*e4b17023SJohn Marino case CPP_RSHIFT_EQ:
5373*e4b17023SJohn Marino code = RSHIFT_EXPR;
5374*e4b17023SJohn Marino break;
5375*e4b17023SJohn Marino case CPP_AND_EQ:
5376*e4b17023SJohn Marino code = BIT_AND_EXPR;
5377*e4b17023SJohn Marino break;
5378*e4b17023SJohn Marino case CPP_XOR_EQ:
5379*e4b17023SJohn Marino code = BIT_XOR_EXPR;
5380*e4b17023SJohn Marino break;
5381*e4b17023SJohn Marino case CPP_OR_EQ:
5382*e4b17023SJohn Marino code = BIT_IOR_EXPR;
5383*e4b17023SJohn Marino break;
5384*e4b17023SJohn Marino default:
5385*e4b17023SJohn Marino return lhs;
5386*e4b17023SJohn Marino }
5387*e4b17023SJohn Marino c_parser_consume_token (parser);
5388*e4b17023SJohn Marino exp_location = c_parser_peek_token (parser)->location;
5389*e4b17023SJohn Marino rhs = c_parser_expr_no_commas (parser, NULL);
5390*e4b17023SJohn Marino rhs = default_function_array_read_conversion (exp_location, rhs);
5391*e4b17023SJohn Marino ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
5392*e4b17023SJohn Marino code, exp_location, rhs.value,
5393*e4b17023SJohn Marino rhs.original_type);
5394*e4b17023SJohn Marino if (code == NOP_EXPR)
5395*e4b17023SJohn Marino ret.original_code = MODIFY_EXPR;
5396*e4b17023SJohn Marino else
5397*e4b17023SJohn Marino {
5398*e4b17023SJohn Marino TREE_NO_WARNING (ret.value) = 1;
5399*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
5400*e4b17023SJohn Marino }
5401*e4b17023SJohn Marino ret.original_type = NULL;
5402*e4b17023SJohn Marino return ret;
5403*e4b17023SJohn Marino }
5404*e4b17023SJohn Marino
5405*e4b17023SJohn Marino /* Parse a conditional expression (C90 6.3.15, C99 6.5.15). If AFTER
5406*e4b17023SJohn Marino is not NULL then it is an Objective-C message expression which is
5407*e4b17023SJohn Marino the primary-expression starting the expression as an initializer.
5408*e4b17023SJohn Marino
5409*e4b17023SJohn Marino conditional-expression:
5410*e4b17023SJohn Marino logical-OR-expression
5411*e4b17023SJohn Marino logical-OR-expression ? expression : conditional-expression
5412*e4b17023SJohn Marino
5413*e4b17023SJohn Marino GNU extensions:
5414*e4b17023SJohn Marino
5415*e4b17023SJohn Marino conditional-expression:
5416*e4b17023SJohn Marino logical-OR-expression ? : conditional-expression
5417*e4b17023SJohn Marino */
5418*e4b17023SJohn Marino
5419*e4b17023SJohn Marino static struct c_expr
c_parser_conditional_expression(c_parser * parser,struct c_expr * after)5420*e4b17023SJohn Marino c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
5421*e4b17023SJohn Marino {
5422*e4b17023SJohn Marino struct c_expr cond, exp1, exp2, ret;
5423*e4b17023SJohn Marino location_t cond_loc, colon_loc, middle_loc;
5424*e4b17023SJohn Marino
5425*e4b17023SJohn Marino gcc_assert (!after || c_dialect_objc ());
5426*e4b17023SJohn Marino
5427*e4b17023SJohn Marino cond = c_parser_binary_expression (parser, after, PREC_NONE);
5428*e4b17023SJohn Marino
5429*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_QUERY))
5430*e4b17023SJohn Marino return cond;
5431*e4b17023SJohn Marino cond_loc = c_parser_peek_token (parser)->location;
5432*e4b17023SJohn Marino cond = default_function_array_read_conversion (cond_loc, cond);
5433*e4b17023SJohn Marino c_parser_consume_token (parser);
5434*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COLON))
5435*e4b17023SJohn Marino {
5436*e4b17023SJohn Marino tree eptype = NULL_TREE;
5437*e4b17023SJohn Marino
5438*e4b17023SJohn Marino middle_loc = c_parser_peek_token (parser)->location;
5439*e4b17023SJohn Marino pedwarn (middle_loc, OPT_pedantic,
5440*e4b17023SJohn Marino "ISO C forbids omitting the middle term of a ?: expression");
5441*e4b17023SJohn Marino warn_for_omitted_condop (middle_loc, cond.value);
5442*e4b17023SJohn Marino if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
5443*e4b17023SJohn Marino {
5444*e4b17023SJohn Marino eptype = TREE_TYPE (cond.value);
5445*e4b17023SJohn Marino cond.value = TREE_OPERAND (cond.value, 0);
5446*e4b17023SJohn Marino }
5447*e4b17023SJohn Marino /* Make sure first operand is calculated only once. */
5448*e4b17023SJohn Marino exp1.value = c_save_expr (default_conversion (cond.value));
5449*e4b17023SJohn Marino if (eptype)
5450*e4b17023SJohn Marino exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
5451*e4b17023SJohn Marino exp1.original_type = NULL;
5452*e4b17023SJohn Marino cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
5453*e4b17023SJohn Marino c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
5454*e4b17023SJohn Marino }
5455*e4b17023SJohn Marino else
5456*e4b17023SJohn Marino {
5457*e4b17023SJohn Marino cond.value
5458*e4b17023SJohn Marino = c_objc_common_truthvalue_conversion
5459*e4b17023SJohn Marino (cond_loc, default_conversion (cond.value));
5460*e4b17023SJohn Marino c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
5461*e4b17023SJohn Marino exp1 = c_parser_expression_conv (parser);
5462*e4b17023SJohn Marino mark_exp_read (exp1.value);
5463*e4b17023SJohn Marino c_inhibit_evaluation_warnings +=
5464*e4b17023SJohn Marino ((cond.value == truthvalue_true_node)
5465*e4b17023SJohn Marino - (cond.value == truthvalue_false_node));
5466*e4b17023SJohn Marino }
5467*e4b17023SJohn Marino
5468*e4b17023SJohn Marino colon_loc = c_parser_peek_token (parser)->location;
5469*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5470*e4b17023SJohn Marino {
5471*e4b17023SJohn Marino c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
5472*e4b17023SJohn Marino ret.value = error_mark_node;
5473*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
5474*e4b17023SJohn Marino ret.original_type = NULL;
5475*e4b17023SJohn Marino return ret;
5476*e4b17023SJohn Marino }
5477*e4b17023SJohn Marino {
5478*e4b17023SJohn Marino location_t exp2_loc = c_parser_peek_token (parser)->location;
5479*e4b17023SJohn Marino exp2 = c_parser_conditional_expression (parser, NULL);
5480*e4b17023SJohn Marino exp2 = default_function_array_read_conversion (exp2_loc, exp2);
5481*e4b17023SJohn Marino }
5482*e4b17023SJohn Marino c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
5483*e4b17023SJohn Marino ret.value = build_conditional_expr (colon_loc, cond.value,
5484*e4b17023SJohn Marino cond.original_code == C_MAYBE_CONST_EXPR,
5485*e4b17023SJohn Marino exp1.value, exp1.original_type,
5486*e4b17023SJohn Marino exp2.value, exp2.original_type);
5487*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
5488*e4b17023SJohn Marino if (exp1.value == error_mark_node || exp2.value == error_mark_node)
5489*e4b17023SJohn Marino ret.original_type = NULL;
5490*e4b17023SJohn Marino else
5491*e4b17023SJohn Marino {
5492*e4b17023SJohn Marino tree t1, t2;
5493*e4b17023SJohn Marino
5494*e4b17023SJohn Marino /* If both sides are enum type, the default conversion will have
5495*e4b17023SJohn Marino made the type of the result be an integer type. We want to
5496*e4b17023SJohn Marino remember the enum types we started with. */
5497*e4b17023SJohn Marino t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
5498*e4b17023SJohn Marino t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
5499*e4b17023SJohn Marino ret.original_type = ((t1 != error_mark_node
5500*e4b17023SJohn Marino && t2 != error_mark_node
5501*e4b17023SJohn Marino && (TYPE_MAIN_VARIANT (t1)
5502*e4b17023SJohn Marino == TYPE_MAIN_VARIANT (t2)))
5503*e4b17023SJohn Marino ? t1
5504*e4b17023SJohn Marino : NULL);
5505*e4b17023SJohn Marino }
5506*e4b17023SJohn Marino return ret;
5507*e4b17023SJohn Marino }
5508*e4b17023SJohn Marino
5509*e4b17023SJohn Marino /* Parse a binary expression; that is, a logical-OR-expression (C90
5510*e4b17023SJohn Marino 6.3.5-6.3.14, C99 6.5.5-6.5.14). If AFTER is not NULL then it is
5511*e4b17023SJohn Marino an Objective-C message expression which is the primary-expression
5512*e4b17023SJohn Marino starting the expression as an initializer. PREC is the starting
5513*e4b17023SJohn Marino precedence, usually PREC_NONE.
5514*e4b17023SJohn Marino
5515*e4b17023SJohn Marino multiplicative-expression:
5516*e4b17023SJohn Marino cast-expression
5517*e4b17023SJohn Marino multiplicative-expression * cast-expression
5518*e4b17023SJohn Marino multiplicative-expression / cast-expression
5519*e4b17023SJohn Marino multiplicative-expression % cast-expression
5520*e4b17023SJohn Marino
5521*e4b17023SJohn Marino additive-expression:
5522*e4b17023SJohn Marino multiplicative-expression
5523*e4b17023SJohn Marino additive-expression + multiplicative-expression
5524*e4b17023SJohn Marino additive-expression - multiplicative-expression
5525*e4b17023SJohn Marino
5526*e4b17023SJohn Marino shift-expression:
5527*e4b17023SJohn Marino additive-expression
5528*e4b17023SJohn Marino shift-expression << additive-expression
5529*e4b17023SJohn Marino shift-expression >> additive-expression
5530*e4b17023SJohn Marino
5531*e4b17023SJohn Marino relational-expression:
5532*e4b17023SJohn Marino shift-expression
5533*e4b17023SJohn Marino relational-expression < shift-expression
5534*e4b17023SJohn Marino relational-expression > shift-expression
5535*e4b17023SJohn Marino relational-expression <= shift-expression
5536*e4b17023SJohn Marino relational-expression >= shift-expression
5537*e4b17023SJohn Marino
5538*e4b17023SJohn Marino equality-expression:
5539*e4b17023SJohn Marino relational-expression
5540*e4b17023SJohn Marino equality-expression == relational-expression
5541*e4b17023SJohn Marino equality-expression != relational-expression
5542*e4b17023SJohn Marino
5543*e4b17023SJohn Marino AND-expression:
5544*e4b17023SJohn Marino equality-expression
5545*e4b17023SJohn Marino AND-expression & equality-expression
5546*e4b17023SJohn Marino
5547*e4b17023SJohn Marino exclusive-OR-expression:
5548*e4b17023SJohn Marino AND-expression
5549*e4b17023SJohn Marino exclusive-OR-expression ^ AND-expression
5550*e4b17023SJohn Marino
5551*e4b17023SJohn Marino inclusive-OR-expression:
5552*e4b17023SJohn Marino exclusive-OR-expression
5553*e4b17023SJohn Marino inclusive-OR-expression | exclusive-OR-expression
5554*e4b17023SJohn Marino
5555*e4b17023SJohn Marino logical-AND-expression:
5556*e4b17023SJohn Marino inclusive-OR-expression
5557*e4b17023SJohn Marino logical-AND-expression && inclusive-OR-expression
5558*e4b17023SJohn Marino
5559*e4b17023SJohn Marino logical-OR-expression:
5560*e4b17023SJohn Marino logical-AND-expression
5561*e4b17023SJohn Marino logical-OR-expression || logical-AND-expression
5562*e4b17023SJohn Marino */
5563*e4b17023SJohn Marino
5564*e4b17023SJohn Marino static struct c_expr
c_parser_binary_expression(c_parser * parser,struct c_expr * after,enum c_parser_prec prec)5565*e4b17023SJohn Marino c_parser_binary_expression (c_parser *parser, struct c_expr *after,
5566*e4b17023SJohn Marino enum c_parser_prec prec)
5567*e4b17023SJohn Marino {
5568*e4b17023SJohn Marino /* A binary expression is parsed using operator-precedence parsing,
5569*e4b17023SJohn Marino with the operands being cast expressions. All the binary
5570*e4b17023SJohn Marino operators are left-associative. Thus a binary expression is of
5571*e4b17023SJohn Marino form:
5572*e4b17023SJohn Marino
5573*e4b17023SJohn Marino E0 op1 E1 op2 E2 ...
5574*e4b17023SJohn Marino
5575*e4b17023SJohn Marino which we represent on a stack. On the stack, the precedence
5576*e4b17023SJohn Marino levels are strictly increasing. When a new operator is
5577*e4b17023SJohn Marino encountered of higher precedence than that at the top of the
5578*e4b17023SJohn Marino stack, it is pushed; its LHS is the top expression, and its RHS
5579*e4b17023SJohn Marino is everything parsed until it is popped. When a new operator is
5580*e4b17023SJohn Marino encountered with precedence less than or equal to that at the top
5581*e4b17023SJohn Marino of the stack, triples E[i-1] op[i] E[i] are popped and replaced
5582*e4b17023SJohn Marino by the result of the operation until the operator at the top of
5583*e4b17023SJohn Marino the stack has lower precedence than the new operator or there is
5584*e4b17023SJohn Marino only one element on the stack; then the top expression is the LHS
5585*e4b17023SJohn Marino of the new operator. In the case of logical AND and OR
5586*e4b17023SJohn Marino expressions, we also need to adjust c_inhibit_evaluation_warnings
5587*e4b17023SJohn Marino as appropriate when the operators are pushed and popped. */
5588*e4b17023SJohn Marino
5589*e4b17023SJohn Marino struct {
5590*e4b17023SJohn Marino /* The expression at this stack level. */
5591*e4b17023SJohn Marino struct c_expr expr;
5592*e4b17023SJohn Marino /* The precedence of the operator on its left, PREC_NONE at the
5593*e4b17023SJohn Marino bottom of the stack. */
5594*e4b17023SJohn Marino enum c_parser_prec prec;
5595*e4b17023SJohn Marino /* The operation on its left. */
5596*e4b17023SJohn Marino enum tree_code op;
5597*e4b17023SJohn Marino /* The source location of this operation. */
5598*e4b17023SJohn Marino location_t loc;
5599*e4b17023SJohn Marino } stack[NUM_PRECS];
5600*e4b17023SJohn Marino int sp;
5601*e4b17023SJohn Marino /* Location of the binary operator. */
5602*e4b17023SJohn Marino location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5603*e4b17023SJohn Marino #define POP \
5604*e4b17023SJohn Marino do { \
5605*e4b17023SJohn Marino switch (stack[sp].op) \
5606*e4b17023SJohn Marino { \
5607*e4b17023SJohn Marino case TRUTH_ANDIF_EXPR: \
5608*e4b17023SJohn Marino c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
5609*e4b17023SJohn Marino == truthvalue_false_node); \
5610*e4b17023SJohn Marino break; \
5611*e4b17023SJohn Marino case TRUTH_ORIF_EXPR: \
5612*e4b17023SJohn Marino c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
5613*e4b17023SJohn Marino == truthvalue_true_node); \
5614*e4b17023SJohn Marino break; \
5615*e4b17023SJohn Marino default: \
5616*e4b17023SJohn Marino break; \
5617*e4b17023SJohn Marino } \
5618*e4b17023SJohn Marino stack[sp - 1].expr \
5619*e4b17023SJohn Marino = default_function_array_read_conversion (stack[sp - 1].loc, \
5620*e4b17023SJohn Marino stack[sp - 1].expr); \
5621*e4b17023SJohn Marino stack[sp].expr \
5622*e4b17023SJohn Marino = default_function_array_read_conversion (stack[sp].loc, \
5623*e4b17023SJohn Marino stack[sp].expr); \
5624*e4b17023SJohn Marino stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
5625*e4b17023SJohn Marino stack[sp].op, \
5626*e4b17023SJohn Marino stack[sp - 1].expr, \
5627*e4b17023SJohn Marino stack[sp].expr); \
5628*e4b17023SJohn Marino sp--; \
5629*e4b17023SJohn Marino } while (0)
5630*e4b17023SJohn Marino gcc_assert (!after || c_dialect_objc ());
5631*e4b17023SJohn Marino stack[0].loc = c_parser_peek_token (parser)->location;
5632*e4b17023SJohn Marino stack[0].expr = c_parser_cast_expression (parser, after);
5633*e4b17023SJohn Marino stack[0].prec = prec;
5634*e4b17023SJohn Marino sp = 0;
5635*e4b17023SJohn Marino while (true)
5636*e4b17023SJohn Marino {
5637*e4b17023SJohn Marino enum c_parser_prec oprec;
5638*e4b17023SJohn Marino enum tree_code ocode;
5639*e4b17023SJohn Marino if (parser->error)
5640*e4b17023SJohn Marino goto out;
5641*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
5642*e4b17023SJohn Marino {
5643*e4b17023SJohn Marino case CPP_MULT:
5644*e4b17023SJohn Marino oprec = PREC_MULT;
5645*e4b17023SJohn Marino ocode = MULT_EXPR;
5646*e4b17023SJohn Marino break;
5647*e4b17023SJohn Marino case CPP_DIV:
5648*e4b17023SJohn Marino oprec = PREC_MULT;
5649*e4b17023SJohn Marino ocode = TRUNC_DIV_EXPR;
5650*e4b17023SJohn Marino break;
5651*e4b17023SJohn Marino case CPP_MOD:
5652*e4b17023SJohn Marino oprec = PREC_MULT;
5653*e4b17023SJohn Marino ocode = TRUNC_MOD_EXPR;
5654*e4b17023SJohn Marino break;
5655*e4b17023SJohn Marino case CPP_PLUS:
5656*e4b17023SJohn Marino oprec = PREC_ADD;
5657*e4b17023SJohn Marino ocode = PLUS_EXPR;
5658*e4b17023SJohn Marino break;
5659*e4b17023SJohn Marino case CPP_MINUS:
5660*e4b17023SJohn Marino oprec = PREC_ADD;
5661*e4b17023SJohn Marino ocode = MINUS_EXPR;
5662*e4b17023SJohn Marino break;
5663*e4b17023SJohn Marino case CPP_LSHIFT:
5664*e4b17023SJohn Marino oprec = PREC_SHIFT;
5665*e4b17023SJohn Marino ocode = LSHIFT_EXPR;
5666*e4b17023SJohn Marino break;
5667*e4b17023SJohn Marino case CPP_RSHIFT:
5668*e4b17023SJohn Marino oprec = PREC_SHIFT;
5669*e4b17023SJohn Marino ocode = RSHIFT_EXPR;
5670*e4b17023SJohn Marino break;
5671*e4b17023SJohn Marino case CPP_LESS:
5672*e4b17023SJohn Marino oprec = PREC_REL;
5673*e4b17023SJohn Marino ocode = LT_EXPR;
5674*e4b17023SJohn Marino break;
5675*e4b17023SJohn Marino case CPP_GREATER:
5676*e4b17023SJohn Marino oprec = PREC_REL;
5677*e4b17023SJohn Marino ocode = GT_EXPR;
5678*e4b17023SJohn Marino break;
5679*e4b17023SJohn Marino case CPP_LESS_EQ:
5680*e4b17023SJohn Marino oprec = PREC_REL;
5681*e4b17023SJohn Marino ocode = LE_EXPR;
5682*e4b17023SJohn Marino break;
5683*e4b17023SJohn Marino case CPP_GREATER_EQ:
5684*e4b17023SJohn Marino oprec = PREC_REL;
5685*e4b17023SJohn Marino ocode = GE_EXPR;
5686*e4b17023SJohn Marino break;
5687*e4b17023SJohn Marino case CPP_EQ_EQ:
5688*e4b17023SJohn Marino oprec = PREC_EQ;
5689*e4b17023SJohn Marino ocode = EQ_EXPR;
5690*e4b17023SJohn Marino break;
5691*e4b17023SJohn Marino case CPP_NOT_EQ:
5692*e4b17023SJohn Marino oprec = PREC_EQ;
5693*e4b17023SJohn Marino ocode = NE_EXPR;
5694*e4b17023SJohn Marino break;
5695*e4b17023SJohn Marino case CPP_AND:
5696*e4b17023SJohn Marino oprec = PREC_BITAND;
5697*e4b17023SJohn Marino ocode = BIT_AND_EXPR;
5698*e4b17023SJohn Marino break;
5699*e4b17023SJohn Marino case CPP_XOR:
5700*e4b17023SJohn Marino oprec = PREC_BITXOR;
5701*e4b17023SJohn Marino ocode = BIT_XOR_EXPR;
5702*e4b17023SJohn Marino break;
5703*e4b17023SJohn Marino case CPP_OR:
5704*e4b17023SJohn Marino oprec = PREC_BITOR;
5705*e4b17023SJohn Marino ocode = BIT_IOR_EXPR;
5706*e4b17023SJohn Marino break;
5707*e4b17023SJohn Marino case CPP_AND_AND:
5708*e4b17023SJohn Marino oprec = PREC_LOGAND;
5709*e4b17023SJohn Marino ocode = TRUTH_ANDIF_EXPR;
5710*e4b17023SJohn Marino break;
5711*e4b17023SJohn Marino case CPP_OR_OR:
5712*e4b17023SJohn Marino oprec = PREC_LOGOR;
5713*e4b17023SJohn Marino ocode = TRUTH_ORIF_EXPR;
5714*e4b17023SJohn Marino break;
5715*e4b17023SJohn Marino default:
5716*e4b17023SJohn Marino /* Not a binary operator, so end of the binary
5717*e4b17023SJohn Marino expression. */
5718*e4b17023SJohn Marino goto out;
5719*e4b17023SJohn Marino }
5720*e4b17023SJohn Marino binary_loc = c_parser_peek_token (parser)->location;
5721*e4b17023SJohn Marino while (oprec <= stack[sp].prec)
5722*e4b17023SJohn Marino {
5723*e4b17023SJohn Marino if (sp == 0)
5724*e4b17023SJohn Marino goto out;
5725*e4b17023SJohn Marino POP;
5726*e4b17023SJohn Marino }
5727*e4b17023SJohn Marino c_parser_consume_token (parser);
5728*e4b17023SJohn Marino switch (ocode)
5729*e4b17023SJohn Marino {
5730*e4b17023SJohn Marino case TRUTH_ANDIF_EXPR:
5731*e4b17023SJohn Marino stack[sp].expr
5732*e4b17023SJohn Marino = default_function_array_read_conversion (stack[sp].loc,
5733*e4b17023SJohn Marino stack[sp].expr);
5734*e4b17023SJohn Marino stack[sp].expr.value = c_objc_common_truthvalue_conversion
5735*e4b17023SJohn Marino (stack[sp].loc, default_conversion (stack[sp].expr.value));
5736*e4b17023SJohn Marino c_inhibit_evaluation_warnings += (stack[sp].expr.value
5737*e4b17023SJohn Marino == truthvalue_false_node);
5738*e4b17023SJohn Marino break;
5739*e4b17023SJohn Marino case TRUTH_ORIF_EXPR:
5740*e4b17023SJohn Marino stack[sp].expr
5741*e4b17023SJohn Marino = default_function_array_read_conversion (stack[sp].loc,
5742*e4b17023SJohn Marino stack[sp].expr);
5743*e4b17023SJohn Marino stack[sp].expr.value = c_objc_common_truthvalue_conversion
5744*e4b17023SJohn Marino (stack[sp].loc, default_conversion (stack[sp].expr.value));
5745*e4b17023SJohn Marino c_inhibit_evaluation_warnings += (stack[sp].expr.value
5746*e4b17023SJohn Marino == truthvalue_true_node);
5747*e4b17023SJohn Marino break;
5748*e4b17023SJohn Marino default:
5749*e4b17023SJohn Marino break;
5750*e4b17023SJohn Marino }
5751*e4b17023SJohn Marino sp++;
5752*e4b17023SJohn Marino stack[sp].loc = binary_loc;
5753*e4b17023SJohn Marino stack[sp].expr = c_parser_cast_expression (parser, NULL);
5754*e4b17023SJohn Marino stack[sp].prec = oprec;
5755*e4b17023SJohn Marino stack[sp].op = ocode;
5756*e4b17023SJohn Marino stack[sp].loc = binary_loc;
5757*e4b17023SJohn Marino }
5758*e4b17023SJohn Marino out:
5759*e4b17023SJohn Marino while (sp > 0)
5760*e4b17023SJohn Marino POP;
5761*e4b17023SJohn Marino return stack[0].expr;
5762*e4b17023SJohn Marino #undef POP
5763*e4b17023SJohn Marino }
5764*e4b17023SJohn Marino
5765*e4b17023SJohn Marino /* Parse a cast expression (C90 6.3.4, C99 6.5.4). If AFTER is not
5766*e4b17023SJohn Marino NULL then it is an Objective-C message expression which is the
5767*e4b17023SJohn Marino primary-expression starting the expression as an initializer.
5768*e4b17023SJohn Marino
5769*e4b17023SJohn Marino cast-expression:
5770*e4b17023SJohn Marino unary-expression
5771*e4b17023SJohn Marino ( type-name ) unary-expression
5772*e4b17023SJohn Marino */
5773*e4b17023SJohn Marino
5774*e4b17023SJohn Marino static struct c_expr
c_parser_cast_expression(c_parser * parser,struct c_expr * after)5775*e4b17023SJohn Marino c_parser_cast_expression (c_parser *parser, struct c_expr *after)
5776*e4b17023SJohn Marino {
5777*e4b17023SJohn Marino location_t cast_loc = c_parser_peek_token (parser)->location;
5778*e4b17023SJohn Marino gcc_assert (!after || c_dialect_objc ());
5779*e4b17023SJohn Marino if (after)
5780*e4b17023SJohn Marino return c_parser_postfix_expression_after_primary (parser,
5781*e4b17023SJohn Marino cast_loc, *after);
5782*e4b17023SJohn Marino /* If the expression begins with a parenthesized type name, it may
5783*e4b17023SJohn Marino be either a cast or a compound literal; we need to see whether
5784*e4b17023SJohn Marino the next character is '{' to tell the difference. If not, it is
5785*e4b17023SJohn Marino an unary expression. Full detection of unknown typenames here
5786*e4b17023SJohn Marino would require a 3-token lookahead. */
5787*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5788*e4b17023SJohn Marino && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5789*e4b17023SJohn Marino {
5790*e4b17023SJohn Marino struct c_type_name *type_name;
5791*e4b17023SJohn Marino struct c_expr ret;
5792*e4b17023SJohn Marino struct c_expr expr;
5793*e4b17023SJohn Marino c_parser_consume_token (parser);
5794*e4b17023SJohn Marino type_name = c_parser_type_name (parser);
5795*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5796*e4b17023SJohn Marino if (type_name == NULL)
5797*e4b17023SJohn Marino {
5798*e4b17023SJohn Marino ret.value = error_mark_node;
5799*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
5800*e4b17023SJohn Marino ret.original_type = NULL;
5801*e4b17023SJohn Marino return ret;
5802*e4b17023SJohn Marino }
5803*e4b17023SJohn Marino
5804*e4b17023SJohn Marino /* Save casted types in the function's used types hash table. */
5805*e4b17023SJohn Marino used_types_insert (type_name->specs->type);
5806*e4b17023SJohn Marino
5807*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5808*e4b17023SJohn Marino return c_parser_postfix_expression_after_paren_type (parser, type_name,
5809*e4b17023SJohn Marino cast_loc);
5810*e4b17023SJohn Marino {
5811*e4b17023SJohn Marino location_t expr_loc = c_parser_peek_token (parser)->location;
5812*e4b17023SJohn Marino expr = c_parser_cast_expression (parser, NULL);
5813*e4b17023SJohn Marino expr = default_function_array_read_conversion (expr_loc, expr);
5814*e4b17023SJohn Marino }
5815*e4b17023SJohn Marino ret.value = c_cast_expr (cast_loc, type_name, expr.value);
5816*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
5817*e4b17023SJohn Marino ret.original_type = NULL;
5818*e4b17023SJohn Marino return ret;
5819*e4b17023SJohn Marino }
5820*e4b17023SJohn Marino else
5821*e4b17023SJohn Marino return c_parser_unary_expression (parser);
5822*e4b17023SJohn Marino }
5823*e4b17023SJohn Marino
5824*e4b17023SJohn Marino /* Parse an unary expression (C90 6.3.3, C99 6.5.3).
5825*e4b17023SJohn Marino
5826*e4b17023SJohn Marino unary-expression:
5827*e4b17023SJohn Marino postfix-expression
5828*e4b17023SJohn Marino ++ unary-expression
5829*e4b17023SJohn Marino -- unary-expression
5830*e4b17023SJohn Marino unary-operator cast-expression
5831*e4b17023SJohn Marino sizeof unary-expression
5832*e4b17023SJohn Marino sizeof ( type-name )
5833*e4b17023SJohn Marino
5834*e4b17023SJohn Marino unary-operator: one of
5835*e4b17023SJohn Marino & * + - ~ !
5836*e4b17023SJohn Marino
5837*e4b17023SJohn Marino GNU extensions:
5838*e4b17023SJohn Marino
5839*e4b17023SJohn Marino unary-expression:
5840*e4b17023SJohn Marino __alignof__ unary-expression
5841*e4b17023SJohn Marino __alignof__ ( type-name )
5842*e4b17023SJohn Marino && identifier
5843*e4b17023SJohn Marino
5844*e4b17023SJohn Marino (C11 permits _Alignof with type names only.)
5845*e4b17023SJohn Marino
5846*e4b17023SJohn Marino unary-operator: one of
5847*e4b17023SJohn Marino __extension__ __real__ __imag__
5848*e4b17023SJohn Marino
5849*e4b17023SJohn Marino Transactional Memory:
5850*e4b17023SJohn Marino
5851*e4b17023SJohn Marino unary-expression:
5852*e4b17023SJohn Marino transaction-expression
5853*e4b17023SJohn Marino
5854*e4b17023SJohn Marino In addition, the GNU syntax treats ++ and -- as unary operators, so
5855*e4b17023SJohn Marino they may be applied to cast expressions with errors for non-lvalues
5856*e4b17023SJohn Marino given later. */
5857*e4b17023SJohn Marino
5858*e4b17023SJohn Marino static struct c_expr
c_parser_unary_expression(c_parser * parser)5859*e4b17023SJohn Marino c_parser_unary_expression (c_parser *parser)
5860*e4b17023SJohn Marino {
5861*e4b17023SJohn Marino int ext;
5862*e4b17023SJohn Marino struct c_expr ret, op;
5863*e4b17023SJohn Marino location_t op_loc = c_parser_peek_token (parser)->location;
5864*e4b17023SJohn Marino location_t exp_loc;
5865*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
5866*e4b17023SJohn Marino ret.original_type = NULL;
5867*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
5868*e4b17023SJohn Marino {
5869*e4b17023SJohn Marino case CPP_PLUS_PLUS:
5870*e4b17023SJohn Marino c_parser_consume_token (parser);
5871*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5872*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5873*e4b17023SJohn Marino op = default_function_array_read_conversion (exp_loc, op);
5874*e4b17023SJohn Marino return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
5875*e4b17023SJohn Marino case CPP_MINUS_MINUS:
5876*e4b17023SJohn Marino c_parser_consume_token (parser);
5877*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5878*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5879*e4b17023SJohn Marino op = default_function_array_read_conversion (exp_loc, op);
5880*e4b17023SJohn Marino return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
5881*e4b17023SJohn Marino case CPP_AND:
5882*e4b17023SJohn Marino c_parser_consume_token (parser);
5883*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5884*e4b17023SJohn Marino mark_exp_read (op.value);
5885*e4b17023SJohn Marino return parser_build_unary_op (op_loc, ADDR_EXPR, op);
5886*e4b17023SJohn Marino case CPP_MULT:
5887*e4b17023SJohn Marino c_parser_consume_token (parser);
5888*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5889*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5890*e4b17023SJohn Marino op = default_function_array_read_conversion (exp_loc, op);
5891*e4b17023SJohn Marino ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR);
5892*e4b17023SJohn Marino return ret;
5893*e4b17023SJohn Marino case CPP_PLUS:
5894*e4b17023SJohn Marino if (!c_dialect_objc () && !in_system_header)
5895*e4b17023SJohn Marino warning_at (op_loc,
5896*e4b17023SJohn Marino OPT_Wtraditional,
5897*e4b17023SJohn Marino "traditional C rejects the unary plus operator");
5898*e4b17023SJohn Marino c_parser_consume_token (parser);
5899*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5900*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5901*e4b17023SJohn Marino op = default_function_array_read_conversion (exp_loc, op);
5902*e4b17023SJohn Marino return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
5903*e4b17023SJohn Marino case CPP_MINUS:
5904*e4b17023SJohn Marino c_parser_consume_token (parser);
5905*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5906*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5907*e4b17023SJohn Marino op = default_function_array_read_conversion (exp_loc, op);
5908*e4b17023SJohn Marino return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
5909*e4b17023SJohn Marino case CPP_COMPL:
5910*e4b17023SJohn Marino c_parser_consume_token (parser);
5911*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5912*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5913*e4b17023SJohn Marino op = default_function_array_read_conversion (exp_loc, op);
5914*e4b17023SJohn Marino return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
5915*e4b17023SJohn Marino case CPP_NOT:
5916*e4b17023SJohn Marino c_parser_consume_token (parser);
5917*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5918*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5919*e4b17023SJohn Marino op = default_function_array_read_conversion (exp_loc, op);
5920*e4b17023SJohn Marino return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
5921*e4b17023SJohn Marino case CPP_AND_AND:
5922*e4b17023SJohn Marino /* Refer to the address of a label as a pointer. */
5923*e4b17023SJohn Marino c_parser_consume_token (parser);
5924*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
5925*e4b17023SJohn Marino {
5926*e4b17023SJohn Marino ret.value = finish_label_address_expr
5927*e4b17023SJohn Marino (c_parser_peek_token (parser)->value, op_loc);
5928*e4b17023SJohn Marino c_parser_consume_token (parser);
5929*e4b17023SJohn Marino }
5930*e4b17023SJohn Marino else
5931*e4b17023SJohn Marino {
5932*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
5933*e4b17023SJohn Marino ret.value = error_mark_node;
5934*e4b17023SJohn Marino }
5935*e4b17023SJohn Marino return ret;
5936*e4b17023SJohn Marino case CPP_KEYWORD:
5937*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->keyword)
5938*e4b17023SJohn Marino {
5939*e4b17023SJohn Marino case RID_SIZEOF:
5940*e4b17023SJohn Marino return c_parser_sizeof_expression (parser);
5941*e4b17023SJohn Marino case RID_ALIGNOF:
5942*e4b17023SJohn Marino return c_parser_alignof_expression (parser);
5943*e4b17023SJohn Marino case RID_EXTENSION:
5944*e4b17023SJohn Marino c_parser_consume_token (parser);
5945*e4b17023SJohn Marino ext = disable_extension_diagnostics ();
5946*e4b17023SJohn Marino ret = c_parser_cast_expression (parser, NULL);
5947*e4b17023SJohn Marino restore_extension_diagnostics (ext);
5948*e4b17023SJohn Marino return ret;
5949*e4b17023SJohn Marino case RID_REALPART:
5950*e4b17023SJohn Marino c_parser_consume_token (parser);
5951*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5952*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5953*e4b17023SJohn Marino op = default_function_array_conversion (exp_loc, op);
5954*e4b17023SJohn Marino return parser_build_unary_op (op_loc, REALPART_EXPR, op);
5955*e4b17023SJohn Marino case RID_IMAGPART:
5956*e4b17023SJohn Marino c_parser_consume_token (parser);
5957*e4b17023SJohn Marino exp_loc = c_parser_peek_token (parser)->location;
5958*e4b17023SJohn Marino op = c_parser_cast_expression (parser, NULL);
5959*e4b17023SJohn Marino op = default_function_array_conversion (exp_loc, op);
5960*e4b17023SJohn Marino return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
5961*e4b17023SJohn Marino case RID_TRANSACTION_ATOMIC:
5962*e4b17023SJohn Marino case RID_TRANSACTION_RELAXED:
5963*e4b17023SJohn Marino return c_parser_transaction_expression (parser,
5964*e4b17023SJohn Marino c_parser_peek_token (parser)->keyword);
5965*e4b17023SJohn Marino default:
5966*e4b17023SJohn Marino return c_parser_postfix_expression (parser);
5967*e4b17023SJohn Marino }
5968*e4b17023SJohn Marino default:
5969*e4b17023SJohn Marino return c_parser_postfix_expression (parser);
5970*e4b17023SJohn Marino }
5971*e4b17023SJohn Marino }
5972*e4b17023SJohn Marino
5973*e4b17023SJohn Marino /* Parse a sizeof expression. */
5974*e4b17023SJohn Marino
5975*e4b17023SJohn Marino static struct c_expr
c_parser_sizeof_expression(c_parser * parser)5976*e4b17023SJohn Marino c_parser_sizeof_expression (c_parser *parser)
5977*e4b17023SJohn Marino {
5978*e4b17023SJohn Marino struct c_expr expr;
5979*e4b17023SJohn Marino location_t expr_loc;
5980*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
5981*e4b17023SJohn Marino c_parser_consume_token (parser);
5982*e4b17023SJohn Marino c_inhibit_evaluation_warnings++;
5983*e4b17023SJohn Marino in_sizeof++;
5984*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5985*e4b17023SJohn Marino && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5986*e4b17023SJohn Marino {
5987*e4b17023SJohn Marino /* Either sizeof ( type-name ) or sizeof unary-expression
5988*e4b17023SJohn Marino starting with a compound literal. */
5989*e4b17023SJohn Marino struct c_type_name *type_name;
5990*e4b17023SJohn Marino c_parser_consume_token (parser);
5991*e4b17023SJohn Marino expr_loc = c_parser_peek_token (parser)->location;
5992*e4b17023SJohn Marino type_name = c_parser_type_name (parser);
5993*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
5994*e4b17023SJohn Marino if (type_name == NULL)
5995*e4b17023SJohn Marino {
5996*e4b17023SJohn Marino struct c_expr ret;
5997*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
5998*e4b17023SJohn Marino in_sizeof--;
5999*e4b17023SJohn Marino ret.value = error_mark_node;
6000*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
6001*e4b17023SJohn Marino ret.original_type = NULL;
6002*e4b17023SJohn Marino return ret;
6003*e4b17023SJohn Marino }
6004*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6005*e4b17023SJohn Marino {
6006*e4b17023SJohn Marino expr = c_parser_postfix_expression_after_paren_type (parser,
6007*e4b17023SJohn Marino type_name,
6008*e4b17023SJohn Marino expr_loc);
6009*e4b17023SJohn Marino goto sizeof_expr;
6010*e4b17023SJohn Marino }
6011*e4b17023SJohn Marino /* sizeof ( type-name ). */
6012*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
6013*e4b17023SJohn Marino in_sizeof--;
6014*e4b17023SJohn Marino return c_expr_sizeof_type (expr_loc, type_name);
6015*e4b17023SJohn Marino }
6016*e4b17023SJohn Marino else
6017*e4b17023SJohn Marino {
6018*e4b17023SJohn Marino expr_loc = c_parser_peek_token (parser)->location;
6019*e4b17023SJohn Marino expr = c_parser_unary_expression (parser);
6020*e4b17023SJohn Marino sizeof_expr:
6021*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
6022*e4b17023SJohn Marino in_sizeof--;
6023*e4b17023SJohn Marino mark_exp_read (expr.value);
6024*e4b17023SJohn Marino if (TREE_CODE (expr.value) == COMPONENT_REF
6025*e4b17023SJohn Marino && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
6026*e4b17023SJohn Marino error_at (expr_loc, "%<sizeof%> applied to a bit-field");
6027*e4b17023SJohn Marino return c_expr_sizeof_expr (expr_loc, expr);
6028*e4b17023SJohn Marino }
6029*e4b17023SJohn Marino }
6030*e4b17023SJohn Marino
6031*e4b17023SJohn Marino /* Parse an alignof expression. */
6032*e4b17023SJohn Marino
6033*e4b17023SJohn Marino static struct c_expr
c_parser_alignof_expression(c_parser * parser)6034*e4b17023SJohn Marino c_parser_alignof_expression (c_parser *parser)
6035*e4b17023SJohn Marino {
6036*e4b17023SJohn Marino struct c_expr expr;
6037*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
6038*e4b17023SJohn Marino tree alignof_spelling = c_parser_peek_token (parser)->value;
6039*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
6040*e4b17023SJohn Marino /* A diagnostic is not required for the use of this identifier in
6041*e4b17023SJohn Marino the implementation namespace; only diagnose it for the C11
6042*e4b17023SJohn Marino spelling because of existing code using the other spellings. */
6043*e4b17023SJohn Marino if (!flag_isoc11
6044*e4b17023SJohn Marino && strcmp (IDENTIFIER_POINTER (alignof_spelling), "_Alignof") == 0)
6045*e4b17023SJohn Marino {
6046*e4b17023SJohn Marino if (flag_isoc99)
6047*e4b17023SJohn Marino pedwarn (loc, OPT_pedantic, "ISO C99 does not support %qE",
6048*e4b17023SJohn Marino alignof_spelling);
6049*e4b17023SJohn Marino else
6050*e4b17023SJohn Marino pedwarn (loc, OPT_pedantic, "ISO C90 does not support %qE",
6051*e4b17023SJohn Marino alignof_spelling);
6052*e4b17023SJohn Marino }
6053*e4b17023SJohn Marino c_parser_consume_token (parser);
6054*e4b17023SJohn Marino c_inhibit_evaluation_warnings++;
6055*e4b17023SJohn Marino in_alignof++;
6056*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6057*e4b17023SJohn Marino && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6058*e4b17023SJohn Marino {
6059*e4b17023SJohn Marino /* Either __alignof__ ( type-name ) or __alignof__
6060*e4b17023SJohn Marino unary-expression starting with a compound literal. */
6061*e4b17023SJohn Marino location_t loc;
6062*e4b17023SJohn Marino struct c_type_name *type_name;
6063*e4b17023SJohn Marino struct c_expr ret;
6064*e4b17023SJohn Marino c_parser_consume_token (parser);
6065*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
6066*e4b17023SJohn Marino type_name = c_parser_type_name (parser);
6067*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
6068*e4b17023SJohn Marino if (type_name == NULL)
6069*e4b17023SJohn Marino {
6070*e4b17023SJohn Marino struct c_expr ret;
6071*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
6072*e4b17023SJohn Marino in_alignof--;
6073*e4b17023SJohn Marino ret.value = error_mark_node;
6074*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
6075*e4b17023SJohn Marino ret.original_type = NULL;
6076*e4b17023SJohn Marino return ret;
6077*e4b17023SJohn Marino }
6078*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6079*e4b17023SJohn Marino {
6080*e4b17023SJohn Marino expr = c_parser_postfix_expression_after_paren_type (parser,
6081*e4b17023SJohn Marino type_name,
6082*e4b17023SJohn Marino loc);
6083*e4b17023SJohn Marino goto alignof_expr;
6084*e4b17023SJohn Marino }
6085*e4b17023SJohn Marino /* alignof ( type-name ). */
6086*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
6087*e4b17023SJohn Marino in_alignof--;
6088*e4b17023SJohn Marino ret.value = c_alignof (loc, groktypename (type_name, NULL, NULL));
6089*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
6090*e4b17023SJohn Marino ret.original_type = NULL;
6091*e4b17023SJohn Marino return ret;
6092*e4b17023SJohn Marino }
6093*e4b17023SJohn Marino else
6094*e4b17023SJohn Marino {
6095*e4b17023SJohn Marino struct c_expr ret;
6096*e4b17023SJohn Marino expr = c_parser_unary_expression (parser);
6097*e4b17023SJohn Marino alignof_expr:
6098*e4b17023SJohn Marino mark_exp_read (expr.value);
6099*e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
6100*e4b17023SJohn Marino in_alignof--;
6101*e4b17023SJohn Marino pedwarn (loc, OPT_pedantic, "ISO C does not allow %<%E (expression)%>",
6102*e4b17023SJohn Marino alignof_spelling);
6103*e4b17023SJohn Marino ret.value = c_alignof_expr (loc, expr.value);
6104*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
6105*e4b17023SJohn Marino ret.original_type = NULL;
6106*e4b17023SJohn Marino return ret;
6107*e4b17023SJohn Marino }
6108*e4b17023SJohn Marino }
6109*e4b17023SJohn Marino
6110*e4b17023SJohn Marino /* Helper function to read arguments of builtins which are interfaces
6111*e4b17023SJohn Marino for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
6112*e4b17023SJohn Marino others. The name of the builtin is passed using BNAME parameter.
6113*e4b17023SJohn Marino Function returns true if there were no errors while parsing and
6114*e4b17023SJohn Marino stores the arguments in CEXPR_LIST. */
6115*e4b17023SJohn Marino static bool
c_parser_get_builtin_args(c_parser * parser,const char * bname,VEC (c_expr_t,gc)** ret_cexpr_list)6116*e4b17023SJohn Marino c_parser_get_builtin_args (c_parser *parser, const char *bname,
6117*e4b17023SJohn Marino VEC(c_expr_t,gc) **ret_cexpr_list)
6118*e4b17023SJohn Marino {
6119*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
6120*e4b17023SJohn Marino VEC (c_expr_t,gc) *cexpr_list;
6121*e4b17023SJohn Marino c_expr_t expr;
6122*e4b17023SJohn Marino
6123*e4b17023SJohn Marino *ret_cexpr_list = NULL;
6124*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
6125*e4b17023SJohn Marino {
6126*e4b17023SJohn Marino error_at (loc, "cannot take address of %qs", bname);
6127*e4b17023SJohn Marino return false;
6128*e4b17023SJohn Marino }
6129*e4b17023SJohn Marino
6130*e4b17023SJohn Marino c_parser_consume_token (parser);
6131*e4b17023SJohn Marino
6132*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6133*e4b17023SJohn Marino {
6134*e4b17023SJohn Marino c_parser_consume_token (parser);
6135*e4b17023SJohn Marino return true;
6136*e4b17023SJohn Marino }
6137*e4b17023SJohn Marino
6138*e4b17023SJohn Marino expr = c_parser_expr_no_commas (parser, NULL);
6139*e4b17023SJohn Marino cexpr_list = VEC_alloc (c_expr_t, gc, 1);
6140*e4b17023SJohn Marino C_EXPR_APPEND (cexpr_list, expr);
6141*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_COMMA))
6142*e4b17023SJohn Marino {
6143*e4b17023SJohn Marino c_parser_consume_token (parser);
6144*e4b17023SJohn Marino expr = c_parser_expr_no_commas (parser, NULL);
6145*e4b17023SJohn Marino C_EXPR_APPEND (cexpr_list, expr);
6146*e4b17023SJohn Marino }
6147*e4b17023SJohn Marino
6148*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
6149*e4b17023SJohn Marino return false;
6150*e4b17023SJohn Marino
6151*e4b17023SJohn Marino *ret_cexpr_list = cexpr_list;
6152*e4b17023SJohn Marino return true;
6153*e4b17023SJohn Marino }
6154*e4b17023SJohn Marino
6155*e4b17023SJohn Marino
6156*e4b17023SJohn Marino /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2).
6157*e4b17023SJohn Marino
6158*e4b17023SJohn Marino postfix-expression:
6159*e4b17023SJohn Marino primary-expression
6160*e4b17023SJohn Marino postfix-expression [ expression ]
6161*e4b17023SJohn Marino postfix-expression ( argument-expression-list[opt] )
6162*e4b17023SJohn Marino postfix-expression . identifier
6163*e4b17023SJohn Marino postfix-expression -> identifier
6164*e4b17023SJohn Marino postfix-expression ++
6165*e4b17023SJohn Marino postfix-expression --
6166*e4b17023SJohn Marino ( type-name ) { initializer-list }
6167*e4b17023SJohn Marino ( type-name ) { initializer-list , }
6168*e4b17023SJohn Marino
6169*e4b17023SJohn Marino argument-expression-list:
6170*e4b17023SJohn Marino argument-expression
6171*e4b17023SJohn Marino argument-expression-list , argument-expression
6172*e4b17023SJohn Marino
6173*e4b17023SJohn Marino primary-expression:
6174*e4b17023SJohn Marino identifier
6175*e4b17023SJohn Marino constant
6176*e4b17023SJohn Marino string-literal
6177*e4b17023SJohn Marino ( expression )
6178*e4b17023SJohn Marino
6179*e4b17023SJohn Marino GNU extensions:
6180*e4b17023SJohn Marino
6181*e4b17023SJohn Marino primary-expression:
6182*e4b17023SJohn Marino __func__
6183*e4b17023SJohn Marino (treated as a keyword in GNU C)
6184*e4b17023SJohn Marino __FUNCTION__
6185*e4b17023SJohn Marino __PRETTY_FUNCTION__
6186*e4b17023SJohn Marino ( compound-statement )
6187*e4b17023SJohn Marino __builtin_va_arg ( assignment-expression , type-name )
6188*e4b17023SJohn Marino __builtin_offsetof ( type-name , offsetof-member-designator )
6189*e4b17023SJohn Marino __builtin_choose_expr ( assignment-expression ,
6190*e4b17023SJohn Marino assignment-expression ,
6191*e4b17023SJohn Marino assignment-expression )
6192*e4b17023SJohn Marino __builtin_types_compatible_p ( type-name , type-name )
6193*e4b17023SJohn Marino __builtin_complex ( assignment-expression , assignment-expression )
6194*e4b17023SJohn Marino __builtin_shuffle ( assignment-expression , assignment-expression )
6195*e4b17023SJohn Marino __builtin_shuffle ( assignment-expression ,
6196*e4b17023SJohn Marino assignment-expression ,
6197*e4b17023SJohn Marino assignment-expression, )
6198*e4b17023SJohn Marino
6199*e4b17023SJohn Marino offsetof-member-designator:
6200*e4b17023SJohn Marino identifier
6201*e4b17023SJohn Marino offsetof-member-designator . identifier
6202*e4b17023SJohn Marino offsetof-member-designator [ expression ]
6203*e4b17023SJohn Marino
6204*e4b17023SJohn Marino Objective-C:
6205*e4b17023SJohn Marino
6206*e4b17023SJohn Marino primary-expression:
6207*e4b17023SJohn Marino [ objc-receiver objc-message-args ]
6208*e4b17023SJohn Marino @selector ( objc-selector-arg )
6209*e4b17023SJohn Marino @protocol ( identifier )
6210*e4b17023SJohn Marino @encode ( type-name )
6211*e4b17023SJohn Marino objc-string-literal
6212*e4b17023SJohn Marino Classname . identifier
6213*e4b17023SJohn Marino */
6214*e4b17023SJohn Marino
6215*e4b17023SJohn Marino static struct c_expr
c_parser_postfix_expression(c_parser * parser)6216*e4b17023SJohn Marino c_parser_postfix_expression (c_parser *parser)
6217*e4b17023SJohn Marino {
6218*e4b17023SJohn Marino struct c_expr expr, e1;
6219*e4b17023SJohn Marino struct c_type_name *t1, *t2;
6220*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;;
6221*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6222*e4b17023SJohn Marino expr.original_type = NULL;
6223*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
6224*e4b17023SJohn Marino {
6225*e4b17023SJohn Marino case CPP_NUMBER:
6226*e4b17023SJohn Marino expr.value = c_parser_peek_token (parser)->value;
6227*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
6228*e4b17023SJohn Marino c_parser_consume_token (parser);
6229*e4b17023SJohn Marino if (TREE_CODE (expr.value) == FIXED_CST
6230*e4b17023SJohn Marino && !targetm.fixed_point_supported_p ())
6231*e4b17023SJohn Marino {
6232*e4b17023SJohn Marino error_at (loc, "fixed-point types not supported for this target");
6233*e4b17023SJohn Marino expr.value = error_mark_node;
6234*e4b17023SJohn Marino }
6235*e4b17023SJohn Marino break;
6236*e4b17023SJohn Marino case CPP_CHAR:
6237*e4b17023SJohn Marino case CPP_CHAR16:
6238*e4b17023SJohn Marino case CPP_CHAR32:
6239*e4b17023SJohn Marino case CPP_WCHAR:
6240*e4b17023SJohn Marino expr.value = c_parser_peek_token (parser)->value;
6241*e4b17023SJohn Marino c_parser_consume_token (parser);
6242*e4b17023SJohn Marino break;
6243*e4b17023SJohn Marino case CPP_STRING:
6244*e4b17023SJohn Marino case CPP_STRING16:
6245*e4b17023SJohn Marino case CPP_STRING32:
6246*e4b17023SJohn Marino case CPP_WSTRING:
6247*e4b17023SJohn Marino case CPP_UTF8STRING:
6248*e4b17023SJohn Marino expr.value = c_parser_peek_token (parser)->value;
6249*e4b17023SJohn Marino expr.original_code = STRING_CST;
6250*e4b17023SJohn Marino c_parser_consume_token (parser);
6251*e4b17023SJohn Marino break;
6252*e4b17023SJohn Marino case CPP_OBJC_STRING:
6253*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
6254*e4b17023SJohn Marino expr.value
6255*e4b17023SJohn Marino = objc_build_string_object (c_parser_peek_token (parser)->value);
6256*e4b17023SJohn Marino c_parser_consume_token (parser);
6257*e4b17023SJohn Marino break;
6258*e4b17023SJohn Marino case CPP_NAME:
6259*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->id_kind)
6260*e4b17023SJohn Marino {
6261*e4b17023SJohn Marino case C_ID_ID:
6262*e4b17023SJohn Marino {
6263*e4b17023SJohn Marino tree id = c_parser_peek_token (parser)->value;
6264*e4b17023SJohn Marino c_parser_consume_token (parser);
6265*e4b17023SJohn Marino expr.value = build_external_ref (loc, id,
6266*e4b17023SJohn Marino (c_parser_peek_token (parser)->type
6267*e4b17023SJohn Marino == CPP_OPEN_PAREN),
6268*e4b17023SJohn Marino &expr.original_type);
6269*e4b17023SJohn Marino break;
6270*e4b17023SJohn Marino }
6271*e4b17023SJohn Marino case C_ID_CLASSNAME:
6272*e4b17023SJohn Marino {
6273*e4b17023SJohn Marino /* Here we parse the Objective-C 2.0 Class.name dot
6274*e4b17023SJohn Marino syntax. */
6275*e4b17023SJohn Marino tree class_name = c_parser_peek_token (parser)->value;
6276*e4b17023SJohn Marino tree component;
6277*e4b17023SJohn Marino c_parser_consume_token (parser);
6278*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
6279*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
6280*e4b17023SJohn Marino {
6281*e4b17023SJohn Marino expr.value = error_mark_node;
6282*e4b17023SJohn Marino break;
6283*e4b17023SJohn Marino }
6284*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
6285*e4b17023SJohn Marino {
6286*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
6287*e4b17023SJohn Marino expr.value = error_mark_node;
6288*e4b17023SJohn Marino break;
6289*e4b17023SJohn Marino }
6290*e4b17023SJohn Marino component = c_parser_peek_token (parser)->value;
6291*e4b17023SJohn Marino c_parser_consume_token (parser);
6292*e4b17023SJohn Marino expr.value = objc_build_class_component_ref (class_name,
6293*e4b17023SJohn Marino component);
6294*e4b17023SJohn Marino break;
6295*e4b17023SJohn Marino }
6296*e4b17023SJohn Marino default:
6297*e4b17023SJohn Marino c_parser_error (parser, "expected expression");
6298*e4b17023SJohn Marino expr.value = error_mark_node;
6299*e4b17023SJohn Marino break;
6300*e4b17023SJohn Marino }
6301*e4b17023SJohn Marino break;
6302*e4b17023SJohn Marino case CPP_OPEN_PAREN:
6303*e4b17023SJohn Marino /* A parenthesized expression, statement expression or compound
6304*e4b17023SJohn Marino literal. */
6305*e4b17023SJohn Marino if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
6306*e4b17023SJohn Marino {
6307*e4b17023SJohn Marino /* A statement expression. */
6308*e4b17023SJohn Marino tree stmt;
6309*e4b17023SJohn Marino location_t brace_loc;
6310*e4b17023SJohn Marino c_parser_consume_token (parser);
6311*e4b17023SJohn Marino brace_loc = c_parser_peek_token (parser)->location;
6312*e4b17023SJohn Marino c_parser_consume_token (parser);
6313*e4b17023SJohn Marino if (!building_stmt_list_p ())
6314*e4b17023SJohn Marino {
6315*e4b17023SJohn Marino error_at (loc, "braced-group within expression allowed "
6316*e4b17023SJohn Marino "only inside a function");
6317*e4b17023SJohn Marino parser->error = true;
6318*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
6319*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6320*e4b17023SJohn Marino expr.value = error_mark_node;
6321*e4b17023SJohn Marino break;
6322*e4b17023SJohn Marino }
6323*e4b17023SJohn Marino stmt = c_begin_stmt_expr ();
6324*e4b17023SJohn Marino c_parser_compound_statement_nostart (parser);
6325*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6326*e4b17023SJohn Marino "expected %<)%>");
6327*e4b17023SJohn Marino pedwarn (loc, OPT_pedantic,
6328*e4b17023SJohn Marino "ISO C forbids braced-groups within expressions");
6329*e4b17023SJohn Marino expr.value = c_finish_stmt_expr (brace_loc, stmt);
6330*e4b17023SJohn Marino mark_exp_read (expr.value);
6331*e4b17023SJohn Marino }
6332*e4b17023SJohn Marino else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6333*e4b17023SJohn Marino {
6334*e4b17023SJohn Marino /* A compound literal. ??? Can we actually get here rather
6335*e4b17023SJohn Marino than going directly to
6336*e4b17023SJohn Marino c_parser_postfix_expression_after_paren_type from
6337*e4b17023SJohn Marino elsewhere? */
6338*e4b17023SJohn Marino location_t loc;
6339*e4b17023SJohn Marino struct c_type_name *type_name;
6340*e4b17023SJohn Marino c_parser_consume_token (parser);
6341*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
6342*e4b17023SJohn Marino type_name = c_parser_type_name (parser);
6343*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6344*e4b17023SJohn Marino "expected %<)%>");
6345*e4b17023SJohn Marino if (type_name == NULL)
6346*e4b17023SJohn Marino {
6347*e4b17023SJohn Marino expr.value = error_mark_node;
6348*e4b17023SJohn Marino }
6349*e4b17023SJohn Marino else
6350*e4b17023SJohn Marino expr = c_parser_postfix_expression_after_paren_type (parser,
6351*e4b17023SJohn Marino type_name,
6352*e4b17023SJohn Marino loc);
6353*e4b17023SJohn Marino }
6354*e4b17023SJohn Marino else
6355*e4b17023SJohn Marino {
6356*e4b17023SJohn Marino /* A parenthesized expression. */
6357*e4b17023SJohn Marino c_parser_consume_token (parser);
6358*e4b17023SJohn Marino expr = c_parser_expression (parser);
6359*e4b17023SJohn Marino if (TREE_CODE (expr.value) == MODIFY_EXPR)
6360*e4b17023SJohn Marino TREE_NO_WARNING (expr.value) = 1;
6361*e4b17023SJohn Marino if (expr.original_code != C_MAYBE_CONST_EXPR)
6362*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6363*e4b17023SJohn Marino /* Don't change EXPR.ORIGINAL_TYPE. */
6364*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6365*e4b17023SJohn Marino "expected %<)%>");
6366*e4b17023SJohn Marino }
6367*e4b17023SJohn Marino break;
6368*e4b17023SJohn Marino case CPP_KEYWORD:
6369*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->keyword)
6370*e4b17023SJohn Marino {
6371*e4b17023SJohn Marino case RID_FUNCTION_NAME:
6372*e4b17023SJohn Marino case RID_PRETTY_FUNCTION_NAME:
6373*e4b17023SJohn Marino case RID_C99_FUNCTION_NAME:
6374*e4b17023SJohn Marino expr.value = fname_decl (loc,
6375*e4b17023SJohn Marino c_parser_peek_token (parser)->keyword,
6376*e4b17023SJohn Marino c_parser_peek_token (parser)->value);
6377*e4b17023SJohn Marino c_parser_consume_token (parser);
6378*e4b17023SJohn Marino break;
6379*e4b17023SJohn Marino case RID_VA_ARG:
6380*e4b17023SJohn Marino c_parser_consume_token (parser);
6381*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6382*e4b17023SJohn Marino {
6383*e4b17023SJohn Marino expr.value = error_mark_node;
6384*e4b17023SJohn Marino break;
6385*e4b17023SJohn Marino }
6386*e4b17023SJohn Marino e1 = c_parser_expr_no_commas (parser, NULL);
6387*e4b17023SJohn Marino mark_exp_read (e1.value);
6388*e4b17023SJohn Marino e1.value = c_fully_fold (e1.value, false, NULL);
6389*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
6390*e4b17023SJohn Marino {
6391*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6392*e4b17023SJohn Marino expr.value = error_mark_node;
6393*e4b17023SJohn Marino break;
6394*e4b17023SJohn Marino }
6395*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
6396*e4b17023SJohn Marino t1 = c_parser_type_name (parser);
6397*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6398*e4b17023SJohn Marino "expected %<)%>");
6399*e4b17023SJohn Marino if (t1 == NULL)
6400*e4b17023SJohn Marino {
6401*e4b17023SJohn Marino expr.value = error_mark_node;
6402*e4b17023SJohn Marino }
6403*e4b17023SJohn Marino else
6404*e4b17023SJohn Marino {
6405*e4b17023SJohn Marino tree type_expr = NULL_TREE;
6406*e4b17023SJohn Marino expr.value = c_build_va_arg (loc, e1.value,
6407*e4b17023SJohn Marino groktypename (t1, &type_expr, NULL));
6408*e4b17023SJohn Marino if (type_expr)
6409*e4b17023SJohn Marino {
6410*e4b17023SJohn Marino expr.value = build2 (C_MAYBE_CONST_EXPR,
6411*e4b17023SJohn Marino TREE_TYPE (expr.value), type_expr,
6412*e4b17023SJohn Marino expr.value);
6413*e4b17023SJohn Marino C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
6414*e4b17023SJohn Marino }
6415*e4b17023SJohn Marino }
6416*e4b17023SJohn Marino break;
6417*e4b17023SJohn Marino case RID_OFFSETOF:
6418*e4b17023SJohn Marino c_parser_consume_token (parser);
6419*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6420*e4b17023SJohn Marino {
6421*e4b17023SJohn Marino expr.value = error_mark_node;
6422*e4b17023SJohn Marino break;
6423*e4b17023SJohn Marino }
6424*e4b17023SJohn Marino t1 = c_parser_type_name (parser);
6425*e4b17023SJohn Marino if (t1 == NULL)
6426*e4b17023SJohn Marino parser->error = true;
6427*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
6428*e4b17023SJohn Marino gcc_assert (parser->error);
6429*e4b17023SJohn Marino if (parser->error)
6430*e4b17023SJohn Marino {
6431*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6432*e4b17023SJohn Marino expr.value = error_mark_node;
6433*e4b17023SJohn Marino break;
6434*e4b17023SJohn Marino }
6435*e4b17023SJohn Marino
6436*e4b17023SJohn Marino {
6437*e4b17023SJohn Marino tree type = groktypename (t1, NULL, NULL);
6438*e4b17023SJohn Marino tree offsetof_ref;
6439*e4b17023SJohn Marino if (type == error_mark_node)
6440*e4b17023SJohn Marino offsetof_ref = error_mark_node;
6441*e4b17023SJohn Marino else
6442*e4b17023SJohn Marino {
6443*e4b17023SJohn Marino offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
6444*e4b17023SJohn Marino SET_EXPR_LOCATION (offsetof_ref, loc);
6445*e4b17023SJohn Marino }
6446*e4b17023SJohn Marino /* Parse the second argument to __builtin_offsetof. We
6447*e4b17023SJohn Marino must have one identifier, and beyond that we want to
6448*e4b17023SJohn Marino accept sub structure and sub array references. */
6449*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
6450*e4b17023SJohn Marino {
6451*e4b17023SJohn Marino offsetof_ref = build_component_ref
6452*e4b17023SJohn Marino (loc, offsetof_ref, c_parser_peek_token (parser)->value);
6453*e4b17023SJohn Marino c_parser_consume_token (parser);
6454*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_DOT)
6455*e4b17023SJohn Marino || c_parser_next_token_is (parser,
6456*e4b17023SJohn Marino CPP_OPEN_SQUARE)
6457*e4b17023SJohn Marino || c_parser_next_token_is (parser,
6458*e4b17023SJohn Marino CPP_DEREF))
6459*e4b17023SJohn Marino {
6460*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_DEREF))
6461*e4b17023SJohn Marino {
6462*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
6463*e4b17023SJohn Marino offsetof_ref = build_array_ref (loc,
6464*e4b17023SJohn Marino offsetof_ref,
6465*e4b17023SJohn Marino integer_zero_node);
6466*e4b17023SJohn Marino goto do_dot;
6467*e4b17023SJohn Marino }
6468*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_DOT))
6469*e4b17023SJohn Marino {
6470*e4b17023SJohn Marino do_dot:
6471*e4b17023SJohn Marino c_parser_consume_token (parser);
6472*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser,
6473*e4b17023SJohn Marino CPP_NAME))
6474*e4b17023SJohn Marino {
6475*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
6476*e4b17023SJohn Marino break;
6477*e4b17023SJohn Marino }
6478*e4b17023SJohn Marino offsetof_ref = build_component_ref
6479*e4b17023SJohn Marino (loc, offsetof_ref,
6480*e4b17023SJohn Marino c_parser_peek_token (parser)->value);
6481*e4b17023SJohn Marino c_parser_consume_token (parser);
6482*e4b17023SJohn Marino }
6483*e4b17023SJohn Marino else
6484*e4b17023SJohn Marino {
6485*e4b17023SJohn Marino tree idx;
6486*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
6487*e4b17023SJohn Marino c_parser_consume_token (parser);
6488*e4b17023SJohn Marino idx = c_parser_expression (parser).value;
6489*e4b17023SJohn Marino idx = c_fully_fold (idx, false, NULL);
6490*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6491*e4b17023SJohn Marino "expected %<]%>");
6492*e4b17023SJohn Marino offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
6493*e4b17023SJohn Marino }
6494*e4b17023SJohn Marino }
6495*e4b17023SJohn Marino }
6496*e4b17023SJohn Marino else
6497*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
6498*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6499*e4b17023SJohn Marino "expected %<)%>");
6500*e4b17023SJohn Marino expr.value = fold_offsetof (offsetof_ref);
6501*e4b17023SJohn Marino }
6502*e4b17023SJohn Marino break;
6503*e4b17023SJohn Marino case RID_CHOOSE_EXPR:
6504*e4b17023SJohn Marino {
6505*e4b17023SJohn Marino VEC (c_expr_t, gc) *cexpr_list;
6506*e4b17023SJohn Marino c_expr_t *e1_p, *e2_p, *e3_p;
6507*e4b17023SJohn Marino tree c;
6508*e4b17023SJohn Marino
6509*e4b17023SJohn Marino c_parser_consume_token (parser);
6510*e4b17023SJohn Marino if (!c_parser_get_builtin_args (parser,
6511*e4b17023SJohn Marino "__builtin_choose_expr",
6512*e4b17023SJohn Marino &cexpr_list))
6513*e4b17023SJohn Marino {
6514*e4b17023SJohn Marino expr.value = error_mark_node;
6515*e4b17023SJohn Marino break;
6516*e4b17023SJohn Marino }
6517*e4b17023SJohn Marino
6518*e4b17023SJohn Marino if (VEC_length (c_expr_t, cexpr_list) != 3)
6519*e4b17023SJohn Marino {
6520*e4b17023SJohn Marino error_at (loc, "wrong number of arguments to "
6521*e4b17023SJohn Marino "%<__builtin_choose_expr%>");
6522*e4b17023SJohn Marino expr.value = error_mark_node;
6523*e4b17023SJohn Marino break;
6524*e4b17023SJohn Marino }
6525*e4b17023SJohn Marino
6526*e4b17023SJohn Marino e1_p = VEC_index (c_expr_t, cexpr_list, 0);
6527*e4b17023SJohn Marino e2_p = VEC_index (c_expr_t, cexpr_list, 1);
6528*e4b17023SJohn Marino e3_p = VEC_index (c_expr_t, cexpr_list, 2);
6529*e4b17023SJohn Marino
6530*e4b17023SJohn Marino c = e1_p->value;
6531*e4b17023SJohn Marino mark_exp_read (e2_p->value);
6532*e4b17023SJohn Marino mark_exp_read (e3_p->value);
6533*e4b17023SJohn Marino if (TREE_CODE (c) != INTEGER_CST
6534*e4b17023SJohn Marino || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
6535*e4b17023SJohn Marino error_at (loc,
6536*e4b17023SJohn Marino "first argument to %<__builtin_choose_expr%> not"
6537*e4b17023SJohn Marino " a constant");
6538*e4b17023SJohn Marino constant_expression_warning (c);
6539*e4b17023SJohn Marino expr = integer_zerop (c) ? *e3_p : *e2_p;
6540*e4b17023SJohn Marino break;
6541*e4b17023SJohn Marino }
6542*e4b17023SJohn Marino case RID_TYPES_COMPATIBLE_P:
6543*e4b17023SJohn Marino c_parser_consume_token (parser);
6544*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6545*e4b17023SJohn Marino {
6546*e4b17023SJohn Marino expr.value = error_mark_node;
6547*e4b17023SJohn Marino break;
6548*e4b17023SJohn Marino }
6549*e4b17023SJohn Marino t1 = c_parser_type_name (parser);
6550*e4b17023SJohn Marino if (t1 == NULL)
6551*e4b17023SJohn Marino {
6552*e4b17023SJohn Marino expr.value = error_mark_node;
6553*e4b17023SJohn Marino break;
6554*e4b17023SJohn Marino }
6555*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
6556*e4b17023SJohn Marino {
6557*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6558*e4b17023SJohn Marino expr.value = error_mark_node;
6559*e4b17023SJohn Marino break;
6560*e4b17023SJohn Marino }
6561*e4b17023SJohn Marino t2 = c_parser_type_name (parser);
6562*e4b17023SJohn Marino if (t2 == NULL)
6563*e4b17023SJohn Marino {
6564*e4b17023SJohn Marino expr.value = error_mark_node;
6565*e4b17023SJohn Marino break;
6566*e4b17023SJohn Marino }
6567*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6568*e4b17023SJohn Marino "expected %<)%>");
6569*e4b17023SJohn Marino {
6570*e4b17023SJohn Marino tree e1, e2;
6571*e4b17023SJohn Marino e1 = groktypename (t1, NULL, NULL);
6572*e4b17023SJohn Marino e2 = groktypename (t2, NULL, NULL);
6573*e4b17023SJohn Marino if (e1 == error_mark_node || e2 == error_mark_node)
6574*e4b17023SJohn Marino {
6575*e4b17023SJohn Marino expr.value = error_mark_node;
6576*e4b17023SJohn Marino break;
6577*e4b17023SJohn Marino }
6578*e4b17023SJohn Marino
6579*e4b17023SJohn Marino e1 = TYPE_MAIN_VARIANT (e1);
6580*e4b17023SJohn Marino e2 = TYPE_MAIN_VARIANT (e2);
6581*e4b17023SJohn Marino
6582*e4b17023SJohn Marino expr.value
6583*e4b17023SJohn Marino = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
6584*e4b17023SJohn Marino }
6585*e4b17023SJohn Marino break;
6586*e4b17023SJohn Marino case RID_BUILTIN_COMPLEX:
6587*e4b17023SJohn Marino {
6588*e4b17023SJohn Marino VEC(c_expr_t, gc) *cexpr_list;
6589*e4b17023SJohn Marino c_expr_t *e1_p, *e2_p;
6590*e4b17023SJohn Marino
6591*e4b17023SJohn Marino c_parser_consume_token (parser);
6592*e4b17023SJohn Marino if (!c_parser_get_builtin_args (parser,
6593*e4b17023SJohn Marino "__builtin_complex",
6594*e4b17023SJohn Marino &cexpr_list))
6595*e4b17023SJohn Marino {
6596*e4b17023SJohn Marino expr.value = error_mark_node;
6597*e4b17023SJohn Marino break;
6598*e4b17023SJohn Marino }
6599*e4b17023SJohn Marino
6600*e4b17023SJohn Marino if (VEC_length (c_expr_t, cexpr_list) != 2)
6601*e4b17023SJohn Marino {
6602*e4b17023SJohn Marino error_at (loc, "wrong number of arguments to "
6603*e4b17023SJohn Marino "%<__builtin_complex%>");
6604*e4b17023SJohn Marino expr.value = error_mark_node;
6605*e4b17023SJohn Marino break;
6606*e4b17023SJohn Marino }
6607*e4b17023SJohn Marino
6608*e4b17023SJohn Marino e1_p = VEC_index (c_expr_t, cexpr_list, 0);
6609*e4b17023SJohn Marino e2_p = VEC_index (c_expr_t, cexpr_list, 1);
6610*e4b17023SJohn Marino
6611*e4b17023SJohn Marino mark_exp_read (e1_p->value);
6612*e4b17023SJohn Marino if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
6613*e4b17023SJohn Marino e1_p->value = convert (TREE_TYPE (e1_p->value),
6614*e4b17023SJohn Marino TREE_OPERAND (e1_p->value, 0));
6615*e4b17023SJohn Marino mark_exp_read (e2_p->value);
6616*e4b17023SJohn Marino if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
6617*e4b17023SJohn Marino e2_p->value = convert (TREE_TYPE (e2_p->value),
6618*e4b17023SJohn Marino TREE_OPERAND (e2_p->value, 0));
6619*e4b17023SJohn Marino if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
6620*e4b17023SJohn Marino || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
6621*e4b17023SJohn Marino || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
6622*e4b17023SJohn Marino || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
6623*e4b17023SJohn Marino {
6624*e4b17023SJohn Marino error_at (loc, "%<__builtin_complex%> operand "
6625*e4b17023SJohn Marino "not of real binary floating-point type");
6626*e4b17023SJohn Marino expr.value = error_mark_node;
6627*e4b17023SJohn Marino break;
6628*e4b17023SJohn Marino }
6629*e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
6630*e4b17023SJohn Marino != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
6631*e4b17023SJohn Marino {
6632*e4b17023SJohn Marino error_at (loc,
6633*e4b17023SJohn Marino "%<__builtin_complex%> operands of different types");
6634*e4b17023SJohn Marino expr.value = error_mark_node;
6635*e4b17023SJohn Marino break;
6636*e4b17023SJohn Marino }
6637*e4b17023SJohn Marino if (!flag_isoc99)
6638*e4b17023SJohn Marino pedwarn (loc, OPT_pedantic,
6639*e4b17023SJohn Marino "ISO C90 does not support complex types");
6640*e4b17023SJohn Marino expr.value = build2 (COMPLEX_EXPR,
6641*e4b17023SJohn Marino build_complex_type
6642*e4b17023SJohn Marino (TYPE_MAIN_VARIANT
6643*e4b17023SJohn Marino (TREE_TYPE (e1_p->value))),
6644*e4b17023SJohn Marino e1_p->value, e2_p->value);
6645*e4b17023SJohn Marino break;
6646*e4b17023SJohn Marino }
6647*e4b17023SJohn Marino case RID_BUILTIN_SHUFFLE:
6648*e4b17023SJohn Marino {
6649*e4b17023SJohn Marino VEC(c_expr_t,gc) *cexpr_list;
6650*e4b17023SJohn Marino unsigned int i;
6651*e4b17023SJohn Marino c_expr_t *p;
6652*e4b17023SJohn Marino
6653*e4b17023SJohn Marino c_parser_consume_token (parser);
6654*e4b17023SJohn Marino if (!c_parser_get_builtin_args (parser,
6655*e4b17023SJohn Marino "__builtin_shuffle",
6656*e4b17023SJohn Marino &cexpr_list))
6657*e4b17023SJohn Marino {
6658*e4b17023SJohn Marino expr.value = error_mark_node;
6659*e4b17023SJohn Marino break;
6660*e4b17023SJohn Marino }
6661*e4b17023SJohn Marino
6662*e4b17023SJohn Marino FOR_EACH_VEC_ELT (c_expr_t, cexpr_list, i, p)
6663*e4b17023SJohn Marino mark_exp_read (p->value);
6664*e4b17023SJohn Marino
6665*e4b17023SJohn Marino if (VEC_length (c_expr_t, cexpr_list) == 2)
6666*e4b17023SJohn Marino expr.value =
6667*e4b17023SJohn Marino c_build_vec_perm_expr
6668*e4b17023SJohn Marino (loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
6669*e4b17023SJohn Marino NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1)->value);
6670*e4b17023SJohn Marino
6671*e4b17023SJohn Marino else if (VEC_length (c_expr_t, cexpr_list) == 3)
6672*e4b17023SJohn Marino expr.value =
6673*e4b17023SJohn Marino c_build_vec_perm_expr
6674*e4b17023SJohn Marino (loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
6675*e4b17023SJohn Marino VEC_index (c_expr_t, cexpr_list, 1)->value,
6676*e4b17023SJohn Marino VEC_index (c_expr_t, cexpr_list, 2)->value);
6677*e4b17023SJohn Marino else
6678*e4b17023SJohn Marino {
6679*e4b17023SJohn Marino error_at (loc, "wrong number of arguments to "
6680*e4b17023SJohn Marino "%<__builtin_shuffle%>");
6681*e4b17023SJohn Marino expr.value = error_mark_node;
6682*e4b17023SJohn Marino }
6683*e4b17023SJohn Marino break;
6684*e4b17023SJohn Marino }
6685*e4b17023SJohn Marino case RID_AT_SELECTOR:
6686*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
6687*e4b17023SJohn Marino c_parser_consume_token (parser);
6688*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6689*e4b17023SJohn Marino {
6690*e4b17023SJohn Marino expr.value = error_mark_node;
6691*e4b17023SJohn Marino break;
6692*e4b17023SJohn Marino }
6693*e4b17023SJohn Marino {
6694*e4b17023SJohn Marino tree sel = c_parser_objc_selector_arg (parser);
6695*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6696*e4b17023SJohn Marino "expected %<)%>");
6697*e4b17023SJohn Marino expr.value = objc_build_selector_expr (loc, sel);
6698*e4b17023SJohn Marino }
6699*e4b17023SJohn Marino break;
6700*e4b17023SJohn Marino case RID_AT_PROTOCOL:
6701*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
6702*e4b17023SJohn Marino c_parser_consume_token (parser);
6703*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6704*e4b17023SJohn Marino {
6705*e4b17023SJohn Marino expr.value = error_mark_node;
6706*e4b17023SJohn Marino break;
6707*e4b17023SJohn Marino }
6708*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
6709*e4b17023SJohn Marino {
6710*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
6711*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6712*e4b17023SJohn Marino expr.value = error_mark_node;
6713*e4b17023SJohn Marino break;
6714*e4b17023SJohn Marino }
6715*e4b17023SJohn Marino {
6716*e4b17023SJohn Marino tree id = c_parser_peek_token (parser)->value;
6717*e4b17023SJohn Marino c_parser_consume_token (parser);
6718*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6719*e4b17023SJohn Marino "expected %<)%>");
6720*e4b17023SJohn Marino expr.value = objc_build_protocol_expr (id);
6721*e4b17023SJohn Marino }
6722*e4b17023SJohn Marino break;
6723*e4b17023SJohn Marino case RID_AT_ENCODE:
6724*e4b17023SJohn Marino /* Extension to support C-structures in the archiver. */
6725*e4b17023SJohn Marino gcc_assert (c_dialect_objc ());
6726*e4b17023SJohn Marino c_parser_consume_token (parser);
6727*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
6728*e4b17023SJohn Marino {
6729*e4b17023SJohn Marino expr.value = error_mark_node;
6730*e4b17023SJohn Marino break;
6731*e4b17023SJohn Marino }
6732*e4b17023SJohn Marino t1 = c_parser_type_name (parser);
6733*e4b17023SJohn Marino if (t1 == NULL)
6734*e4b17023SJohn Marino {
6735*e4b17023SJohn Marino expr.value = error_mark_node;
6736*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6737*e4b17023SJohn Marino break;
6738*e4b17023SJohn Marino }
6739*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6740*e4b17023SJohn Marino "expected %<)%>");
6741*e4b17023SJohn Marino {
6742*e4b17023SJohn Marino tree type = groktypename (t1, NULL, NULL);
6743*e4b17023SJohn Marino expr.value = objc_build_encode_expr (type);
6744*e4b17023SJohn Marino }
6745*e4b17023SJohn Marino break;
6746*e4b17023SJohn Marino default:
6747*e4b17023SJohn Marino c_parser_error (parser, "expected expression");
6748*e4b17023SJohn Marino expr.value = error_mark_node;
6749*e4b17023SJohn Marino break;
6750*e4b17023SJohn Marino }
6751*e4b17023SJohn Marino break;
6752*e4b17023SJohn Marino case CPP_OPEN_SQUARE:
6753*e4b17023SJohn Marino if (c_dialect_objc ())
6754*e4b17023SJohn Marino {
6755*e4b17023SJohn Marino tree receiver, args;
6756*e4b17023SJohn Marino c_parser_consume_token (parser);
6757*e4b17023SJohn Marino receiver = c_parser_objc_receiver (parser);
6758*e4b17023SJohn Marino args = c_parser_objc_message_args (parser);
6759*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6760*e4b17023SJohn Marino "expected %<]%>");
6761*e4b17023SJohn Marino expr.value = objc_build_message_expr (receiver, args);
6762*e4b17023SJohn Marino break;
6763*e4b17023SJohn Marino }
6764*e4b17023SJohn Marino /* Else fall through to report error. */
6765*e4b17023SJohn Marino default:
6766*e4b17023SJohn Marino c_parser_error (parser, "expected expression");
6767*e4b17023SJohn Marino expr.value = error_mark_node;
6768*e4b17023SJohn Marino break;
6769*e4b17023SJohn Marino }
6770*e4b17023SJohn Marino return c_parser_postfix_expression_after_primary (parser, loc, expr);
6771*e4b17023SJohn Marino }
6772*e4b17023SJohn Marino
6773*e4b17023SJohn Marino /* Parse a postfix expression after a parenthesized type name: the
6774*e4b17023SJohn Marino brace-enclosed initializer of a compound literal, possibly followed
6775*e4b17023SJohn Marino by some postfix operators. This is separate because it is not
6776*e4b17023SJohn Marino possible to tell until after the type name whether a cast
6777*e4b17023SJohn Marino expression has a cast or a compound literal, or whether the operand
6778*e4b17023SJohn Marino of sizeof is a parenthesized type name or starts with a compound
6779*e4b17023SJohn Marino literal. TYPE_LOC is the location where TYPE_NAME starts--the
6780*e4b17023SJohn Marino location of the first token after the parentheses around the type
6781*e4b17023SJohn Marino name. */
6782*e4b17023SJohn Marino
6783*e4b17023SJohn Marino static struct c_expr
c_parser_postfix_expression_after_paren_type(c_parser * parser,struct c_type_name * type_name,location_t type_loc)6784*e4b17023SJohn Marino c_parser_postfix_expression_after_paren_type (c_parser *parser,
6785*e4b17023SJohn Marino struct c_type_name *type_name,
6786*e4b17023SJohn Marino location_t type_loc)
6787*e4b17023SJohn Marino {
6788*e4b17023SJohn Marino tree type;
6789*e4b17023SJohn Marino struct c_expr init;
6790*e4b17023SJohn Marino bool non_const;
6791*e4b17023SJohn Marino struct c_expr expr;
6792*e4b17023SJohn Marino location_t start_loc;
6793*e4b17023SJohn Marino tree type_expr = NULL_TREE;
6794*e4b17023SJohn Marino bool type_expr_const = true;
6795*e4b17023SJohn Marino check_compound_literal_type (type_loc, type_name);
6796*e4b17023SJohn Marino start_init (NULL_TREE, NULL, 0);
6797*e4b17023SJohn Marino type = groktypename (type_name, &type_expr, &type_expr_const);
6798*e4b17023SJohn Marino start_loc = c_parser_peek_token (parser)->location;
6799*e4b17023SJohn Marino if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
6800*e4b17023SJohn Marino {
6801*e4b17023SJohn Marino error_at (type_loc, "compound literal has variable size");
6802*e4b17023SJohn Marino type = error_mark_node;
6803*e4b17023SJohn Marino }
6804*e4b17023SJohn Marino init = c_parser_braced_init (parser, type, false);
6805*e4b17023SJohn Marino finish_init ();
6806*e4b17023SJohn Marino maybe_warn_string_init (type, init);
6807*e4b17023SJohn Marino
6808*e4b17023SJohn Marino if (type != error_mark_node
6809*e4b17023SJohn Marino && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
6810*e4b17023SJohn Marino && current_function_decl)
6811*e4b17023SJohn Marino {
6812*e4b17023SJohn Marino error ("compound literal qualified by address-space qualifier");
6813*e4b17023SJohn Marino type = error_mark_node;
6814*e4b17023SJohn Marino }
6815*e4b17023SJohn Marino
6816*e4b17023SJohn Marino if (!flag_isoc99)
6817*e4b17023SJohn Marino pedwarn (start_loc, OPT_pedantic, "ISO C90 forbids compound literals");
6818*e4b17023SJohn Marino non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
6819*e4b17023SJohn Marino ? CONSTRUCTOR_NON_CONST (init.value)
6820*e4b17023SJohn Marino : init.original_code == C_MAYBE_CONST_EXPR);
6821*e4b17023SJohn Marino non_const |= !type_expr_const;
6822*e4b17023SJohn Marino expr.value = build_compound_literal (start_loc, type, init.value, non_const);
6823*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6824*e4b17023SJohn Marino expr.original_type = NULL;
6825*e4b17023SJohn Marino if (type_expr)
6826*e4b17023SJohn Marino {
6827*e4b17023SJohn Marino if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
6828*e4b17023SJohn Marino {
6829*e4b17023SJohn Marino gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
6830*e4b17023SJohn Marino C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
6831*e4b17023SJohn Marino }
6832*e4b17023SJohn Marino else
6833*e4b17023SJohn Marino {
6834*e4b17023SJohn Marino gcc_assert (!non_const);
6835*e4b17023SJohn Marino expr.value = build2 (C_MAYBE_CONST_EXPR, type,
6836*e4b17023SJohn Marino type_expr, expr.value);
6837*e4b17023SJohn Marino }
6838*e4b17023SJohn Marino }
6839*e4b17023SJohn Marino return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
6840*e4b17023SJohn Marino }
6841*e4b17023SJohn Marino
6842*e4b17023SJohn Marino /* Parse a postfix expression after the initial primary or compound
6843*e4b17023SJohn Marino literal; that is, parse a series of postfix operators.
6844*e4b17023SJohn Marino
6845*e4b17023SJohn Marino EXPR_LOC is the location of the primary expression. */
6846*e4b17023SJohn Marino
6847*e4b17023SJohn Marino static struct c_expr
c_parser_postfix_expression_after_primary(c_parser * parser,location_t expr_loc,struct c_expr expr)6848*e4b17023SJohn Marino c_parser_postfix_expression_after_primary (c_parser *parser,
6849*e4b17023SJohn Marino location_t expr_loc,
6850*e4b17023SJohn Marino struct c_expr expr)
6851*e4b17023SJohn Marino {
6852*e4b17023SJohn Marino struct c_expr orig_expr;
6853*e4b17023SJohn Marino tree ident, idx;
6854*e4b17023SJohn Marino VEC(tree,gc) *exprlist;
6855*e4b17023SJohn Marino VEC(tree,gc) *origtypes;
6856*e4b17023SJohn Marino while (true)
6857*e4b17023SJohn Marino {
6858*e4b17023SJohn Marino location_t op_loc = c_parser_peek_token (parser)->location;
6859*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
6860*e4b17023SJohn Marino {
6861*e4b17023SJohn Marino case CPP_OPEN_SQUARE:
6862*e4b17023SJohn Marino /* Array reference. */
6863*e4b17023SJohn Marino c_parser_consume_token (parser);
6864*e4b17023SJohn Marino idx = c_parser_expression (parser).value;
6865*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6866*e4b17023SJohn Marino "expected %<]%>");
6867*e4b17023SJohn Marino expr.value = build_array_ref (op_loc, expr.value, idx);
6868*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6869*e4b17023SJohn Marino expr.original_type = NULL;
6870*e4b17023SJohn Marino break;
6871*e4b17023SJohn Marino case CPP_OPEN_PAREN:
6872*e4b17023SJohn Marino /* Function call. */
6873*e4b17023SJohn Marino c_parser_consume_token (parser);
6874*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6875*e4b17023SJohn Marino exprlist = NULL;
6876*e4b17023SJohn Marino else
6877*e4b17023SJohn Marino exprlist = c_parser_expr_list (parser, true, false, &origtypes);
6878*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
6879*e4b17023SJohn Marino "expected %<)%>");
6880*e4b17023SJohn Marino orig_expr = expr;
6881*e4b17023SJohn Marino mark_exp_read (expr.value);
6882*e4b17023SJohn Marino /* FIXME diagnostics: Ideally we want the FUNCNAME, not the
6883*e4b17023SJohn Marino "(" after the FUNCNAME, which is what we have now. */
6884*e4b17023SJohn Marino expr.value = build_function_call_vec (op_loc, expr.value, exprlist,
6885*e4b17023SJohn Marino origtypes);
6886*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6887*e4b17023SJohn Marino if (TREE_CODE (expr.value) == INTEGER_CST
6888*e4b17023SJohn Marino && TREE_CODE (orig_expr.value) == FUNCTION_DECL
6889*e4b17023SJohn Marino && DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
6890*e4b17023SJohn Marino && DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
6891*e4b17023SJohn Marino expr.original_code = C_MAYBE_CONST_EXPR;
6892*e4b17023SJohn Marino expr.original_type = NULL;
6893*e4b17023SJohn Marino if (exprlist != NULL)
6894*e4b17023SJohn Marino {
6895*e4b17023SJohn Marino release_tree_vector (exprlist);
6896*e4b17023SJohn Marino release_tree_vector (origtypes);
6897*e4b17023SJohn Marino }
6898*e4b17023SJohn Marino break;
6899*e4b17023SJohn Marino case CPP_DOT:
6900*e4b17023SJohn Marino /* Structure element reference. */
6901*e4b17023SJohn Marino c_parser_consume_token (parser);
6902*e4b17023SJohn Marino expr = default_function_array_conversion (expr_loc, expr);
6903*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
6904*e4b17023SJohn Marino ident = c_parser_peek_token (parser)->value;
6905*e4b17023SJohn Marino else
6906*e4b17023SJohn Marino {
6907*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
6908*e4b17023SJohn Marino expr.value = error_mark_node;
6909*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6910*e4b17023SJohn Marino expr.original_type = NULL;
6911*e4b17023SJohn Marino return expr;
6912*e4b17023SJohn Marino }
6913*e4b17023SJohn Marino c_parser_consume_token (parser);
6914*e4b17023SJohn Marino expr.value = build_component_ref (op_loc, expr.value, ident);
6915*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6916*e4b17023SJohn Marino if (TREE_CODE (expr.value) != COMPONENT_REF)
6917*e4b17023SJohn Marino expr.original_type = NULL;
6918*e4b17023SJohn Marino else
6919*e4b17023SJohn Marino {
6920*e4b17023SJohn Marino /* Remember the original type of a bitfield. */
6921*e4b17023SJohn Marino tree field = TREE_OPERAND (expr.value, 1);
6922*e4b17023SJohn Marino if (TREE_CODE (field) != FIELD_DECL)
6923*e4b17023SJohn Marino expr.original_type = NULL;
6924*e4b17023SJohn Marino else
6925*e4b17023SJohn Marino expr.original_type = DECL_BIT_FIELD_TYPE (field);
6926*e4b17023SJohn Marino }
6927*e4b17023SJohn Marino break;
6928*e4b17023SJohn Marino case CPP_DEREF:
6929*e4b17023SJohn Marino /* Structure element reference. */
6930*e4b17023SJohn Marino c_parser_consume_token (parser);
6931*e4b17023SJohn Marino expr = default_function_array_conversion (expr_loc, expr);
6932*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
6933*e4b17023SJohn Marino ident = c_parser_peek_token (parser)->value;
6934*e4b17023SJohn Marino else
6935*e4b17023SJohn Marino {
6936*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
6937*e4b17023SJohn Marino expr.value = error_mark_node;
6938*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6939*e4b17023SJohn Marino expr.original_type = NULL;
6940*e4b17023SJohn Marino return expr;
6941*e4b17023SJohn Marino }
6942*e4b17023SJohn Marino c_parser_consume_token (parser);
6943*e4b17023SJohn Marino expr.value = build_component_ref (op_loc,
6944*e4b17023SJohn Marino build_indirect_ref (op_loc,
6945*e4b17023SJohn Marino expr.value,
6946*e4b17023SJohn Marino RO_ARROW),
6947*e4b17023SJohn Marino ident);
6948*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6949*e4b17023SJohn Marino if (TREE_CODE (expr.value) != COMPONENT_REF)
6950*e4b17023SJohn Marino expr.original_type = NULL;
6951*e4b17023SJohn Marino else
6952*e4b17023SJohn Marino {
6953*e4b17023SJohn Marino /* Remember the original type of a bitfield. */
6954*e4b17023SJohn Marino tree field = TREE_OPERAND (expr.value, 1);
6955*e4b17023SJohn Marino if (TREE_CODE (field) != FIELD_DECL)
6956*e4b17023SJohn Marino expr.original_type = NULL;
6957*e4b17023SJohn Marino else
6958*e4b17023SJohn Marino expr.original_type = DECL_BIT_FIELD_TYPE (field);
6959*e4b17023SJohn Marino }
6960*e4b17023SJohn Marino break;
6961*e4b17023SJohn Marino case CPP_PLUS_PLUS:
6962*e4b17023SJohn Marino /* Postincrement. */
6963*e4b17023SJohn Marino c_parser_consume_token (parser);
6964*e4b17023SJohn Marino expr = default_function_array_read_conversion (expr_loc, expr);
6965*e4b17023SJohn Marino expr.value = build_unary_op (op_loc,
6966*e4b17023SJohn Marino POSTINCREMENT_EXPR, expr.value, 0);
6967*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6968*e4b17023SJohn Marino expr.original_type = NULL;
6969*e4b17023SJohn Marino break;
6970*e4b17023SJohn Marino case CPP_MINUS_MINUS:
6971*e4b17023SJohn Marino /* Postdecrement. */
6972*e4b17023SJohn Marino c_parser_consume_token (parser);
6973*e4b17023SJohn Marino expr = default_function_array_read_conversion (expr_loc, expr);
6974*e4b17023SJohn Marino expr.value = build_unary_op (op_loc,
6975*e4b17023SJohn Marino POSTDECREMENT_EXPR, expr.value, 0);
6976*e4b17023SJohn Marino expr.original_code = ERROR_MARK;
6977*e4b17023SJohn Marino expr.original_type = NULL;
6978*e4b17023SJohn Marino break;
6979*e4b17023SJohn Marino default:
6980*e4b17023SJohn Marino return expr;
6981*e4b17023SJohn Marino }
6982*e4b17023SJohn Marino }
6983*e4b17023SJohn Marino }
6984*e4b17023SJohn Marino
6985*e4b17023SJohn Marino /* Parse an expression (C90 6.3.17, C99 6.5.17).
6986*e4b17023SJohn Marino
6987*e4b17023SJohn Marino expression:
6988*e4b17023SJohn Marino assignment-expression
6989*e4b17023SJohn Marino expression , assignment-expression
6990*e4b17023SJohn Marino */
6991*e4b17023SJohn Marino
6992*e4b17023SJohn Marino static struct c_expr
c_parser_expression(c_parser * parser)6993*e4b17023SJohn Marino c_parser_expression (c_parser *parser)
6994*e4b17023SJohn Marino {
6995*e4b17023SJohn Marino struct c_expr expr;
6996*e4b17023SJohn Marino expr = c_parser_expr_no_commas (parser, NULL);
6997*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_COMMA))
6998*e4b17023SJohn Marino {
6999*e4b17023SJohn Marino struct c_expr next;
7000*e4b17023SJohn Marino tree lhsval;
7001*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
7002*e4b17023SJohn Marino location_t expr_loc;
7003*e4b17023SJohn Marino c_parser_consume_token (parser);
7004*e4b17023SJohn Marino expr_loc = c_parser_peek_token (parser)->location;
7005*e4b17023SJohn Marino lhsval = expr.value;
7006*e4b17023SJohn Marino while (TREE_CODE (lhsval) == COMPOUND_EXPR)
7007*e4b17023SJohn Marino lhsval = TREE_OPERAND (lhsval, 1);
7008*e4b17023SJohn Marino if (DECL_P (lhsval) || handled_component_p (lhsval))
7009*e4b17023SJohn Marino mark_exp_read (lhsval);
7010*e4b17023SJohn Marino next = c_parser_expr_no_commas (parser, NULL);
7011*e4b17023SJohn Marino next = default_function_array_conversion (expr_loc, next);
7012*e4b17023SJohn Marino expr.value = build_compound_expr (loc, expr.value, next.value);
7013*e4b17023SJohn Marino expr.original_code = COMPOUND_EXPR;
7014*e4b17023SJohn Marino expr.original_type = next.original_type;
7015*e4b17023SJohn Marino }
7016*e4b17023SJohn Marino return expr;
7017*e4b17023SJohn Marino }
7018*e4b17023SJohn Marino
7019*e4b17023SJohn Marino /* Parse an expression and convert functions or arrays to
7020*e4b17023SJohn Marino pointers. */
7021*e4b17023SJohn Marino
7022*e4b17023SJohn Marino static struct c_expr
c_parser_expression_conv(c_parser * parser)7023*e4b17023SJohn Marino c_parser_expression_conv (c_parser *parser)
7024*e4b17023SJohn Marino {
7025*e4b17023SJohn Marino struct c_expr expr;
7026*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
7027*e4b17023SJohn Marino expr = c_parser_expression (parser);
7028*e4b17023SJohn Marino expr = default_function_array_conversion (loc, expr);
7029*e4b17023SJohn Marino return expr;
7030*e4b17023SJohn Marino }
7031*e4b17023SJohn Marino
7032*e4b17023SJohn Marino /* Parse a non-empty list of expressions. If CONVERT_P, convert
7033*e4b17023SJohn Marino functions and arrays to pointers. If FOLD_P, fold the expressions.
7034*e4b17023SJohn Marino
7035*e4b17023SJohn Marino nonempty-expr-list:
7036*e4b17023SJohn Marino assignment-expression
7037*e4b17023SJohn Marino nonempty-expr-list , assignment-expression
7038*e4b17023SJohn Marino */
7039*e4b17023SJohn Marino
VEC(tree,gc)7040*e4b17023SJohn Marino static VEC(tree,gc) *
7041*e4b17023SJohn Marino c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
7042*e4b17023SJohn Marino VEC(tree,gc) **p_orig_types)
7043*e4b17023SJohn Marino {
7044*e4b17023SJohn Marino VEC(tree,gc) *ret;
7045*e4b17023SJohn Marino VEC(tree,gc) *orig_types;
7046*e4b17023SJohn Marino struct c_expr expr;
7047*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
7048*e4b17023SJohn Marino
7049*e4b17023SJohn Marino ret = make_tree_vector ();
7050*e4b17023SJohn Marino if (p_orig_types == NULL)
7051*e4b17023SJohn Marino orig_types = NULL;
7052*e4b17023SJohn Marino else
7053*e4b17023SJohn Marino orig_types = make_tree_vector ();
7054*e4b17023SJohn Marino
7055*e4b17023SJohn Marino expr = c_parser_expr_no_commas (parser, NULL);
7056*e4b17023SJohn Marino if (convert_p)
7057*e4b17023SJohn Marino expr = default_function_array_read_conversion (loc, expr);
7058*e4b17023SJohn Marino if (fold_p)
7059*e4b17023SJohn Marino expr.value = c_fully_fold (expr.value, false, NULL);
7060*e4b17023SJohn Marino VEC_quick_push (tree, ret, expr.value);
7061*e4b17023SJohn Marino if (orig_types != NULL)
7062*e4b17023SJohn Marino VEC_quick_push (tree, orig_types, expr.original_type);
7063*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_COMMA))
7064*e4b17023SJohn Marino {
7065*e4b17023SJohn Marino c_parser_consume_token (parser);
7066*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
7067*e4b17023SJohn Marino expr = c_parser_expr_no_commas (parser, NULL);
7068*e4b17023SJohn Marino if (convert_p)
7069*e4b17023SJohn Marino expr = default_function_array_read_conversion (loc, expr);
7070*e4b17023SJohn Marino if (fold_p)
7071*e4b17023SJohn Marino expr.value = c_fully_fold (expr.value, false, NULL);
7072*e4b17023SJohn Marino VEC_safe_push (tree, gc, ret, expr.value);
7073*e4b17023SJohn Marino if (orig_types != NULL)
7074*e4b17023SJohn Marino VEC_safe_push (tree, gc, orig_types, expr.original_type);
7075*e4b17023SJohn Marino }
7076*e4b17023SJohn Marino if (orig_types != NULL)
7077*e4b17023SJohn Marino *p_orig_types = orig_types;
7078*e4b17023SJohn Marino return ret;
7079*e4b17023SJohn Marino }
7080*e4b17023SJohn Marino
7081*e4b17023SJohn Marino /* Parse Objective-C-specific constructs. */
7082*e4b17023SJohn Marino
7083*e4b17023SJohn Marino /* Parse an objc-class-definition.
7084*e4b17023SJohn Marino
7085*e4b17023SJohn Marino objc-class-definition:
7086*e4b17023SJohn Marino @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
7087*e4b17023SJohn Marino objc-class-instance-variables[opt] objc-methodprotolist @end
7088*e4b17023SJohn Marino @implementation identifier objc-superclass[opt]
7089*e4b17023SJohn Marino objc-class-instance-variables[opt]
7090*e4b17023SJohn Marino @interface identifier ( identifier ) objc-protocol-refs[opt]
7091*e4b17023SJohn Marino objc-methodprotolist @end
7092*e4b17023SJohn Marino @interface identifier ( ) objc-protocol-refs[opt]
7093*e4b17023SJohn Marino objc-methodprotolist @end
7094*e4b17023SJohn Marino @implementation identifier ( identifier )
7095*e4b17023SJohn Marino
7096*e4b17023SJohn Marino objc-superclass:
7097*e4b17023SJohn Marino : identifier
7098*e4b17023SJohn Marino
7099*e4b17023SJohn Marino "@interface identifier (" must start "@interface identifier (
7100*e4b17023SJohn Marino identifier ) ...": objc-methodprotolist in the first production may
7101*e4b17023SJohn Marino not start with a parenthesized identifier as a declarator of a data
7102*e4b17023SJohn Marino definition with no declaration specifiers if the objc-superclass,
7103*e4b17023SJohn Marino objc-protocol-refs and objc-class-instance-variables are omitted. */
7104*e4b17023SJohn Marino
7105*e4b17023SJohn Marino static void
c_parser_objc_class_definition(c_parser * parser,tree attributes)7106*e4b17023SJohn Marino c_parser_objc_class_definition (c_parser *parser, tree attributes)
7107*e4b17023SJohn Marino {
7108*e4b17023SJohn Marino bool iface_p;
7109*e4b17023SJohn Marino tree id1;
7110*e4b17023SJohn Marino tree superclass;
7111*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
7112*e4b17023SJohn Marino iface_p = true;
7113*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
7114*e4b17023SJohn Marino iface_p = false;
7115*e4b17023SJohn Marino else
7116*e4b17023SJohn Marino gcc_unreachable ();
7117*e4b17023SJohn Marino
7118*e4b17023SJohn Marino c_parser_consume_token (parser);
7119*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7120*e4b17023SJohn Marino {
7121*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7122*e4b17023SJohn Marino return;
7123*e4b17023SJohn Marino }
7124*e4b17023SJohn Marino id1 = c_parser_peek_token (parser)->value;
7125*e4b17023SJohn Marino c_parser_consume_token (parser);
7126*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7127*e4b17023SJohn Marino {
7128*e4b17023SJohn Marino /* We have a category or class extension. */
7129*e4b17023SJohn Marino tree id2;
7130*e4b17023SJohn Marino tree proto = NULL_TREE;
7131*e4b17023SJohn Marino c_parser_consume_token (parser);
7132*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7133*e4b17023SJohn Marino {
7134*e4b17023SJohn Marino if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7135*e4b17023SJohn Marino {
7136*e4b17023SJohn Marino /* We have a class extension. */
7137*e4b17023SJohn Marino id2 = NULL_TREE;
7138*e4b17023SJohn Marino }
7139*e4b17023SJohn Marino else
7140*e4b17023SJohn Marino {
7141*e4b17023SJohn Marino c_parser_error (parser, "expected identifier or %<)%>");
7142*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7143*e4b17023SJohn Marino return;
7144*e4b17023SJohn Marino }
7145*e4b17023SJohn Marino }
7146*e4b17023SJohn Marino else
7147*e4b17023SJohn Marino {
7148*e4b17023SJohn Marino id2 = c_parser_peek_token (parser)->value;
7149*e4b17023SJohn Marino c_parser_consume_token (parser);
7150*e4b17023SJohn Marino }
7151*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7152*e4b17023SJohn Marino if (!iface_p)
7153*e4b17023SJohn Marino {
7154*e4b17023SJohn Marino objc_start_category_implementation (id1, id2);
7155*e4b17023SJohn Marino return;
7156*e4b17023SJohn Marino }
7157*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_LESS))
7158*e4b17023SJohn Marino proto = c_parser_objc_protocol_refs (parser);
7159*e4b17023SJohn Marino objc_start_category_interface (id1, id2, proto, attributes);
7160*e4b17023SJohn Marino c_parser_objc_methodprotolist (parser);
7161*e4b17023SJohn Marino c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
7162*e4b17023SJohn Marino objc_finish_interface ();
7163*e4b17023SJohn Marino return;
7164*e4b17023SJohn Marino }
7165*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COLON))
7166*e4b17023SJohn Marino {
7167*e4b17023SJohn Marino c_parser_consume_token (parser);
7168*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7169*e4b17023SJohn Marino {
7170*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7171*e4b17023SJohn Marino return;
7172*e4b17023SJohn Marino }
7173*e4b17023SJohn Marino superclass = c_parser_peek_token (parser)->value;
7174*e4b17023SJohn Marino c_parser_consume_token (parser);
7175*e4b17023SJohn Marino }
7176*e4b17023SJohn Marino else
7177*e4b17023SJohn Marino superclass = NULL_TREE;
7178*e4b17023SJohn Marino if (iface_p)
7179*e4b17023SJohn Marino {
7180*e4b17023SJohn Marino tree proto = NULL_TREE;
7181*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_LESS))
7182*e4b17023SJohn Marino proto = c_parser_objc_protocol_refs (parser);
7183*e4b17023SJohn Marino objc_start_class_interface (id1, superclass, proto, attributes);
7184*e4b17023SJohn Marino }
7185*e4b17023SJohn Marino else
7186*e4b17023SJohn Marino objc_start_class_implementation (id1, superclass);
7187*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7188*e4b17023SJohn Marino c_parser_objc_class_instance_variables (parser);
7189*e4b17023SJohn Marino if (iface_p)
7190*e4b17023SJohn Marino {
7191*e4b17023SJohn Marino objc_continue_interface ();
7192*e4b17023SJohn Marino c_parser_objc_methodprotolist (parser);
7193*e4b17023SJohn Marino c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
7194*e4b17023SJohn Marino objc_finish_interface ();
7195*e4b17023SJohn Marino }
7196*e4b17023SJohn Marino else
7197*e4b17023SJohn Marino {
7198*e4b17023SJohn Marino objc_continue_implementation ();
7199*e4b17023SJohn Marino return;
7200*e4b17023SJohn Marino }
7201*e4b17023SJohn Marino }
7202*e4b17023SJohn Marino
7203*e4b17023SJohn Marino /* Parse objc-class-instance-variables.
7204*e4b17023SJohn Marino
7205*e4b17023SJohn Marino objc-class-instance-variables:
7206*e4b17023SJohn Marino { objc-instance-variable-decl-list[opt] }
7207*e4b17023SJohn Marino
7208*e4b17023SJohn Marino objc-instance-variable-decl-list:
7209*e4b17023SJohn Marino objc-visibility-spec
7210*e4b17023SJohn Marino objc-instance-variable-decl ;
7211*e4b17023SJohn Marino ;
7212*e4b17023SJohn Marino objc-instance-variable-decl-list objc-visibility-spec
7213*e4b17023SJohn Marino objc-instance-variable-decl-list objc-instance-variable-decl ;
7214*e4b17023SJohn Marino objc-instance-variable-decl-list ;
7215*e4b17023SJohn Marino
7216*e4b17023SJohn Marino objc-visibility-spec:
7217*e4b17023SJohn Marino @private
7218*e4b17023SJohn Marino @protected
7219*e4b17023SJohn Marino @public
7220*e4b17023SJohn Marino
7221*e4b17023SJohn Marino objc-instance-variable-decl:
7222*e4b17023SJohn Marino struct-declaration
7223*e4b17023SJohn Marino */
7224*e4b17023SJohn Marino
7225*e4b17023SJohn Marino static void
c_parser_objc_class_instance_variables(c_parser * parser)7226*e4b17023SJohn Marino c_parser_objc_class_instance_variables (c_parser *parser)
7227*e4b17023SJohn Marino {
7228*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
7229*e4b17023SJohn Marino c_parser_consume_token (parser);
7230*e4b17023SJohn Marino while (c_parser_next_token_is_not (parser, CPP_EOF))
7231*e4b17023SJohn Marino {
7232*e4b17023SJohn Marino tree decls;
7233*e4b17023SJohn Marino /* Parse any stray semicolon. */
7234*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7235*e4b17023SJohn Marino {
7236*e4b17023SJohn Marino pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
7237*e4b17023SJohn Marino "extra semicolon");
7238*e4b17023SJohn Marino c_parser_consume_token (parser);
7239*e4b17023SJohn Marino continue;
7240*e4b17023SJohn Marino }
7241*e4b17023SJohn Marino /* Stop if at the end of the instance variables. */
7242*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
7243*e4b17023SJohn Marino {
7244*e4b17023SJohn Marino c_parser_consume_token (parser);
7245*e4b17023SJohn Marino break;
7246*e4b17023SJohn Marino }
7247*e4b17023SJohn Marino /* Parse any objc-visibility-spec. */
7248*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
7249*e4b17023SJohn Marino {
7250*e4b17023SJohn Marino c_parser_consume_token (parser);
7251*e4b17023SJohn Marino objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
7252*e4b17023SJohn Marino continue;
7253*e4b17023SJohn Marino }
7254*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
7255*e4b17023SJohn Marino {
7256*e4b17023SJohn Marino c_parser_consume_token (parser);
7257*e4b17023SJohn Marino objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
7258*e4b17023SJohn Marino continue;
7259*e4b17023SJohn Marino }
7260*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
7261*e4b17023SJohn Marino {
7262*e4b17023SJohn Marino c_parser_consume_token (parser);
7263*e4b17023SJohn Marino objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
7264*e4b17023SJohn Marino continue;
7265*e4b17023SJohn Marino }
7266*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
7267*e4b17023SJohn Marino {
7268*e4b17023SJohn Marino c_parser_consume_token (parser);
7269*e4b17023SJohn Marino objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
7270*e4b17023SJohn Marino continue;
7271*e4b17023SJohn Marino }
7272*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_PRAGMA))
7273*e4b17023SJohn Marino {
7274*e4b17023SJohn Marino c_parser_pragma (parser, pragma_external);
7275*e4b17023SJohn Marino continue;
7276*e4b17023SJohn Marino }
7277*e4b17023SJohn Marino
7278*e4b17023SJohn Marino /* Parse some comma-separated declarations. */
7279*e4b17023SJohn Marino decls = c_parser_struct_declaration (parser);
7280*e4b17023SJohn Marino if (decls == NULL)
7281*e4b17023SJohn Marino {
7282*e4b17023SJohn Marino /* There is a syntax error. We want to skip the offending
7283*e4b17023SJohn Marino tokens up to the next ';' (included) or '}'
7284*e4b17023SJohn Marino (excluded). */
7285*e4b17023SJohn Marino
7286*e4b17023SJohn Marino /* First, skip manually a ')' or ']'. This is because they
7287*e4b17023SJohn Marino reduce the nesting level, so c_parser_skip_until_found()
7288*e4b17023SJohn Marino wouldn't be able to skip past them. */
7289*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
7290*e4b17023SJohn Marino if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
7291*e4b17023SJohn Marino c_parser_consume_token (parser);
7292*e4b17023SJohn Marino
7293*e4b17023SJohn Marino /* Then, do the standard skipping. */
7294*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
7295*e4b17023SJohn Marino
7296*e4b17023SJohn Marino /* We hopefully recovered. Start normal parsing again. */
7297*e4b17023SJohn Marino parser->error = false;
7298*e4b17023SJohn Marino continue;
7299*e4b17023SJohn Marino }
7300*e4b17023SJohn Marino else
7301*e4b17023SJohn Marino {
7302*e4b17023SJohn Marino /* Comma-separated instance variables are chained together
7303*e4b17023SJohn Marino in reverse order; add them one by one. */
7304*e4b17023SJohn Marino tree ivar = nreverse (decls);
7305*e4b17023SJohn Marino for (; ivar; ivar = DECL_CHAIN (ivar))
7306*e4b17023SJohn Marino objc_add_instance_variable (copy_node (ivar));
7307*e4b17023SJohn Marino }
7308*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7309*e4b17023SJohn Marino }
7310*e4b17023SJohn Marino }
7311*e4b17023SJohn Marino
7312*e4b17023SJohn Marino /* Parse an objc-class-declaration.
7313*e4b17023SJohn Marino
7314*e4b17023SJohn Marino objc-class-declaration:
7315*e4b17023SJohn Marino @class identifier-list ;
7316*e4b17023SJohn Marino */
7317*e4b17023SJohn Marino
7318*e4b17023SJohn Marino static void
c_parser_objc_class_declaration(c_parser * parser)7319*e4b17023SJohn Marino c_parser_objc_class_declaration (c_parser *parser)
7320*e4b17023SJohn Marino {
7321*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
7322*e4b17023SJohn Marino c_parser_consume_token (parser);
7323*e4b17023SJohn Marino /* Any identifiers, including those declared as type names, are OK
7324*e4b17023SJohn Marino here. */
7325*e4b17023SJohn Marino while (true)
7326*e4b17023SJohn Marino {
7327*e4b17023SJohn Marino tree id;
7328*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7329*e4b17023SJohn Marino {
7330*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7331*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
7332*e4b17023SJohn Marino parser->error = false;
7333*e4b17023SJohn Marino return;
7334*e4b17023SJohn Marino }
7335*e4b17023SJohn Marino id = c_parser_peek_token (parser)->value;
7336*e4b17023SJohn Marino objc_declare_class (id);
7337*e4b17023SJohn Marino c_parser_consume_token (parser);
7338*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
7339*e4b17023SJohn Marino c_parser_consume_token (parser);
7340*e4b17023SJohn Marino else
7341*e4b17023SJohn Marino break;
7342*e4b17023SJohn Marino }
7343*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7344*e4b17023SJohn Marino }
7345*e4b17023SJohn Marino
7346*e4b17023SJohn Marino /* Parse an objc-alias-declaration.
7347*e4b17023SJohn Marino
7348*e4b17023SJohn Marino objc-alias-declaration:
7349*e4b17023SJohn Marino @compatibility_alias identifier identifier ;
7350*e4b17023SJohn Marino */
7351*e4b17023SJohn Marino
7352*e4b17023SJohn Marino static void
c_parser_objc_alias_declaration(c_parser * parser)7353*e4b17023SJohn Marino c_parser_objc_alias_declaration (c_parser *parser)
7354*e4b17023SJohn Marino {
7355*e4b17023SJohn Marino tree id1, id2;
7356*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
7357*e4b17023SJohn Marino c_parser_consume_token (parser);
7358*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7359*e4b17023SJohn Marino {
7360*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7361*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
7362*e4b17023SJohn Marino return;
7363*e4b17023SJohn Marino }
7364*e4b17023SJohn Marino id1 = c_parser_peek_token (parser)->value;
7365*e4b17023SJohn Marino c_parser_consume_token (parser);
7366*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7367*e4b17023SJohn Marino {
7368*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7369*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
7370*e4b17023SJohn Marino return;
7371*e4b17023SJohn Marino }
7372*e4b17023SJohn Marino id2 = c_parser_peek_token (parser)->value;
7373*e4b17023SJohn Marino c_parser_consume_token (parser);
7374*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7375*e4b17023SJohn Marino objc_declare_alias (id1, id2);
7376*e4b17023SJohn Marino }
7377*e4b17023SJohn Marino
7378*e4b17023SJohn Marino /* Parse an objc-protocol-definition.
7379*e4b17023SJohn Marino
7380*e4b17023SJohn Marino objc-protocol-definition:
7381*e4b17023SJohn Marino @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
7382*e4b17023SJohn Marino @protocol identifier-list ;
7383*e4b17023SJohn Marino
7384*e4b17023SJohn Marino "@protocol identifier ;" should be resolved as "@protocol
7385*e4b17023SJohn Marino identifier-list ;": objc-methodprotolist may not start with a
7386*e4b17023SJohn Marino semicolon in the first alternative if objc-protocol-refs are
7387*e4b17023SJohn Marino omitted. */
7388*e4b17023SJohn Marino
7389*e4b17023SJohn Marino static void
c_parser_objc_protocol_definition(c_parser * parser,tree attributes)7390*e4b17023SJohn Marino c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
7391*e4b17023SJohn Marino {
7392*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
7393*e4b17023SJohn Marino
7394*e4b17023SJohn Marino c_parser_consume_token (parser);
7395*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7396*e4b17023SJohn Marino {
7397*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7398*e4b17023SJohn Marino return;
7399*e4b17023SJohn Marino }
7400*e4b17023SJohn Marino if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
7401*e4b17023SJohn Marino || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
7402*e4b17023SJohn Marino {
7403*e4b17023SJohn Marino /* Any identifiers, including those declared as type names, are
7404*e4b17023SJohn Marino OK here. */
7405*e4b17023SJohn Marino while (true)
7406*e4b17023SJohn Marino {
7407*e4b17023SJohn Marino tree id;
7408*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7409*e4b17023SJohn Marino {
7410*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7411*e4b17023SJohn Marino break;
7412*e4b17023SJohn Marino }
7413*e4b17023SJohn Marino id = c_parser_peek_token (parser)->value;
7414*e4b17023SJohn Marino objc_declare_protocol (id, attributes);
7415*e4b17023SJohn Marino c_parser_consume_token (parser);
7416*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
7417*e4b17023SJohn Marino c_parser_consume_token (parser);
7418*e4b17023SJohn Marino else
7419*e4b17023SJohn Marino break;
7420*e4b17023SJohn Marino }
7421*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7422*e4b17023SJohn Marino }
7423*e4b17023SJohn Marino else
7424*e4b17023SJohn Marino {
7425*e4b17023SJohn Marino tree id = c_parser_peek_token (parser)->value;
7426*e4b17023SJohn Marino tree proto = NULL_TREE;
7427*e4b17023SJohn Marino c_parser_consume_token (parser);
7428*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_LESS))
7429*e4b17023SJohn Marino proto = c_parser_objc_protocol_refs (parser);
7430*e4b17023SJohn Marino parser->objc_pq_context = true;
7431*e4b17023SJohn Marino objc_start_protocol (id, proto, attributes);
7432*e4b17023SJohn Marino c_parser_objc_methodprotolist (parser);
7433*e4b17023SJohn Marino c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
7434*e4b17023SJohn Marino parser->objc_pq_context = false;
7435*e4b17023SJohn Marino objc_finish_interface ();
7436*e4b17023SJohn Marino }
7437*e4b17023SJohn Marino }
7438*e4b17023SJohn Marino
7439*e4b17023SJohn Marino /* Parse an objc-method-type.
7440*e4b17023SJohn Marino
7441*e4b17023SJohn Marino objc-method-type:
7442*e4b17023SJohn Marino +
7443*e4b17023SJohn Marino -
7444*e4b17023SJohn Marino
7445*e4b17023SJohn Marino Return true if it is a class method (+) and false if it is
7446*e4b17023SJohn Marino an instance method (-).
7447*e4b17023SJohn Marino */
7448*e4b17023SJohn Marino static inline bool
c_parser_objc_method_type(c_parser * parser)7449*e4b17023SJohn Marino c_parser_objc_method_type (c_parser *parser)
7450*e4b17023SJohn Marino {
7451*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
7452*e4b17023SJohn Marino {
7453*e4b17023SJohn Marino case CPP_PLUS:
7454*e4b17023SJohn Marino c_parser_consume_token (parser);
7455*e4b17023SJohn Marino return true;
7456*e4b17023SJohn Marino case CPP_MINUS:
7457*e4b17023SJohn Marino c_parser_consume_token (parser);
7458*e4b17023SJohn Marino return false;
7459*e4b17023SJohn Marino default:
7460*e4b17023SJohn Marino gcc_unreachable ();
7461*e4b17023SJohn Marino }
7462*e4b17023SJohn Marino }
7463*e4b17023SJohn Marino
7464*e4b17023SJohn Marino /* Parse an objc-method-definition.
7465*e4b17023SJohn Marino
7466*e4b17023SJohn Marino objc-method-definition:
7467*e4b17023SJohn Marino objc-method-type objc-method-decl ;[opt] compound-statement
7468*e4b17023SJohn Marino */
7469*e4b17023SJohn Marino
7470*e4b17023SJohn Marino static void
c_parser_objc_method_definition(c_parser * parser)7471*e4b17023SJohn Marino c_parser_objc_method_definition (c_parser *parser)
7472*e4b17023SJohn Marino {
7473*e4b17023SJohn Marino bool is_class_method = c_parser_objc_method_type (parser);
7474*e4b17023SJohn Marino tree decl, attributes = NULL_TREE, expr = NULL_TREE;
7475*e4b17023SJohn Marino parser->objc_pq_context = true;
7476*e4b17023SJohn Marino decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
7477*e4b17023SJohn Marino &expr);
7478*e4b17023SJohn Marino if (decl == error_mark_node)
7479*e4b17023SJohn Marino return; /* Bail here. */
7480*e4b17023SJohn Marino
7481*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7482*e4b17023SJohn Marino {
7483*e4b17023SJohn Marino c_parser_consume_token (parser);
7484*e4b17023SJohn Marino pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
7485*e4b17023SJohn Marino "extra semicolon in method definition specified");
7486*e4b17023SJohn Marino }
7487*e4b17023SJohn Marino
7488*e4b17023SJohn Marino if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7489*e4b17023SJohn Marino {
7490*e4b17023SJohn Marino c_parser_error (parser, "expected %<{%>");
7491*e4b17023SJohn Marino return;
7492*e4b17023SJohn Marino }
7493*e4b17023SJohn Marino
7494*e4b17023SJohn Marino parser->objc_pq_context = false;
7495*e4b17023SJohn Marino if (objc_start_method_definition (is_class_method, decl, attributes, expr))
7496*e4b17023SJohn Marino {
7497*e4b17023SJohn Marino add_stmt (c_parser_compound_statement (parser));
7498*e4b17023SJohn Marino objc_finish_method_definition (current_function_decl);
7499*e4b17023SJohn Marino }
7500*e4b17023SJohn Marino else
7501*e4b17023SJohn Marino {
7502*e4b17023SJohn Marino /* This code is executed when we find a method definition
7503*e4b17023SJohn Marino outside of an @implementation context (or invalid for other
7504*e4b17023SJohn Marino reasons). Parse the method (to keep going) but do not emit
7505*e4b17023SJohn Marino any code.
7506*e4b17023SJohn Marino */
7507*e4b17023SJohn Marino c_parser_compound_statement (parser);
7508*e4b17023SJohn Marino }
7509*e4b17023SJohn Marino }
7510*e4b17023SJohn Marino
7511*e4b17023SJohn Marino /* Parse an objc-methodprotolist.
7512*e4b17023SJohn Marino
7513*e4b17023SJohn Marino objc-methodprotolist:
7514*e4b17023SJohn Marino empty
7515*e4b17023SJohn Marino objc-methodprotolist objc-methodproto
7516*e4b17023SJohn Marino objc-methodprotolist declaration
7517*e4b17023SJohn Marino objc-methodprotolist ;
7518*e4b17023SJohn Marino @optional
7519*e4b17023SJohn Marino @required
7520*e4b17023SJohn Marino
7521*e4b17023SJohn Marino The declaration is a data definition, which may be missing
7522*e4b17023SJohn Marino declaration specifiers under the same rules and diagnostics as
7523*e4b17023SJohn Marino other data definitions outside functions, and the stray semicolon
7524*e4b17023SJohn Marino is diagnosed the same way as a stray semicolon outside a
7525*e4b17023SJohn Marino function. */
7526*e4b17023SJohn Marino
7527*e4b17023SJohn Marino static void
c_parser_objc_methodprotolist(c_parser * parser)7528*e4b17023SJohn Marino c_parser_objc_methodprotolist (c_parser *parser)
7529*e4b17023SJohn Marino {
7530*e4b17023SJohn Marino while (true)
7531*e4b17023SJohn Marino {
7532*e4b17023SJohn Marino /* The list is terminated by @end. */
7533*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
7534*e4b17023SJohn Marino {
7535*e4b17023SJohn Marino case CPP_SEMICOLON:
7536*e4b17023SJohn Marino pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
7537*e4b17023SJohn Marino "ISO C does not allow extra %<;%> outside of a function");
7538*e4b17023SJohn Marino c_parser_consume_token (parser);
7539*e4b17023SJohn Marino break;
7540*e4b17023SJohn Marino case CPP_PLUS:
7541*e4b17023SJohn Marino case CPP_MINUS:
7542*e4b17023SJohn Marino c_parser_objc_methodproto (parser);
7543*e4b17023SJohn Marino break;
7544*e4b17023SJohn Marino case CPP_PRAGMA:
7545*e4b17023SJohn Marino c_parser_pragma (parser, pragma_external);
7546*e4b17023SJohn Marino break;
7547*e4b17023SJohn Marino case CPP_EOF:
7548*e4b17023SJohn Marino return;
7549*e4b17023SJohn Marino default:
7550*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_AT_END))
7551*e4b17023SJohn Marino return;
7552*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
7553*e4b17023SJohn Marino c_parser_objc_at_property_declaration (parser);
7554*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
7555*e4b17023SJohn Marino {
7556*e4b17023SJohn Marino objc_set_method_opt (true);
7557*e4b17023SJohn Marino c_parser_consume_token (parser);
7558*e4b17023SJohn Marino }
7559*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
7560*e4b17023SJohn Marino {
7561*e4b17023SJohn Marino objc_set_method_opt (false);
7562*e4b17023SJohn Marino c_parser_consume_token (parser);
7563*e4b17023SJohn Marino }
7564*e4b17023SJohn Marino else
7565*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, false, false, true,
7566*e4b17023SJohn Marino false, true, NULL);
7567*e4b17023SJohn Marino break;
7568*e4b17023SJohn Marino }
7569*e4b17023SJohn Marino }
7570*e4b17023SJohn Marino }
7571*e4b17023SJohn Marino
7572*e4b17023SJohn Marino /* Parse an objc-methodproto.
7573*e4b17023SJohn Marino
7574*e4b17023SJohn Marino objc-methodproto:
7575*e4b17023SJohn Marino objc-method-type objc-method-decl ;
7576*e4b17023SJohn Marino */
7577*e4b17023SJohn Marino
7578*e4b17023SJohn Marino static void
c_parser_objc_methodproto(c_parser * parser)7579*e4b17023SJohn Marino c_parser_objc_methodproto (c_parser *parser)
7580*e4b17023SJohn Marino {
7581*e4b17023SJohn Marino bool is_class_method = c_parser_objc_method_type (parser);
7582*e4b17023SJohn Marino tree decl, attributes = NULL_TREE;
7583*e4b17023SJohn Marino
7584*e4b17023SJohn Marino /* Remember protocol qualifiers in prototypes. */
7585*e4b17023SJohn Marino parser->objc_pq_context = true;
7586*e4b17023SJohn Marino decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
7587*e4b17023SJohn Marino NULL);
7588*e4b17023SJohn Marino /* Forget protocol qualifiers now. */
7589*e4b17023SJohn Marino parser->objc_pq_context = false;
7590*e4b17023SJohn Marino
7591*e4b17023SJohn Marino /* Do not allow the presence of attributes to hide an erroneous
7592*e4b17023SJohn Marino method implementation in the interface section. */
7593*e4b17023SJohn Marino if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
7594*e4b17023SJohn Marino {
7595*e4b17023SJohn Marino c_parser_error (parser, "expected %<;%>");
7596*e4b17023SJohn Marino return;
7597*e4b17023SJohn Marino }
7598*e4b17023SJohn Marino
7599*e4b17023SJohn Marino if (decl != error_mark_node)
7600*e4b17023SJohn Marino objc_add_method_declaration (is_class_method, decl, attributes);
7601*e4b17023SJohn Marino
7602*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
7603*e4b17023SJohn Marino }
7604*e4b17023SJohn Marino
7605*e4b17023SJohn Marino /* If we are at a position that method attributes may be present, check that
7606*e4b17023SJohn Marino there are not any parsed already (a syntax error) and then collect any
7607*e4b17023SJohn Marino specified at the current location. Finally, if new attributes were present,
7608*e4b17023SJohn Marino check that the next token is legal ( ';' for decls and '{' for defs). */
7609*e4b17023SJohn Marino
7610*e4b17023SJohn Marino static bool
c_parser_objc_maybe_method_attributes(c_parser * parser,tree * attributes)7611*e4b17023SJohn Marino c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
7612*e4b17023SJohn Marino {
7613*e4b17023SJohn Marino bool bad = false;
7614*e4b17023SJohn Marino if (*attributes)
7615*e4b17023SJohn Marino {
7616*e4b17023SJohn Marino c_parser_error (parser,
7617*e4b17023SJohn Marino "method attributes must be specified at the end only");
7618*e4b17023SJohn Marino *attributes = NULL_TREE;
7619*e4b17023SJohn Marino bad = true;
7620*e4b17023SJohn Marino }
7621*e4b17023SJohn Marino
7622*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
7623*e4b17023SJohn Marino *attributes = c_parser_attributes (parser);
7624*e4b17023SJohn Marino
7625*e4b17023SJohn Marino /* If there were no attributes here, just report any earlier error. */
7626*e4b17023SJohn Marino if (*attributes == NULL_TREE || bad)
7627*e4b17023SJohn Marino return bad;
7628*e4b17023SJohn Marino
7629*e4b17023SJohn Marino /* If the attributes are followed by a ; or {, then just report any earlier
7630*e4b17023SJohn Marino error. */
7631*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_SEMICOLON)
7632*e4b17023SJohn Marino || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7633*e4b17023SJohn Marino return bad;
7634*e4b17023SJohn Marino
7635*e4b17023SJohn Marino /* We've got attributes, but not at the end. */
7636*e4b17023SJohn Marino c_parser_error (parser,
7637*e4b17023SJohn Marino "expected %<;%> or %<{%> after method attribute definition");
7638*e4b17023SJohn Marino return true;
7639*e4b17023SJohn Marino }
7640*e4b17023SJohn Marino
7641*e4b17023SJohn Marino /* Parse an objc-method-decl.
7642*e4b17023SJohn Marino
7643*e4b17023SJohn Marino objc-method-decl:
7644*e4b17023SJohn Marino ( objc-type-name ) objc-selector
7645*e4b17023SJohn Marino objc-selector
7646*e4b17023SJohn Marino ( objc-type-name ) objc-keyword-selector objc-optparmlist
7647*e4b17023SJohn Marino objc-keyword-selector objc-optparmlist
7648*e4b17023SJohn Marino attributes
7649*e4b17023SJohn Marino
7650*e4b17023SJohn Marino objc-keyword-selector:
7651*e4b17023SJohn Marino objc-keyword-decl
7652*e4b17023SJohn Marino objc-keyword-selector objc-keyword-decl
7653*e4b17023SJohn Marino
7654*e4b17023SJohn Marino objc-keyword-decl:
7655*e4b17023SJohn Marino objc-selector : ( objc-type-name ) identifier
7656*e4b17023SJohn Marino objc-selector : identifier
7657*e4b17023SJohn Marino : ( objc-type-name ) identifier
7658*e4b17023SJohn Marino : identifier
7659*e4b17023SJohn Marino
7660*e4b17023SJohn Marino objc-optparmlist:
7661*e4b17023SJohn Marino objc-optparms objc-optellipsis
7662*e4b17023SJohn Marino
7663*e4b17023SJohn Marino objc-optparms:
7664*e4b17023SJohn Marino empty
7665*e4b17023SJohn Marino objc-opt-parms , parameter-declaration
7666*e4b17023SJohn Marino
7667*e4b17023SJohn Marino objc-optellipsis:
7668*e4b17023SJohn Marino empty
7669*e4b17023SJohn Marino , ...
7670*e4b17023SJohn Marino */
7671*e4b17023SJohn Marino
7672*e4b17023SJohn Marino static tree
c_parser_objc_method_decl(c_parser * parser,bool is_class_method,tree * attributes,tree * expr)7673*e4b17023SJohn Marino c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
7674*e4b17023SJohn Marino tree *attributes, tree *expr)
7675*e4b17023SJohn Marino {
7676*e4b17023SJohn Marino tree type = NULL_TREE;
7677*e4b17023SJohn Marino tree sel;
7678*e4b17023SJohn Marino tree parms = NULL_TREE;
7679*e4b17023SJohn Marino bool ellipsis = false;
7680*e4b17023SJohn Marino bool attr_err = false;
7681*e4b17023SJohn Marino
7682*e4b17023SJohn Marino *attributes = NULL_TREE;
7683*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7684*e4b17023SJohn Marino {
7685*e4b17023SJohn Marino c_parser_consume_token (parser);
7686*e4b17023SJohn Marino type = c_parser_objc_type_name (parser);
7687*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7688*e4b17023SJohn Marino }
7689*e4b17023SJohn Marino sel = c_parser_objc_selector (parser);
7690*e4b17023SJohn Marino /* If there is no selector, or a colon follows, we have an
7691*e4b17023SJohn Marino objc-keyword-selector. If there is a selector, and a colon does
7692*e4b17023SJohn Marino not follow, that selector ends the objc-method-decl. */
7693*e4b17023SJohn Marino if (!sel || c_parser_next_token_is (parser, CPP_COLON))
7694*e4b17023SJohn Marino {
7695*e4b17023SJohn Marino tree tsel = sel;
7696*e4b17023SJohn Marino tree list = NULL_TREE;
7697*e4b17023SJohn Marino while (true)
7698*e4b17023SJohn Marino {
7699*e4b17023SJohn Marino tree atype = NULL_TREE, id, keyworddecl;
7700*e4b17023SJohn Marino tree param_attr = NULL_TREE;
7701*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7702*e4b17023SJohn Marino break;
7703*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
7704*e4b17023SJohn Marino {
7705*e4b17023SJohn Marino c_parser_consume_token (parser);
7706*e4b17023SJohn Marino atype = c_parser_objc_type_name (parser);
7707*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
7708*e4b17023SJohn Marino "expected %<)%>");
7709*e4b17023SJohn Marino }
7710*e4b17023SJohn Marino /* New ObjC allows attributes on method parameters. */
7711*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
7712*e4b17023SJohn Marino param_attr = c_parser_attributes (parser);
7713*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7714*e4b17023SJohn Marino {
7715*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7716*e4b17023SJohn Marino return error_mark_node;
7717*e4b17023SJohn Marino }
7718*e4b17023SJohn Marino id = c_parser_peek_token (parser)->value;
7719*e4b17023SJohn Marino c_parser_consume_token (parser);
7720*e4b17023SJohn Marino keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
7721*e4b17023SJohn Marino list = chainon (list, keyworddecl);
7722*e4b17023SJohn Marino tsel = c_parser_objc_selector (parser);
7723*e4b17023SJohn Marino if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
7724*e4b17023SJohn Marino break;
7725*e4b17023SJohn Marino }
7726*e4b17023SJohn Marino
7727*e4b17023SJohn Marino attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
7728*e4b17023SJohn Marino
7729*e4b17023SJohn Marino /* Parse the optional parameter list. Optional Objective-C
7730*e4b17023SJohn Marino method parameters follow the C syntax, and may include '...'
7731*e4b17023SJohn Marino to denote a variable number of arguments. */
7732*e4b17023SJohn Marino parms = make_node (TREE_LIST);
7733*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_COMMA))
7734*e4b17023SJohn Marino {
7735*e4b17023SJohn Marino struct c_parm *parm;
7736*e4b17023SJohn Marino c_parser_consume_token (parser);
7737*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
7738*e4b17023SJohn Marino {
7739*e4b17023SJohn Marino ellipsis = true;
7740*e4b17023SJohn Marino c_parser_consume_token (parser);
7741*e4b17023SJohn Marino attr_err |= c_parser_objc_maybe_method_attributes
7742*e4b17023SJohn Marino (parser, attributes) ;
7743*e4b17023SJohn Marino break;
7744*e4b17023SJohn Marino }
7745*e4b17023SJohn Marino parm = c_parser_parameter_declaration (parser, NULL_TREE);
7746*e4b17023SJohn Marino if (parm == NULL)
7747*e4b17023SJohn Marino break;
7748*e4b17023SJohn Marino parms = chainon (parms,
7749*e4b17023SJohn Marino build_tree_list (NULL_TREE, grokparm (parm, expr)));
7750*e4b17023SJohn Marino }
7751*e4b17023SJohn Marino sel = list;
7752*e4b17023SJohn Marino }
7753*e4b17023SJohn Marino else
7754*e4b17023SJohn Marino attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
7755*e4b17023SJohn Marino
7756*e4b17023SJohn Marino if (sel == NULL)
7757*e4b17023SJohn Marino {
7758*e4b17023SJohn Marino c_parser_error (parser, "objective-c method declaration is expected");
7759*e4b17023SJohn Marino return error_mark_node;
7760*e4b17023SJohn Marino }
7761*e4b17023SJohn Marino
7762*e4b17023SJohn Marino if (attr_err)
7763*e4b17023SJohn Marino return error_mark_node;
7764*e4b17023SJohn Marino
7765*e4b17023SJohn Marino return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
7766*e4b17023SJohn Marino }
7767*e4b17023SJohn Marino
7768*e4b17023SJohn Marino /* Parse an objc-type-name.
7769*e4b17023SJohn Marino
7770*e4b17023SJohn Marino objc-type-name:
7771*e4b17023SJohn Marino objc-type-qualifiers[opt] type-name
7772*e4b17023SJohn Marino objc-type-qualifiers[opt]
7773*e4b17023SJohn Marino
7774*e4b17023SJohn Marino objc-type-qualifiers:
7775*e4b17023SJohn Marino objc-type-qualifier
7776*e4b17023SJohn Marino objc-type-qualifiers objc-type-qualifier
7777*e4b17023SJohn Marino
7778*e4b17023SJohn Marino objc-type-qualifier: one of
7779*e4b17023SJohn Marino in out inout bycopy byref oneway
7780*e4b17023SJohn Marino */
7781*e4b17023SJohn Marino
7782*e4b17023SJohn Marino static tree
c_parser_objc_type_name(c_parser * parser)7783*e4b17023SJohn Marino c_parser_objc_type_name (c_parser *parser)
7784*e4b17023SJohn Marino {
7785*e4b17023SJohn Marino tree quals = NULL_TREE;
7786*e4b17023SJohn Marino struct c_type_name *type_name = NULL;
7787*e4b17023SJohn Marino tree type = NULL_TREE;
7788*e4b17023SJohn Marino while (true)
7789*e4b17023SJohn Marino {
7790*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
7791*e4b17023SJohn Marino if (token->type == CPP_KEYWORD
7792*e4b17023SJohn Marino && (token->keyword == RID_IN
7793*e4b17023SJohn Marino || token->keyword == RID_OUT
7794*e4b17023SJohn Marino || token->keyword == RID_INOUT
7795*e4b17023SJohn Marino || token->keyword == RID_BYCOPY
7796*e4b17023SJohn Marino || token->keyword == RID_BYREF
7797*e4b17023SJohn Marino || token->keyword == RID_ONEWAY))
7798*e4b17023SJohn Marino {
7799*e4b17023SJohn Marino quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
7800*e4b17023SJohn Marino c_parser_consume_token (parser);
7801*e4b17023SJohn Marino }
7802*e4b17023SJohn Marino else
7803*e4b17023SJohn Marino break;
7804*e4b17023SJohn Marino }
7805*e4b17023SJohn Marino if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
7806*e4b17023SJohn Marino type_name = c_parser_type_name (parser);
7807*e4b17023SJohn Marino if (type_name)
7808*e4b17023SJohn Marino type = groktypename (type_name, NULL, NULL);
7809*e4b17023SJohn Marino
7810*e4b17023SJohn Marino /* If the type is unknown, and error has already been produced and
7811*e4b17023SJohn Marino we need to recover from the error. In that case, use NULL_TREE
7812*e4b17023SJohn Marino for the type, as if no type had been specified; this will use the
7813*e4b17023SJohn Marino default type ('id') which is good for error recovery. */
7814*e4b17023SJohn Marino if (type == error_mark_node)
7815*e4b17023SJohn Marino type = NULL_TREE;
7816*e4b17023SJohn Marino
7817*e4b17023SJohn Marino return build_tree_list (quals, type);
7818*e4b17023SJohn Marino }
7819*e4b17023SJohn Marino
7820*e4b17023SJohn Marino /* Parse objc-protocol-refs.
7821*e4b17023SJohn Marino
7822*e4b17023SJohn Marino objc-protocol-refs:
7823*e4b17023SJohn Marino < identifier-list >
7824*e4b17023SJohn Marino */
7825*e4b17023SJohn Marino
7826*e4b17023SJohn Marino static tree
c_parser_objc_protocol_refs(c_parser * parser)7827*e4b17023SJohn Marino c_parser_objc_protocol_refs (c_parser *parser)
7828*e4b17023SJohn Marino {
7829*e4b17023SJohn Marino tree list = NULL_TREE;
7830*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
7831*e4b17023SJohn Marino c_parser_consume_token (parser);
7832*e4b17023SJohn Marino /* Any identifiers, including those declared as type names, are OK
7833*e4b17023SJohn Marino here. */
7834*e4b17023SJohn Marino while (true)
7835*e4b17023SJohn Marino {
7836*e4b17023SJohn Marino tree id;
7837*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
7838*e4b17023SJohn Marino {
7839*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
7840*e4b17023SJohn Marino break;
7841*e4b17023SJohn Marino }
7842*e4b17023SJohn Marino id = c_parser_peek_token (parser)->value;
7843*e4b17023SJohn Marino list = chainon (list, build_tree_list (NULL_TREE, id));
7844*e4b17023SJohn Marino c_parser_consume_token (parser);
7845*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
7846*e4b17023SJohn Marino c_parser_consume_token (parser);
7847*e4b17023SJohn Marino else
7848*e4b17023SJohn Marino break;
7849*e4b17023SJohn Marino }
7850*e4b17023SJohn Marino c_parser_require (parser, CPP_GREATER, "expected %<>%>");
7851*e4b17023SJohn Marino return list;
7852*e4b17023SJohn Marino }
7853*e4b17023SJohn Marino
7854*e4b17023SJohn Marino /* Parse an objc-try-catch-finally-statement.
7855*e4b17023SJohn Marino
7856*e4b17023SJohn Marino objc-try-catch-finally-statement:
7857*e4b17023SJohn Marino @try compound-statement objc-catch-list[opt]
7858*e4b17023SJohn Marino @try compound-statement objc-catch-list[opt] @finally compound-statement
7859*e4b17023SJohn Marino
7860*e4b17023SJohn Marino objc-catch-list:
7861*e4b17023SJohn Marino @catch ( objc-catch-parameter-declaration ) compound-statement
7862*e4b17023SJohn Marino objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
7863*e4b17023SJohn Marino
7864*e4b17023SJohn Marino objc-catch-parameter-declaration:
7865*e4b17023SJohn Marino parameter-declaration
7866*e4b17023SJohn Marino '...'
7867*e4b17023SJohn Marino
7868*e4b17023SJohn Marino where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
7869*e4b17023SJohn Marino
7870*e4b17023SJohn Marino PS: This function is identical to cp_parser_objc_try_catch_finally_statement
7871*e4b17023SJohn Marino for C++. Keep them in sync. */
7872*e4b17023SJohn Marino
7873*e4b17023SJohn Marino static void
c_parser_objc_try_catch_finally_statement(c_parser * parser)7874*e4b17023SJohn Marino c_parser_objc_try_catch_finally_statement (c_parser *parser)
7875*e4b17023SJohn Marino {
7876*e4b17023SJohn Marino location_t location;
7877*e4b17023SJohn Marino tree stmt;
7878*e4b17023SJohn Marino
7879*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
7880*e4b17023SJohn Marino c_parser_consume_token (parser);
7881*e4b17023SJohn Marino location = c_parser_peek_token (parser)->location;
7882*e4b17023SJohn Marino objc_maybe_warn_exceptions (location);
7883*e4b17023SJohn Marino stmt = c_parser_compound_statement (parser);
7884*e4b17023SJohn Marino objc_begin_try_stmt (location, stmt);
7885*e4b17023SJohn Marino
7886*e4b17023SJohn Marino while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
7887*e4b17023SJohn Marino {
7888*e4b17023SJohn Marino struct c_parm *parm;
7889*e4b17023SJohn Marino tree parameter_declaration = error_mark_node;
7890*e4b17023SJohn Marino bool seen_open_paren = false;
7891*e4b17023SJohn Marino
7892*e4b17023SJohn Marino c_parser_consume_token (parser);
7893*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7894*e4b17023SJohn Marino seen_open_paren = true;
7895*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
7896*e4b17023SJohn Marino {
7897*e4b17023SJohn Marino /* We have "@catch (...)" (where the '...' are literally
7898*e4b17023SJohn Marino what is in the code). Skip the '...'.
7899*e4b17023SJohn Marino parameter_declaration is set to NULL_TREE, and
7900*e4b17023SJohn Marino objc_being_catch_clauses() knows that that means
7901*e4b17023SJohn Marino '...'. */
7902*e4b17023SJohn Marino c_parser_consume_token (parser);
7903*e4b17023SJohn Marino parameter_declaration = NULL_TREE;
7904*e4b17023SJohn Marino }
7905*e4b17023SJohn Marino else
7906*e4b17023SJohn Marino {
7907*e4b17023SJohn Marino /* We have "@catch (NSException *exception)" or something
7908*e4b17023SJohn Marino like that. Parse the parameter declaration. */
7909*e4b17023SJohn Marino parm = c_parser_parameter_declaration (parser, NULL_TREE);
7910*e4b17023SJohn Marino if (parm == NULL)
7911*e4b17023SJohn Marino parameter_declaration = error_mark_node;
7912*e4b17023SJohn Marino else
7913*e4b17023SJohn Marino parameter_declaration = grokparm (parm, NULL);
7914*e4b17023SJohn Marino }
7915*e4b17023SJohn Marino if (seen_open_paren)
7916*e4b17023SJohn Marino c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7917*e4b17023SJohn Marino else
7918*e4b17023SJohn Marino {
7919*e4b17023SJohn Marino /* If there was no open parenthesis, we are recovering from
7920*e4b17023SJohn Marino an error, and we are trying to figure out what mistake
7921*e4b17023SJohn Marino the user has made. */
7922*e4b17023SJohn Marino
7923*e4b17023SJohn Marino /* If there is an immediate closing parenthesis, the user
7924*e4b17023SJohn Marino probably forgot the opening one (ie, they typed "@catch
7925*e4b17023SJohn Marino NSException *e)". Parse the closing parenthesis and keep
7926*e4b17023SJohn Marino going. */
7927*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7928*e4b17023SJohn Marino c_parser_consume_token (parser);
7929*e4b17023SJohn Marino
7930*e4b17023SJohn Marino /* If these is no immediate closing parenthesis, the user
7931*e4b17023SJohn Marino probably doesn't know that parenthesis are required at
7932*e4b17023SJohn Marino all (ie, they typed "@catch NSException *e"). So, just
7933*e4b17023SJohn Marino forget about the closing parenthesis and keep going. */
7934*e4b17023SJohn Marino }
7935*e4b17023SJohn Marino objc_begin_catch_clause (parameter_declaration);
7936*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
7937*e4b17023SJohn Marino c_parser_compound_statement_nostart (parser);
7938*e4b17023SJohn Marino objc_finish_catch_clause ();
7939*e4b17023SJohn Marino }
7940*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
7941*e4b17023SJohn Marino {
7942*e4b17023SJohn Marino c_parser_consume_token (parser);
7943*e4b17023SJohn Marino location = c_parser_peek_token (parser)->location;
7944*e4b17023SJohn Marino stmt = c_parser_compound_statement (parser);
7945*e4b17023SJohn Marino objc_build_finally_clause (location, stmt);
7946*e4b17023SJohn Marino }
7947*e4b17023SJohn Marino objc_finish_try_stmt ();
7948*e4b17023SJohn Marino }
7949*e4b17023SJohn Marino
7950*e4b17023SJohn Marino /* Parse an objc-synchronized-statement.
7951*e4b17023SJohn Marino
7952*e4b17023SJohn Marino objc-synchronized-statement:
7953*e4b17023SJohn Marino @synchronized ( expression ) compound-statement
7954*e4b17023SJohn Marino */
7955*e4b17023SJohn Marino
7956*e4b17023SJohn Marino static void
c_parser_objc_synchronized_statement(c_parser * parser)7957*e4b17023SJohn Marino c_parser_objc_synchronized_statement (c_parser *parser)
7958*e4b17023SJohn Marino {
7959*e4b17023SJohn Marino location_t loc;
7960*e4b17023SJohn Marino tree expr, stmt;
7961*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
7962*e4b17023SJohn Marino c_parser_consume_token (parser);
7963*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
7964*e4b17023SJohn Marino objc_maybe_warn_exceptions (loc);
7965*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
7966*e4b17023SJohn Marino {
7967*e4b17023SJohn Marino expr = c_parser_expression (parser).value;
7968*e4b17023SJohn Marino expr = c_fully_fold (expr, false, NULL);
7969*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
7970*e4b17023SJohn Marino }
7971*e4b17023SJohn Marino else
7972*e4b17023SJohn Marino expr = error_mark_node;
7973*e4b17023SJohn Marino stmt = c_parser_compound_statement (parser);
7974*e4b17023SJohn Marino objc_build_synchronized (loc, expr, stmt);
7975*e4b17023SJohn Marino }
7976*e4b17023SJohn Marino
7977*e4b17023SJohn Marino /* Parse an objc-selector; return NULL_TREE without an error if the
7978*e4b17023SJohn Marino next token is not an objc-selector.
7979*e4b17023SJohn Marino
7980*e4b17023SJohn Marino objc-selector:
7981*e4b17023SJohn Marino identifier
7982*e4b17023SJohn Marino one of
7983*e4b17023SJohn Marino enum struct union if else while do for switch case default
7984*e4b17023SJohn Marino break continue return goto asm sizeof typeof __alignof
7985*e4b17023SJohn Marino unsigned long const short volatile signed restrict _Complex
7986*e4b17023SJohn Marino in out inout bycopy byref oneway int char float double void _Bool
7987*e4b17023SJohn Marino
7988*e4b17023SJohn Marino ??? Why this selection of keywords but not, for example, storage
7989*e4b17023SJohn Marino class specifiers? */
7990*e4b17023SJohn Marino
7991*e4b17023SJohn Marino static tree
c_parser_objc_selector(c_parser * parser)7992*e4b17023SJohn Marino c_parser_objc_selector (c_parser *parser)
7993*e4b17023SJohn Marino {
7994*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
7995*e4b17023SJohn Marino tree value = token->value;
7996*e4b17023SJohn Marino if (token->type == CPP_NAME)
7997*e4b17023SJohn Marino {
7998*e4b17023SJohn Marino c_parser_consume_token (parser);
7999*e4b17023SJohn Marino return value;
8000*e4b17023SJohn Marino }
8001*e4b17023SJohn Marino if (token->type != CPP_KEYWORD)
8002*e4b17023SJohn Marino return NULL_TREE;
8003*e4b17023SJohn Marino switch (token->keyword)
8004*e4b17023SJohn Marino {
8005*e4b17023SJohn Marino case RID_ENUM:
8006*e4b17023SJohn Marino case RID_STRUCT:
8007*e4b17023SJohn Marino case RID_UNION:
8008*e4b17023SJohn Marino case RID_IF:
8009*e4b17023SJohn Marino case RID_ELSE:
8010*e4b17023SJohn Marino case RID_WHILE:
8011*e4b17023SJohn Marino case RID_DO:
8012*e4b17023SJohn Marino case RID_FOR:
8013*e4b17023SJohn Marino case RID_SWITCH:
8014*e4b17023SJohn Marino case RID_CASE:
8015*e4b17023SJohn Marino case RID_DEFAULT:
8016*e4b17023SJohn Marino case RID_BREAK:
8017*e4b17023SJohn Marino case RID_CONTINUE:
8018*e4b17023SJohn Marino case RID_RETURN:
8019*e4b17023SJohn Marino case RID_GOTO:
8020*e4b17023SJohn Marino case RID_ASM:
8021*e4b17023SJohn Marino case RID_SIZEOF:
8022*e4b17023SJohn Marino case RID_TYPEOF:
8023*e4b17023SJohn Marino case RID_ALIGNOF:
8024*e4b17023SJohn Marino case RID_UNSIGNED:
8025*e4b17023SJohn Marino case RID_LONG:
8026*e4b17023SJohn Marino case RID_INT128:
8027*e4b17023SJohn Marino case RID_CONST:
8028*e4b17023SJohn Marino case RID_SHORT:
8029*e4b17023SJohn Marino case RID_VOLATILE:
8030*e4b17023SJohn Marino case RID_SIGNED:
8031*e4b17023SJohn Marino case RID_RESTRICT:
8032*e4b17023SJohn Marino case RID_COMPLEX:
8033*e4b17023SJohn Marino case RID_IN:
8034*e4b17023SJohn Marino case RID_OUT:
8035*e4b17023SJohn Marino case RID_INOUT:
8036*e4b17023SJohn Marino case RID_BYCOPY:
8037*e4b17023SJohn Marino case RID_BYREF:
8038*e4b17023SJohn Marino case RID_ONEWAY:
8039*e4b17023SJohn Marino case RID_INT:
8040*e4b17023SJohn Marino case RID_CHAR:
8041*e4b17023SJohn Marino case RID_FLOAT:
8042*e4b17023SJohn Marino case RID_DOUBLE:
8043*e4b17023SJohn Marino case RID_VOID:
8044*e4b17023SJohn Marino case RID_BOOL:
8045*e4b17023SJohn Marino c_parser_consume_token (parser);
8046*e4b17023SJohn Marino return value;
8047*e4b17023SJohn Marino default:
8048*e4b17023SJohn Marino return NULL_TREE;
8049*e4b17023SJohn Marino }
8050*e4b17023SJohn Marino }
8051*e4b17023SJohn Marino
8052*e4b17023SJohn Marino /* Parse an objc-selector-arg.
8053*e4b17023SJohn Marino
8054*e4b17023SJohn Marino objc-selector-arg:
8055*e4b17023SJohn Marino objc-selector
8056*e4b17023SJohn Marino objc-keywordname-list
8057*e4b17023SJohn Marino
8058*e4b17023SJohn Marino objc-keywordname-list:
8059*e4b17023SJohn Marino objc-keywordname
8060*e4b17023SJohn Marino objc-keywordname-list objc-keywordname
8061*e4b17023SJohn Marino
8062*e4b17023SJohn Marino objc-keywordname:
8063*e4b17023SJohn Marino objc-selector :
8064*e4b17023SJohn Marino :
8065*e4b17023SJohn Marino */
8066*e4b17023SJohn Marino
8067*e4b17023SJohn Marino static tree
c_parser_objc_selector_arg(c_parser * parser)8068*e4b17023SJohn Marino c_parser_objc_selector_arg (c_parser *parser)
8069*e4b17023SJohn Marino {
8070*e4b17023SJohn Marino tree sel = c_parser_objc_selector (parser);
8071*e4b17023SJohn Marino tree list = NULL_TREE;
8072*e4b17023SJohn Marino if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
8073*e4b17023SJohn Marino return sel;
8074*e4b17023SJohn Marino while (true)
8075*e4b17023SJohn Marino {
8076*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8077*e4b17023SJohn Marino return list;
8078*e4b17023SJohn Marino list = chainon (list, build_tree_list (sel, NULL_TREE));
8079*e4b17023SJohn Marino sel = c_parser_objc_selector (parser);
8080*e4b17023SJohn Marino if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
8081*e4b17023SJohn Marino break;
8082*e4b17023SJohn Marino }
8083*e4b17023SJohn Marino return list;
8084*e4b17023SJohn Marino }
8085*e4b17023SJohn Marino
8086*e4b17023SJohn Marino /* Parse an objc-receiver.
8087*e4b17023SJohn Marino
8088*e4b17023SJohn Marino objc-receiver:
8089*e4b17023SJohn Marino expression
8090*e4b17023SJohn Marino class-name
8091*e4b17023SJohn Marino type-name
8092*e4b17023SJohn Marino */
8093*e4b17023SJohn Marino
8094*e4b17023SJohn Marino static tree
c_parser_objc_receiver(c_parser * parser)8095*e4b17023SJohn Marino c_parser_objc_receiver (c_parser *parser)
8096*e4b17023SJohn Marino {
8097*e4b17023SJohn Marino if (c_parser_peek_token (parser)->type == CPP_NAME
8098*e4b17023SJohn Marino && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
8099*e4b17023SJohn Marino || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
8100*e4b17023SJohn Marino {
8101*e4b17023SJohn Marino tree id = c_parser_peek_token (parser)->value;
8102*e4b17023SJohn Marino c_parser_consume_token (parser);
8103*e4b17023SJohn Marino return objc_get_class_reference (id);
8104*e4b17023SJohn Marino }
8105*e4b17023SJohn Marino return c_fully_fold (c_parser_expression (parser).value, false, NULL);
8106*e4b17023SJohn Marino }
8107*e4b17023SJohn Marino
8108*e4b17023SJohn Marino /* Parse objc-message-args.
8109*e4b17023SJohn Marino
8110*e4b17023SJohn Marino objc-message-args:
8111*e4b17023SJohn Marino objc-selector
8112*e4b17023SJohn Marino objc-keywordarg-list
8113*e4b17023SJohn Marino
8114*e4b17023SJohn Marino objc-keywordarg-list:
8115*e4b17023SJohn Marino objc-keywordarg
8116*e4b17023SJohn Marino objc-keywordarg-list objc-keywordarg
8117*e4b17023SJohn Marino
8118*e4b17023SJohn Marino objc-keywordarg:
8119*e4b17023SJohn Marino objc-selector : objc-keywordexpr
8120*e4b17023SJohn Marino : objc-keywordexpr
8121*e4b17023SJohn Marino */
8122*e4b17023SJohn Marino
8123*e4b17023SJohn Marino static tree
c_parser_objc_message_args(c_parser * parser)8124*e4b17023SJohn Marino c_parser_objc_message_args (c_parser *parser)
8125*e4b17023SJohn Marino {
8126*e4b17023SJohn Marino tree sel = c_parser_objc_selector (parser);
8127*e4b17023SJohn Marino tree list = NULL_TREE;
8128*e4b17023SJohn Marino if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
8129*e4b17023SJohn Marino return sel;
8130*e4b17023SJohn Marino while (true)
8131*e4b17023SJohn Marino {
8132*e4b17023SJohn Marino tree keywordexpr;
8133*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8134*e4b17023SJohn Marino return error_mark_node;
8135*e4b17023SJohn Marino keywordexpr = c_parser_objc_keywordexpr (parser);
8136*e4b17023SJohn Marino list = chainon (list, build_tree_list (sel, keywordexpr));
8137*e4b17023SJohn Marino sel = c_parser_objc_selector (parser);
8138*e4b17023SJohn Marino if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
8139*e4b17023SJohn Marino break;
8140*e4b17023SJohn Marino }
8141*e4b17023SJohn Marino return list;
8142*e4b17023SJohn Marino }
8143*e4b17023SJohn Marino
8144*e4b17023SJohn Marino /* Parse an objc-keywordexpr.
8145*e4b17023SJohn Marino
8146*e4b17023SJohn Marino objc-keywordexpr:
8147*e4b17023SJohn Marino nonempty-expr-list
8148*e4b17023SJohn Marino */
8149*e4b17023SJohn Marino
8150*e4b17023SJohn Marino static tree
c_parser_objc_keywordexpr(c_parser * parser)8151*e4b17023SJohn Marino c_parser_objc_keywordexpr (c_parser *parser)
8152*e4b17023SJohn Marino {
8153*e4b17023SJohn Marino tree ret;
8154*e4b17023SJohn Marino VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true, NULL);
8155*e4b17023SJohn Marino if (VEC_length (tree, expr_list) == 1)
8156*e4b17023SJohn Marino {
8157*e4b17023SJohn Marino /* Just return the expression, remove a level of
8158*e4b17023SJohn Marino indirection. */
8159*e4b17023SJohn Marino ret = VEC_index (tree, expr_list, 0);
8160*e4b17023SJohn Marino }
8161*e4b17023SJohn Marino else
8162*e4b17023SJohn Marino {
8163*e4b17023SJohn Marino /* We have a comma expression, we will collapse later. */
8164*e4b17023SJohn Marino ret = build_tree_list_vec (expr_list);
8165*e4b17023SJohn Marino }
8166*e4b17023SJohn Marino release_tree_vector (expr_list);
8167*e4b17023SJohn Marino return ret;
8168*e4b17023SJohn Marino }
8169*e4b17023SJohn Marino
8170*e4b17023SJohn Marino /* A check, needed in several places, that ObjC interface, implementation or
8171*e4b17023SJohn Marino method definitions are not prefixed by incorrect items. */
8172*e4b17023SJohn Marino static bool
c_parser_objc_diagnose_bad_element_prefix(c_parser * parser,struct c_declspecs * specs)8173*e4b17023SJohn Marino c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
8174*e4b17023SJohn Marino struct c_declspecs *specs)
8175*e4b17023SJohn Marino {
8176*e4b17023SJohn Marino if (!specs->declspecs_seen_p || specs->non_sc_seen_p
8177*e4b17023SJohn Marino || specs->typespec_kind != ctsk_none)
8178*e4b17023SJohn Marino {
8179*e4b17023SJohn Marino c_parser_error (parser,
8180*e4b17023SJohn Marino "no type or storage class may be specified here,");
8181*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
8182*e4b17023SJohn Marino return true;
8183*e4b17023SJohn Marino }
8184*e4b17023SJohn Marino return false;
8185*e4b17023SJohn Marino }
8186*e4b17023SJohn Marino
8187*e4b17023SJohn Marino /* Parse an Objective-C @property declaration. The syntax is:
8188*e4b17023SJohn Marino
8189*e4b17023SJohn Marino objc-property-declaration:
8190*e4b17023SJohn Marino '@property' objc-property-attributes[opt] struct-declaration ;
8191*e4b17023SJohn Marino
8192*e4b17023SJohn Marino objc-property-attributes:
8193*e4b17023SJohn Marino '(' objc-property-attribute-list ')'
8194*e4b17023SJohn Marino
8195*e4b17023SJohn Marino objc-property-attribute-list:
8196*e4b17023SJohn Marino objc-property-attribute
8197*e4b17023SJohn Marino objc-property-attribute-list, objc-property-attribute
8198*e4b17023SJohn Marino
8199*e4b17023SJohn Marino objc-property-attribute
8200*e4b17023SJohn Marino 'getter' = identifier
8201*e4b17023SJohn Marino 'setter' = identifier
8202*e4b17023SJohn Marino 'readonly'
8203*e4b17023SJohn Marino 'readwrite'
8204*e4b17023SJohn Marino 'assign'
8205*e4b17023SJohn Marino 'retain'
8206*e4b17023SJohn Marino 'copy'
8207*e4b17023SJohn Marino 'nonatomic'
8208*e4b17023SJohn Marino
8209*e4b17023SJohn Marino For example:
8210*e4b17023SJohn Marino @property NSString *name;
8211*e4b17023SJohn Marino @property (readonly) id object;
8212*e4b17023SJohn Marino @property (retain, nonatomic, getter=getTheName) id name;
8213*e4b17023SJohn Marino @property int a, b, c;
8214*e4b17023SJohn Marino
8215*e4b17023SJohn Marino PS: This function is identical to cp_parser_objc_at_propery_declaration
8216*e4b17023SJohn Marino for C++. Keep them in sync. */
8217*e4b17023SJohn Marino static void
c_parser_objc_at_property_declaration(c_parser * parser)8218*e4b17023SJohn Marino c_parser_objc_at_property_declaration (c_parser *parser)
8219*e4b17023SJohn Marino {
8220*e4b17023SJohn Marino /* The following variables hold the attributes of the properties as
8221*e4b17023SJohn Marino parsed. They are 'false' or 'NULL_TREE' if the attribute was not
8222*e4b17023SJohn Marino seen. When we see an attribute, we set them to 'true' (if they
8223*e4b17023SJohn Marino are boolean properties) or to the identifier (if they have an
8224*e4b17023SJohn Marino argument, ie, for getter and setter). Note that here we only
8225*e4b17023SJohn Marino parse the list of attributes, check the syntax and accumulate the
8226*e4b17023SJohn Marino attributes that we find. objc_add_property_declaration() will
8227*e4b17023SJohn Marino then process the information. */
8228*e4b17023SJohn Marino bool property_assign = false;
8229*e4b17023SJohn Marino bool property_copy = false;
8230*e4b17023SJohn Marino tree property_getter_ident = NULL_TREE;
8231*e4b17023SJohn Marino bool property_nonatomic = false;
8232*e4b17023SJohn Marino bool property_readonly = false;
8233*e4b17023SJohn Marino bool property_readwrite = false;
8234*e4b17023SJohn Marino bool property_retain = false;
8235*e4b17023SJohn Marino tree property_setter_ident = NULL_TREE;
8236*e4b17023SJohn Marino
8237*e4b17023SJohn Marino /* 'properties' is the list of properties that we read. Usually a
8238*e4b17023SJohn Marino single one, but maybe more (eg, in "@property int a, b, c;" there
8239*e4b17023SJohn Marino are three). */
8240*e4b17023SJohn Marino tree properties;
8241*e4b17023SJohn Marino location_t loc;
8242*e4b17023SJohn Marino
8243*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
8244*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
8245*e4b17023SJohn Marino
8246*e4b17023SJohn Marino c_parser_consume_token (parser); /* Eat '@property'. */
8247*e4b17023SJohn Marino
8248*e4b17023SJohn Marino /* Parse the optional attribute list... */
8249*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
8250*e4b17023SJohn Marino {
8251*e4b17023SJohn Marino /* Eat the '(' */
8252*e4b17023SJohn Marino c_parser_consume_token (parser);
8253*e4b17023SJohn Marino
8254*e4b17023SJohn Marino /* Property attribute keywords are valid now. */
8255*e4b17023SJohn Marino parser->objc_property_attr_context = true;
8256*e4b17023SJohn Marino
8257*e4b17023SJohn Marino while (true)
8258*e4b17023SJohn Marino {
8259*e4b17023SJohn Marino bool syntax_error = false;
8260*e4b17023SJohn Marino c_token *token = c_parser_peek_token (parser);
8261*e4b17023SJohn Marino enum rid keyword;
8262*e4b17023SJohn Marino
8263*e4b17023SJohn Marino if (token->type != CPP_KEYWORD)
8264*e4b17023SJohn Marino {
8265*e4b17023SJohn Marino if (token->type == CPP_CLOSE_PAREN)
8266*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
8267*e4b17023SJohn Marino else
8268*e4b17023SJohn Marino {
8269*e4b17023SJohn Marino c_parser_consume_token (parser);
8270*e4b17023SJohn Marino c_parser_error (parser, "unknown property attribute");
8271*e4b17023SJohn Marino }
8272*e4b17023SJohn Marino break;
8273*e4b17023SJohn Marino }
8274*e4b17023SJohn Marino keyword = token->keyword;
8275*e4b17023SJohn Marino c_parser_consume_token (parser);
8276*e4b17023SJohn Marino switch (keyword)
8277*e4b17023SJohn Marino {
8278*e4b17023SJohn Marino case RID_ASSIGN: property_assign = true; break;
8279*e4b17023SJohn Marino case RID_COPY: property_copy = true; break;
8280*e4b17023SJohn Marino case RID_NONATOMIC: property_nonatomic = true; break;
8281*e4b17023SJohn Marino case RID_READONLY: property_readonly = true; break;
8282*e4b17023SJohn Marino case RID_READWRITE: property_readwrite = true; break;
8283*e4b17023SJohn Marino case RID_RETAIN: property_retain = true; break;
8284*e4b17023SJohn Marino
8285*e4b17023SJohn Marino case RID_GETTER:
8286*e4b17023SJohn Marino case RID_SETTER:
8287*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_EQ))
8288*e4b17023SJohn Marino {
8289*e4b17023SJohn Marino if (keyword == RID_GETTER)
8290*e4b17023SJohn Marino c_parser_error (parser,
8291*e4b17023SJohn Marino "missing %<=%> (after %<getter%> attribute)");
8292*e4b17023SJohn Marino else
8293*e4b17023SJohn Marino c_parser_error (parser,
8294*e4b17023SJohn Marino "missing %<=%> (after %<setter%> attribute)");
8295*e4b17023SJohn Marino syntax_error = true;
8296*e4b17023SJohn Marino break;
8297*e4b17023SJohn Marino }
8298*e4b17023SJohn Marino c_parser_consume_token (parser); /* eat the = */
8299*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
8300*e4b17023SJohn Marino {
8301*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
8302*e4b17023SJohn Marino syntax_error = true;
8303*e4b17023SJohn Marino break;
8304*e4b17023SJohn Marino }
8305*e4b17023SJohn Marino if (keyword == RID_SETTER)
8306*e4b17023SJohn Marino {
8307*e4b17023SJohn Marino if (property_setter_ident != NULL_TREE)
8308*e4b17023SJohn Marino c_parser_error (parser, "the %<setter%> attribute may only be specified once");
8309*e4b17023SJohn Marino else
8310*e4b17023SJohn Marino property_setter_ident = c_parser_peek_token (parser)->value;
8311*e4b17023SJohn Marino c_parser_consume_token (parser);
8312*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_COLON))
8313*e4b17023SJohn Marino c_parser_error (parser, "setter name must terminate with %<:%>");
8314*e4b17023SJohn Marino else
8315*e4b17023SJohn Marino c_parser_consume_token (parser);
8316*e4b17023SJohn Marino }
8317*e4b17023SJohn Marino else
8318*e4b17023SJohn Marino {
8319*e4b17023SJohn Marino if (property_getter_ident != NULL_TREE)
8320*e4b17023SJohn Marino c_parser_error (parser, "the %<getter%> attribute may only be specified once");
8321*e4b17023SJohn Marino else
8322*e4b17023SJohn Marino property_getter_ident = c_parser_peek_token (parser)->value;
8323*e4b17023SJohn Marino c_parser_consume_token (parser);
8324*e4b17023SJohn Marino }
8325*e4b17023SJohn Marino break;
8326*e4b17023SJohn Marino default:
8327*e4b17023SJohn Marino c_parser_error (parser, "unknown property attribute");
8328*e4b17023SJohn Marino syntax_error = true;
8329*e4b17023SJohn Marino break;
8330*e4b17023SJohn Marino }
8331*e4b17023SJohn Marino
8332*e4b17023SJohn Marino if (syntax_error)
8333*e4b17023SJohn Marino break;
8334*e4b17023SJohn Marino
8335*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
8336*e4b17023SJohn Marino c_parser_consume_token (parser);
8337*e4b17023SJohn Marino else
8338*e4b17023SJohn Marino break;
8339*e4b17023SJohn Marino }
8340*e4b17023SJohn Marino parser->objc_property_attr_context = false;
8341*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8342*e4b17023SJohn Marino }
8343*e4b17023SJohn Marino /* ... and the property declaration(s). */
8344*e4b17023SJohn Marino properties = c_parser_struct_declaration (parser);
8345*e4b17023SJohn Marino
8346*e4b17023SJohn Marino if (properties == error_mark_node)
8347*e4b17023SJohn Marino {
8348*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
8349*e4b17023SJohn Marino parser->error = false;
8350*e4b17023SJohn Marino return;
8351*e4b17023SJohn Marino }
8352*e4b17023SJohn Marino
8353*e4b17023SJohn Marino if (properties == NULL_TREE)
8354*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
8355*e4b17023SJohn Marino else
8356*e4b17023SJohn Marino {
8357*e4b17023SJohn Marino /* Comma-separated properties are chained together in
8358*e4b17023SJohn Marino reverse order; add them one by one. */
8359*e4b17023SJohn Marino properties = nreverse (properties);
8360*e4b17023SJohn Marino
8361*e4b17023SJohn Marino for (; properties; properties = TREE_CHAIN (properties))
8362*e4b17023SJohn Marino objc_add_property_declaration (loc, copy_node (properties),
8363*e4b17023SJohn Marino property_readonly, property_readwrite,
8364*e4b17023SJohn Marino property_assign, property_retain,
8365*e4b17023SJohn Marino property_copy, property_nonatomic,
8366*e4b17023SJohn Marino property_getter_ident, property_setter_ident);
8367*e4b17023SJohn Marino }
8368*e4b17023SJohn Marino
8369*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
8370*e4b17023SJohn Marino parser->error = false;
8371*e4b17023SJohn Marino }
8372*e4b17023SJohn Marino
8373*e4b17023SJohn Marino /* Parse an Objective-C @synthesize declaration. The syntax is:
8374*e4b17023SJohn Marino
8375*e4b17023SJohn Marino objc-synthesize-declaration:
8376*e4b17023SJohn Marino @synthesize objc-synthesize-identifier-list ;
8377*e4b17023SJohn Marino
8378*e4b17023SJohn Marino objc-synthesize-identifier-list:
8379*e4b17023SJohn Marino objc-synthesize-identifier
8380*e4b17023SJohn Marino objc-synthesize-identifier-list, objc-synthesize-identifier
8381*e4b17023SJohn Marino
8382*e4b17023SJohn Marino objc-synthesize-identifier
8383*e4b17023SJohn Marino identifier
8384*e4b17023SJohn Marino identifier = identifier
8385*e4b17023SJohn Marino
8386*e4b17023SJohn Marino For example:
8387*e4b17023SJohn Marino @synthesize MyProperty;
8388*e4b17023SJohn Marino @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
8389*e4b17023SJohn Marino
8390*e4b17023SJohn Marino PS: This function is identical to cp_parser_objc_at_synthesize_declaration
8391*e4b17023SJohn Marino for C++. Keep them in sync.
8392*e4b17023SJohn Marino */
8393*e4b17023SJohn Marino static void
c_parser_objc_at_synthesize_declaration(c_parser * parser)8394*e4b17023SJohn Marino c_parser_objc_at_synthesize_declaration (c_parser *parser)
8395*e4b17023SJohn Marino {
8396*e4b17023SJohn Marino tree list = NULL_TREE;
8397*e4b17023SJohn Marino location_t loc;
8398*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
8399*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
8400*e4b17023SJohn Marino
8401*e4b17023SJohn Marino c_parser_consume_token (parser);
8402*e4b17023SJohn Marino while (true)
8403*e4b17023SJohn Marino {
8404*e4b17023SJohn Marino tree property, ivar;
8405*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
8406*e4b17023SJohn Marino {
8407*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
8408*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
8409*e4b17023SJohn Marino /* Once we find the semicolon, we can resume normal parsing.
8410*e4b17023SJohn Marino We have to reset parser->error manually because
8411*e4b17023SJohn Marino c_parser_skip_until_found() won't reset it for us if the
8412*e4b17023SJohn Marino next token is precisely a semicolon. */
8413*e4b17023SJohn Marino parser->error = false;
8414*e4b17023SJohn Marino return;
8415*e4b17023SJohn Marino }
8416*e4b17023SJohn Marino property = c_parser_peek_token (parser)->value;
8417*e4b17023SJohn Marino c_parser_consume_token (parser);
8418*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_EQ))
8419*e4b17023SJohn Marino {
8420*e4b17023SJohn Marino c_parser_consume_token (parser);
8421*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
8422*e4b17023SJohn Marino {
8423*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
8424*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
8425*e4b17023SJohn Marino parser->error = false;
8426*e4b17023SJohn Marino return;
8427*e4b17023SJohn Marino }
8428*e4b17023SJohn Marino ivar = c_parser_peek_token (parser)->value;
8429*e4b17023SJohn Marino c_parser_consume_token (parser);
8430*e4b17023SJohn Marino }
8431*e4b17023SJohn Marino else
8432*e4b17023SJohn Marino ivar = NULL_TREE;
8433*e4b17023SJohn Marino list = chainon (list, build_tree_list (ivar, property));
8434*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
8435*e4b17023SJohn Marino c_parser_consume_token (parser);
8436*e4b17023SJohn Marino else
8437*e4b17023SJohn Marino break;
8438*e4b17023SJohn Marino }
8439*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
8440*e4b17023SJohn Marino objc_add_synthesize_declaration (loc, list);
8441*e4b17023SJohn Marino }
8442*e4b17023SJohn Marino
8443*e4b17023SJohn Marino /* Parse an Objective-C @dynamic declaration. The syntax is:
8444*e4b17023SJohn Marino
8445*e4b17023SJohn Marino objc-dynamic-declaration:
8446*e4b17023SJohn Marino @dynamic identifier-list ;
8447*e4b17023SJohn Marino
8448*e4b17023SJohn Marino For example:
8449*e4b17023SJohn Marino @dynamic MyProperty;
8450*e4b17023SJohn Marino @dynamic MyProperty, AnotherProperty;
8451*e4b17023SJohn Marino
8452*e4b17023SJohn Marino PS: This function is identical to cp_parser_objc_at_dynamic_declaration
8453*e4b17023SJohn Marino for C++. Keep them in sync.
8454*e4b17023SJohn Marino */
8455*e4b17023SJohn Marino static void
c_parser_objc_at_dynamic_declaration(c_parser * parser)8456*e4b17023SJohn Marino c_parser_objc_at_dynamic_declaration (c_parser *parser)
8457*e4b17023SJohn Marino {
8458*e4b17023SJohn Marino tree list = NULL_TREE;
8459*e4b17023SJohn Marino location_t loc;
8460*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
8461*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
8462*e4b17023SJohn Marino
8463*e4b17023SJohn Marino c_parser_consume_token (parser);
8464*e4b17023SJohn Marino while (true)
8465*e4b17023SJohn Marino {
8466*e4b17023SJohn Marino tree property;
8467*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME))
8468*e4b17023SJohn Marino {
8469*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
8470*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
8471*e4b17023SJohn Marino parser->error = false;
8472*e4b17023SJohn Marino return;
8473*e4b17023SJohn Marino }
8474*e4b17023SJohn Marino property = c_parser_peek_token (parser)->value;
8475*e4b17023SJohn Marino list = chainon (list, build_tree_list (NULL_TREE, property));
8476*e4b17023SJohn Marino c_parser_consume_token (parser);
8477*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
8478*e4b17023SJohn Marino c_parser_consume_token (parser);
8479*e4b17023SJohn Marino else
8480*e4b17023SJohn Marino break;
8481*e4b17023SJohn Marino }
8482*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
8483*e4b17023SJohn Marino objc_add_dynamic_declaration (loc, list);
8484*e4b17023SJohn Marino }
8485*e4b17023SJohn Marino
8486*e4b17023SJohn Marino
8487*e4b17023SJohn Marino /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
8488*e4b17023SJohn Marino should be considered, statements. ALLOW_STMT is true if we're within
8489*e4b17023SJohn Marino the context of a function and such pragmas are to be allowed. Returns
8490*e4b17023SJohn Marino true if we actually parsed such a pragma. */
8491*e4b17023SJohn Marino
8492*e4b17023SJohn Marino static bool
c_parser_pragma(c_parser * parser,enum pragma_context context)8493*e4b17023SJohn Marino c_parser_pragma (c_parser *parser, enum pragma_context context)
8494*e4b17023SJohn Marino {
8495*e4b17023SJohn Marino unsigned int id;
8496*e4b17023SJohn Marino
8497*e4b17023SJohn Marino id = c_parser_peek_token (parser)->pragma_kind;
8498*e4b17023SJohn Marino gcc_assert (id != PRAGMA_NONE);
8499*e4b17023SJohn Marino
8500*e4b17023SJohn Marino switch (id)
8501*e4b17023SJohn Marino {
8502*e4b17023SJohn Marino case PRAGMA_OMP_BARRIER:
8503*e4b17023SJohn Marino if (context != pragma_compound)
8504*e4b17023SJohn Marino {
8505*e4b17023SJohn Marino if (context == pragma_stmt)
8506*e4b17023SJohn Marino c_parser_error (parser, "%<#pragma omp barrier%> may only be "
8507*e4b17023SJohn Marino "used in compound statements");
8508*e4b17023SJohn Marino goto bad_stmt;
8509*e4b17023SJohn Marino }
8510*e4b17023SJohn Marino c_parser_omp_barrier (parser);
8511*e4b17023SJohn Marino return false;
8512*e4b17023SJohn Marino
8513*e4b17023SJohn Marino case PRAGMA_OMP_FLUSH:
8514*e4b17023SJohn Marino if (context != pragma_compound)
8515*e4b17023SJohn Marino {
8516*e4b17023SJohn Marino if (context == pragma_stmt)
8517*e4b17023SJohn Marino c_parser_error (parser, "%<#pragma omp flush%> may only be "
8518*e4b17023SJohn Marino "used in compound statements");
8519*e4b17023SJohn Marino goto bad_stmt;
8520*e4b17023SJohn Marino }
8521*e4b17023SJohn Marino c_parser_omp_flush (parser);
8522*e4b17023SJohn Marino return false;
8523*e4b17023SJohn Marino
8524*e4b17023SJohn Marino case PRAGMA_OMP_TASKWAIT:
8525*e4b17023SJohn Marino if (context != pragma_compound)
8526*e4b17023SJohn Marino {
8527*e4b17023SJohn Marino if (context == pragma_stmt)
8528*e4b17023SJohn Marino c_parser_error (parser, "%<#pragma omp taskwait%> may only be "
8529*e4b17023SJohn Marino "used in compound statements");
8530*e4b17023SJohn Marino goto bad_stmt;
8531*e4b17023SJohn Marino }
8532*e4b17023SJohn Marino c_parser_omp_taskwait (parser);
8533*e4b17023SJohn Marino return false;
8534*e4b17023SJohn Marino
8535*e4b17023SJohn Marino case PRAGMA_OMP_TASKYIELD:
8536*e4b17023SJohn Marino if (context != pragma_compound)
8537*e4b17023SJohn Marino {
8538*e4b17023SJohn Marino if (context == pragma_stmt)
8539*e4b17023SJohn Marino c_parser_error (parser, "%<#pragma omp taskyield%> may only be "
8540*e4b17023SJohn Marino "used in compound statements");
8541*e4b17023SJohn Marino goto bad_stmt;
8542*e4b17023SJohn Marino }
8543*e4b17023SJohn Marino c_parser_omp_taskyield (parser);
8544*e4b17023SJohn Marino return false;
8545*e4b17023SJohn Marino
8546*e4b17023SJohn Marino case PRAGMA_OMP_THREADPRIVATE:
8547*e4b17023SJohn Marino c_parser_omp_threadprivate (parser);
8548*e4b17023SJohn Marino return false;
8549*e4b17023SJohn Marino
8550*e4b17023SJohn Marino case PRAGMA_OMP_SECTION:
8551*e4b17023SJohn Marino error_at (c_parser_peek_token (parser)->location,
8552*e4b17023SJohn Marino "%<#pragma omp section%> may only be used in "
8553*e4b17023SJohn Marino "%<#pragma omp sections%> construct");
8554*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
8555*e4b17023SJohn Marino return false;
8556*e4b17023SJohn Marino
8557*e4b17023SJohn Marino case PRAGMA_GCC_PCH_PREPROCESS:
8558*e4b17023SJohn Marino c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
8559*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
8560*e4b17023SJohn Marino return false;
8561*e4b17023SJohn Marino
8562*e4b17023SJohn Marino default:
8563*e4b17023SJohn Marino if (id < PRAGMA_FIRST_EXTERNAL)
8564*e4b17023SJohn Marino {
8565*e4b17023SJohn Marino if (context == pragma_external)
8566*e4b17023SJohn Marino {
8567*e4b17023SJohn Marino bad_stmt:
8568*e4b17023SJohn Marino c_parser_error (parser, "expected declaration specifiers");
8569*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
8570*e4b17023SJohn Marino return false;
8571*e4b17023SJohn Marino }
8572*e4b17023SJohn Marino c_parser_omp_construct (parser);
8573*e4b17023SJohn Marino return true;
8574*e4b17023SJohn Marino }
8575*e4b17023SJohn Marino break;
8576*e4b17023SJohn Marino }
8577*e4b17023SJohn Marino
8578*e4b17023SJohn Marino c_parser_consume_pragma (parser);
8579*e4b17023SJohn Marino c_invoke_pragma_handler (id);
8580*e4b17023SJohn Marino
8581*e4b17023SJohn Marino /* Skip to EOL, but suppress any error message. Those will have been
8582*e4b17023SJohn Marino generated by the handler routine through calling error, as opposed
8583*e4b17023SJohn Marino to calling c_parser_error. */
8584*e4b17023SJohn Marino parser->error = true;
8585*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
8586*e4b17023SJohn Marino
8587*e4b17023SJohn Marino return false;
8588*e4b17023SJohn Marino }
8589*e4b17023SJohn Marino
8590*e4b17023SJohn Marino /* The interface the pragma parsers have to the lexer. */
8591*e4b17023SJohn Marino
8592*e4b17023SJohn Marino enum cpp_ttype
pragma_lex(tree * value)8593*e4b17023SJohn Marino pragma_lex (tree *value)
8594*e4b17023SJohn Marino {
8595*e4b17023SJohn Marino c_token *tok = c_parser_peek_token (the_parser);
8596*e4b17023SJohn Marino enum cpp_ttype ret = tok->type;
8597*e4b17023SJohn Marino
8598*e4b17023SJohn Marino *value = tok->value;
8599*e4b17023SJohn Marino if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
8600*e4b17023SJohn Marino ret = CPP_EOF;
8601*e4b17023SJohn Marino else
8602*e4b17023SJohn Marino {
8603*e4b17023SJohn Marino if (ret == CPP_KEYWORD)
8604*e4b17023SJohn Marino ret = CPP_NAME;
8605*e4b17023SJohn Marino c_parser_consume_token (the_parser);
8606*e4b17023SJohn Marino }
8607*e4b17023SJohn Marino
8608*e4b17023SJohn Marino return ret;
8609*e4b17023SJohn Marino }
8610*e4b17023SJohn Marino
8611*e4b17023SJohn Marino static void
c_parser_pragma_pch_preprocess(c_parser * parser)8612*e4b17023SJohn Marino c_parser_pragma_pch_preprocess (c_parser *parser)
8613*e4b17023SJohn Marino {
8614*e4b17023SJohn Marino tree name = NULL;
8615*e4b17023SJohn Marino
8616*e4b17023SJohn Marino c_parser_consume_pragma (parser);
8617*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_STRING))
8618*e4b17023SJohn Marino {
8619*e4b17023SJohn Marino name = c_parser_peek_token (parser)->value;
8620*e4b17023SJohn Marino c_parser_consume_token (parser);
8621*e4b17023SJohn Marino }
8622*e4b17023SJohn Marino else
8623*e4b17023SJohn Marino c_parser_error (parser, "expected string literal");
8624*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
8625*e4b17023SJohn Marino
8626*e4b17023SJohn Marino if (name)
8627*e4b17023SJohn Marino c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
8628*e4b17023SJohn Marino }
8629*e4b17023SJohn Marino
8630*e4b17023SJohn Marino /* OpenMP 2.5 parsing routines. */
8631*e4b17023SJohn Marino
8632*e4b17023SJohn Marino /* Returns name of the next clause.
8633*e4b17023SJohn Marino If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
8634*e4b17023SJohn Marino the token is not consumed. Otherwise appropriate pragma_omp_clause is
8635*e4b17023SJohn Marino returned and the token is consumed. */
8636*e4b17023SJohn Marino
8637*e4b17023SJohn Marino static pragma_omp_clause
c_parser_omp_clause_name(c_parser * parser)8638*e4b17023SJohn Marino c_parser_omp_clause_name (c_parser *parser)
8639*e4b17023SJohn Marino {
8640*e4b17023SJohn Marino pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
8641*e4b17023SJohn Marino
8642*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_IF))
8643*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_IF;
8644*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
8645*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_DEFAULT;
8646*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_NAME))
8647*e4b17023SJohn Marino {
8648*e4b17023SJohn Marino const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
8649*e4b17023SJohn Marino
8650*e4b17023SJohn Marino switch (p[0])
8651*e4b17023SJohn Marino {
8652*e4b17023SJohn Marino case 'c':
8653*e4b17023SJohn Marino if (!strcmp ("collapse", p))
8654*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_COLLAPSE;
8655*e4b17023SJohn Marino else if (!strcmp ("copyin", p))
8656*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_COPYIN;
8657*e4b17023SJohn Marino else if (!strcmp ("copyprivate", p))
8658*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
8659*e4b17023SJohn Marino break;
8660*e4b17023SJohn Marino case 'f':
8661*e4b17023SJohn Marino if (!strcmp ("final", p))
8662*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_FINAL;
8663*e4b17023SJohn Marino else if (!strcmp ("firstprivate", p))
8664*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
8665*e4b17023SJohn Marino break;
8666*e4b17023SJohn Marino case 'l':
8667*e4b17023SJohn Marino if (!strcmp ("lastprivate", p))
8668*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
8669*e4b17023SJohn Marino break;
8670*e4b17023SJohn Marino case 'm':
8671*e4b17023SJohn Marino if (!strcmp ("mergeable", p))
8672*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_MERGEABLE;
8673*e4b17023SJohn Marino break;
8674*e4b17023SJohn Marino case 'n':
8675*e4b17023SJohn Marino if (!strcmp ("nowait", p))
8676*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_NOWAIT;
8677*e4b17023SJohn Marino else if (!strcmp ("num_threads", p))
8678*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
8679*e4b17023SJohn Marino break;
8680*e4b17023SJohn Marino case 'o':
8681*e4b17023SJohn Marino if (!strcmp ("ordered", p))
8682*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_ORDERED;
8683*e4b17023SJohn Marino break;
8684*e4b17023SJohn Marino case 'p':
8685*e4b17023SJohn Marino if (!strcmp ("private", p))
8686*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_PRIVATE;
8687*e4b17023SJohn Marino break;
8688*e4b17023SJohn Marino case 'r':
8689*e4b17023SJohn Marino if (!strcmp ("reduction", p))
8690*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_REDUCTION;
8691*e4b17023SJohn Marino break;
8692*e4b17023SJohn Marino case 's':
8693*e4b17023SJohn Marino if (!strcmp ("schedule", p))
8694*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_SCHEDULE;
8695*e4b17023SJohn Marino else if (!strcmp ("shared", p))
8696*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_SHARED;
8697*e4b17023SJohn Marino break;
8698*e4b17023SJohn Marino case 'u':
8699*e4b17023SJohn Marino if (!strcmp ("untied", p))
8700*e4b17023SJohn Marino result = PRAGMA_OMP_CLAUSE_UNTIED;
8701*e4b17023SJohn Marino break;
8702*e4b17023SJohn Marino }
8703*e4b17023SJohn Marino }
8704*e4b17023SJohn Marino
8705*e4b17023SJohn Marino if (result != PRAGMA_OMP_CLAUSE_NONE)
8706*e4b17023SJohn Marino c_parser_consume_token (parser);
8707*e4b17023SJohn Marino
8708*e4b17023SJohn Marino return result;
8709*e4b17023SJohn Marino }
8710*e4b17023SJohn Marino
8711*e4b17023SJohn Marino /* Validate that a clause of the given type does not already exist. */
8712*e4b17023SJohn Marino
8713*e4b17023SJohn Marino static void
check_no_duplicate_clause(tree clauses,enum omp_clause_code code,const char * name)8714*e4b17023SJohn Marino check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
8715*e4b17023SJohn Marino const char *name)
8716*e4b17023SJohn Marino {
8717*e4b17023SJohn Marino tree c;
8718*e4b17023SJohn Marino
8719*e4b17023SJohn Marino for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
8720*e4b17023SJohn Marino if (OMP_CLAUSE_CODE (c) == code)
8721*e4b17023SJohn Marino {
8722*e4b17023SJohn Marino location_t loc = OMP_CLAUSE_LOCATION (c);
8723*e4b17023SJohn Marino error_at (loc, "too many %qs clauses", name);
8724*e4b17023SJohn Marino break;
8725*e4b17023SJohn Marino }
8726*e4b17023SJohn Marino }
8727*e4b17023SJohn Marino
8728*e4b17023SJohn Marino /* OpenMP 2.5:
8729*e4b17023SJohn Marino variable-list:
8730*e4b17023SJohn Marino identifier
8731*e4b17023SJohn Marino variable-list , identifier
8732*e4b17023SJohn Marino
8733*e4b17023SJohn Marino If KIND is nonzero, create the appropriate node and install the
8734*e4b17023SJohn Marino decl in OMP_CLAUSE_DECL and add the node to the head of the list.
8735*e4b17023SJohn Marino If KIND is nonzero, CLAUSE_LOC is the location of the clause.
8736*e4b17023SJohn Marino
8737*e4b17023SJohn Marino If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
8738*e4b17023SJohn Marino return the list created. */
8739*e4b17023SJohn Marino
8740*e4b17023SJohn Marino static tree
c_parser_omp_variable_list(c_parser * parser,location_t clause_loc,enum omp_clause_code kind,tree list)8741*e4b17023SJohn Marino c_parser_omp_variable_list (c_parser *parser,
8742*e4b17023SJohn Marino location_t clause_loc,
8743*e4b17023SJohn Marino enum omp_clause_code kind,
8744*e4b17023SJohn Marino tree list)
8745*e4b17023SJohn Marino {
8746*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_NAME)
8747*e4b17023SJohn Marino || c_parser_peek_token (parser)->id_kind != C_ID_ID)
8748*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
8749*e4b17023SJohn Marino
8750*e4b17023SJohn Marino while (c_parser_next_token_is (parser, CPP_NAME)
8751*e4b17023SJohn Marino && c_parser_peek_token (parser)->id_kind == C_ID_ID)
8752*e4b17023SJohn Marino {
8753*e4b17023SJohn Marino tree t = lookup_name (c_parser_peek_token (parser)->value);
8754*e4b17023SJohn Marino
8755*e4b17023SJohn Marino if (t == NULL_TREE)
8756*e4b17023SJohn Marino undeclared_variable (c_parser_peek_token (parser)->location,
8757*e4b17023SJohn Marino c_parser_peek_token (parser)->value);
8758*e4b17023SJohn Marino else if (t == error_mark_node)
8759*e4b17023SJohn Marino ;
8760*e4b17023SJohn Marino else if (kind != 0)
8761*e4b17023SJohn Marino {
8762*e4b17023SJohn Marino tree u = build_omp_clause (clause_loc, kind);
8763*e4b17023SJohn Marino OMP_CLAUSE_DECL (u) = t;
8764*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (u) = list;
8765*e4b17023SJohn Marino list = u;
8766*e4b17023SJohn Marino }
8767*e4b17023SJohn Marino else
8768*e4b17023SJohn Marino list = tree_cons (t, NULL_TREE, list);
8769*e4b17023SJohn Marino
8770*e4b17023SJohn Marino c_parser_consume_token (parser);
8771*e4b17023SJohn Marino
8772*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_COMMA))
8773*e4b17023SJohn Marino break;
8774*e4b17023SJohn Marino
8775*e4b17023SJohn Marino c_parser_consume_token (parser);
8776*e4b17023SJohn Marino }
8777*e4b17023SJohn Marino
8778*e4b17023SJohn Marino return list;
8779*e4b17023SJohn Marino }
8780*e4b17023SJohn Marino
8781*e4b17023SJohn Marino /* Similarly, but expect leading and trailing parenthesis. This is a very
8782*e4b17023SJohn Marino common case for omp clauses. */
8783*e4b17023SJohn Marino
8784*e4b17023SJohn Marino static tree
c_parser_omp_var_list_parens(c_parser * parser,enum omp_clause_code kind,tree list)8785*e4b17023SJohn Marino c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
8786*e4b17023SJohn Marino tree list)
8787*e4b17023SJohn Marino {
8788*e4b17023SJohn Marino /* The clauses location. */
8789*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
8790*e4b17023SJohn Marino
8791*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
8792*e4b17023SJohn Marino {
8793*e4b17023SJohn Marino list = c_parser_omp_variable_list (parser, loc, kind, list);
8794*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8795*e4b17023SJohn Marino }
8796*e4b17023SJohn Marino return list;
8797*e4b17023SJohn Marino }
8798*e4b17023SJohn Marino
8799*e4b17023SJohn Marino /* OpenMP 3.0:
8800*e4b17023SJohn Marino collapse ( constant-expression ) */
8801*e4b17023SJohn Marino
8802*e4b17023SJohn Marino static tree
c_parser_omp_clause_collapse(c_parser * parser,tree list)8803*e4b17023SJohn Marino c_parser_omp_clause_collapse (c_parser *parser, tree list)
8804*e4b17023SJohn Marino {
8805*e4b17023SJohn Marino tree c, num = error_mark_node;
8806*e4b17023SJohn Marino HOST_WIDE_INT n;
8807*e4b17023SJohn Marino location_t loc;
8808*e4b17023SJohn Marino
8809*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
8810*e4b17023SJohn Marino
8811*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
8812*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
8813*e4b17023SJohn Marino {
8814*e4b17023SJohn Marino num = c_parser_expr_no_commas (parser, NULL).value;
8815*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8816*e4b17023SJohn Marino }
8817*e4b17023SJohn Marino if (num == error_mark_node)
8818*e4b17023SJohn Marino return list;
8819*e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
8820*e4b17023SJohn Marino || !host_integerp (num, 0)
8821*e4b17023SJohn Marino || (n = tree_low_cst (num, 0)) <= 0
8822*e4b17023SJohn Marino || (int) n != n)
8823*e4b17023SJohn Marino {
8824*e4b17023SJohn Marino error_at (loc,
8825*e4b17023SJohn Marino "collapse argument needs positive constant integer expression");
8826*e4b17023SJohn Marino return list;
8827*e4b17023SJohn Marino }
8828*e4b17023SJohn Marino c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
8829*e4b17023SJohn Marino OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
8830*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
8831*e4b17023SJohn Marino return c;
8832*e4b17023SJohn Marino }
8833*e4b17023SJohn Marino
8834*e4b17023SJohn Marino /* OpenMP 2.5:
8835*e4b17023SJohn Marino copyin ( variable-list ) */
8836*e4b17023SJohn Marino
8837*e4b17023SJohn Marino static tree
c_parser_omp_clause_copyin(c_parser * parser,tree list)8838*e4b17023SJohn Marino c_parser_omp_clause_copyin (c_parser *parser, tree list)
8839*e4b17023SJohn Marino {
8840*e4b17023SJohn Marino return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
8841*e4b17023SJohn Marino }
8842*e4b17023SJohn Marino
8843*e4b17023SJohn Marino /* OpenMP 2.5:
8844*e4b17023SJohn Marino copyprivate ( variable-list ) */
8845*e4b17023SJohn Marino
8846*e4b17023SJohn Marino static tree
c_parser_omp_clause_copyprivate(c_parser * parser,tree list)8847*e4b17023SJohn Marino c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
8848*e4b17023SJohn Marino {
8849*e4b17023SJohn Marino return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
8850*e4b17023SJohn Marino }
8851*e4b17023SJohn Marino
8852*e4b17023SJohn Marino /* OpenMP 2.5:
8853*e4b17023SJohn Marino default ( shared | none ) */
8854*e4b17023SJohn Marino
8855*e4b17023SJohn Marino static tree
c_parser_omp_clause_default(c_parser * parser,tree list)8856*e4b17023SJohn Marino c_parser_omp_clause_default (c_parser *parser, tree list)
8857*e4b17023SJohn Marino {
8858*e4b17023SJohn Marino enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
8859*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
8860*e4b17023SJohn Marino tree c;
8861*e4b17023SJohn Marino
8862*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
8863*e4b17023SJohn Marino return list;
8864*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
8865*e4b17023SJohn Marino {
8866*e4b17023SJohn Marino const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
8867*e4b17023SJohn Marino
8868*e4b17023SJohn Marino switch (p[0])
8869*e4b17023SJohn Marino {
8870*e4b17023SJohn Marino case 'n':
8871*e4b17023SJohn Marino if (strcmp ("none", p) != 0)
8872*e4b17023SJohn Marino goto invalid_kind;
8873*e4b17023SJohn Marino kind = OMP_CLAUSE_DEFAULT_NONE;
8874*e4b17023SJohn Marino break;
8875*e4b17023SJohn Marino
8876*e4b17023SJohn Marino case 's':
8877*e4b17023SJohn Marino if (strcmp ("shared", p) != 0)
8878*e4b17023SJohn Marino goto invalid_kind;
8879*e4b17023SJohn Marino kind = OMP_CLAUSE_DEFAULT_SHARED;
8880*e4b17023SJohn Marino break;
8881*e4b17023SJohn Marino
8882*e4b17023SJohn Marino default:
8883*e4b17023SJohn Marino goto invalid_kind;
8884*e4b17023SJohn Marino }
8885*e4b17023SJohn Marino
8886*e4b17023SJohn Marino c_parser_consume_token (parser);
8887*e4b17023SJohn Marino }
8888*e4b17023SJohn Marino else
8889*e4b17023SJohn Marino {
8890*e4b17023SJohn Marino invalid_kind:
8891*e4b17023SJohn Marino c_parser_error (parser, "expected %<none%> or %<shared%>");
8892*e4b17023SJohn Marino }
8893*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
8894*e4b17023SJohn Marino
8895*e4b17023SJohn Marino if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
8896*e4b17023SJohn Marino return list;
8897*e4b17023SJohn Marino
8898*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
8899*e4b17023SJohn Marino c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
8900*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
8901*e4b17023SJohn Marino OMP_CLAUSE_DEFAULT_KIND (c) = kind;
8902*e4b17023SJohn Marino
8903*e4b17023SJohn Marino return c;
8904*e4b17023SJohn Marino }
8905*e4b17023SJohn Marino
8906*e4b17023SJohn Marino /* OpenMP 2.5:
8907*e4b17023SJohn Marino firstprivate ( variable-list ) */
8908*e4b17023SJohn Marino
8909*e4b17023SJohn Marino static tree
c_parser_omp_clause_firstprivate(c_parser * parser,tree list)8910*e4b17023SJohn Marino c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
8911*e4b17023SJohn Marino {
8912*e4b17023SJohn Marino return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
8913*e4b17023SJohn Marino }
8914*e4b17023SJohn Marino
8915*e4b17023SJohn Marino /* OpenMP 3.1:
8916*e4b17023SJohn Marino final ( expression ) */
8917*e4b17023SJohn Marino
8918*e4b17023SJohn Marino static tree
c_parser_omp_clause_final(c_parser * parser,tree list)8919*e4b17023SJohn Marino c_parser_omp_clause_final (c_parser *parser, tree list)
8920*e4b17023SJohn Marino {
8921*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
8922*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
8923*e4b17023SJohn Marino {
8924*e4b17023SJohn Marino tree t = c_parser_paren_condition (parser);
8925*e4b17023SJohn Marino tree c;
8926*e4b17023SJohn Marino
8927*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
8928*e4b17023SJohn Marino
8929*e4b17023SJohn Marino c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
8930*e4b17023SJohn Marino OMP_CLAUSE_FINAL_EXPR (c) = t;
8931*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
8932*e4b17023SJohn Marino list = c;
8933*e4b17023SJohn Marino }
8934*e4b17023SJohn Marino else
8935*e4b17023SJohn Marino c_parser_error (parser, "expected %<(%>");
8936*e4b17023SJohn Marino
8937*e4b17023SJohn Marino return list;
8938*e4b17023SJohn Marino }
8939*e4b17023SJohn Marino
8940*e4b17023SJohn Marino /* OpenMP 2.5:
8941*e4b17023SJohn Marino if ( expression ) */
8942*e4b17023SJohn Marino
8943*e4b17023SJohn Marino static tree
c_parser_omp_clause_if(c_parser * parser,tree list)8944*e4b17023SJohn Marino c_parser_omp_clause_if (c_parser *parser, tree list)
8945*e4b17023SJohn Marino {
8946*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
8947*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
8948*e4b17023SJohn Marino {
8949*e4b17023SJohn Marino tree t = c_parser_paren_condition (parser);
8950*e4b17023SJohn Marino tree c;
8951*e4b17023SJohn Marino
8952*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
8953*e4b17023SJohn Marino
8954*e4b17023SJohn Marino c = build_omp_clause (loc, OMP_CLAUSE_IF);
8955*e4b17023SJohn Marino OMP_CLAUSE_IF_EXPR (c) = t;
8956*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
8957*e4b17023SJohn Marino list = c;
8958*e4b17023SJohn Marino }
8959*e4b17023SJohn Marino else
8960*e4b17023SJohn Marino c_parser_error (parser, "expected %<(%>");
8961*e4b17023SJohn Marino
8962*e4b17023SJohn Marino return list;
8963*e4b17023SJohn Marino }
8964*e4b17023SJohn Marino
8965*e4b17023SJohn Marino /* OpenMP 2.5:
8966*e4b17023SJohn Marino lastprivate ( variable-list ) */
8967*e4b17023SJohn Marino
8968*e4b17023SJohn Marino static tree
c_parser_omp_clause_lastprivate(c_parser * parser,tree list)8969*e4b17023SJohn Marino c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
8970*e4b17023SJohn Marino {
8971*e4b17023SJohn Marino return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LASTPRIVATE, list);
8972*e4b17023SJohn Marino }
8973*e4b17023SJohn Marino
8974*e4b17023SJohn Marino /* OpenMP 3.1:
8975*e4b17023SJohn Marino mergeable */
8976*e4b17023SJohn Marino
8977*e4b17023SJohn Marino static tree
c_parser_omp_clause_mergeable(c_parser * parser ATTRIBUTE_UNUSED,tree list)8978*e4b17023SJohn Marino c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
8979*e4b17023SJohn Marino {
8980*e4b17023SJohn Marino tree c;
8981*e4b17023SJohn Marino
8982*e4b17023SJohn Marino /* FIXME: Should we allow duplicates? */
8983*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
8984*e4b17023SJohn Marino
8985*e4b17023SJohn Marino c = build_omp_clause (c_parser_peek_token (parser)->location,
8986*e4b17023SJohn Marino OMP_CLAUSE_MERGEABLE);
8987*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
8988*e4b17023SJohn Marino
8989*e4b17023SJohn Marino return c;
8990*e4b17023SJohn Marino }
8991*e4b17023SJohn Marino
8992*e4b17023SJohn Marino /* OpenMP 2.5:
8993*e4b17023SJohn Marino nowait */
8994*e4b17023SJohn Marino
8995*e4b17023SJohn Marino static tree
c_parser_omp_clause_nowait(c_parser * parser ATTRIBUTE_UNUSED,tree list)8996*e4b17023SJohn Marino c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
8997*e4b17023SJohn Marino {
8998*e4b17023SJohn Marino tree c;
8999*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
9000*e4b17023SJohn Marino
9001*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
9002*e4b17023SJohn Marino
9003*e4b17023SJohn Marino c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
9004*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
9005*e4b17023SJohn Marino return c;
9006*e4b17023SJohn Marino }
9007*e4b17023SJohn Marino
9008*e4b17023SJohn Marino /* OpenMP 2.5:
9009*e4b17023SJohn Marino num_threads ( expression ) */
9010*e4b17023SJohn Marino
9011*e4b17023SJohn Marino static tree
c_parser_omp_clause_num_threads(c_parser * parser,tree list)9012*e4b17023SJohn Marino c_parser_omp_clause_num_threads (c_parser *parser, tree list)
9013*e4b17023SJohn Marino {
9014*e4b17023SJohn Marino location_t num_threads_loc = c_parser_peek_token (parser)->location;
9015*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
9016*e4b17023SJohn Marino {
9017*e4b17023SJohn Marino location_t expr_loc = c_parser_peek_token (parser)->location;
9018*e4b17023SJohn Marino tree c, t = c_parser_expression (parser).value;
9019*e4b17023SJohn Marino mark_exp_read (t);
9020*e4b17023SJohn Marino t = c_fully_fold (t, false, NULL);
9021*e4b17023SJohn Marino
9022*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9023*e4b17023SJohn Marino
9024*e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
9025*e4b17023SJohn Marino {
9026*e4b17023SJohn Marino c_parser_error (parser, "expected integer expression");
9027*e4b17023SJohn Marino return list;
9028*e4b17023SJohn Marino }
9029*e4b17023SJohn Marino
9030*e4b17023SJohn Marino /* Attempt to statically determine when the number isn't positive. */
9031*e4b17023SJohn Marino c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
9032*e4b17023SJohn Marino build_int_cst (TREE_TYPE (t), 0));
9033*e4b17023SJohn Marino if (CAN_HAVE_LOCATION_P (c))
9034*e4b17023SJohn Marino SET_EXPR_LOCATION (c, expr_loc);
9035*e4b17023SJohn Marino if (c == boolean_true_node)
9036*e4b17023SJohn Marino {
9037*e4b17023SJohn Marino warning_at (expr_loc, 0,
9038*e4b17023SJohn Marino "%<num_threads%> value must be positive");
9039*e4b17023SJohn Marino t = integer_one_node;
9040*e4b17023SJohn Marino }
9041*e4b17023SJohn Marino
9042*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
9043*e4b17023SJohn Marino
9044*e4b17023SJohn Marino c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
9045*e4b17023SJohn Marino OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
9046*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
9047*e4b17023SJohn Marino list = c;
9048*e4b17023SJohn Marino }
9049*e4b17023SJohn Marino
9050*e4b17023SJohn Marino return list;
9051*e4b17023SJohn Marino }
9052*e4b17023SJohn Marino
9053*e4b17023SJohn Marino /* OpenMP 2.5:
9054*e4b17023SJohn Marino ordered */
9055*e4b17023SJohn Marino
9056*e4b17023SJohn Marino static tree
c_parser_omp_clause_ordered(c_parser * parser,tree list)9057*e4b17023SJohn Marino c_parser_omp_clause_ordered (c_parser *parser, tree list)
9058*e4b17023SJohn Marino {
9059*e4b17023SJohn Marino tree c;
9060*e4b17023SJohn Marino
9061*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
9062*e4b17023SJohn Marino
9063*e4b17023SJohn Marino c = build_omp_clause (c_parser_peek_token (parser)->location,
9064*e4b17023SJohn Marino OMP_CLAUSE_ORDERED);
9065*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
9066*e4b17023SJohn Marino
9067*e4b17023SJohn Marino return c;
9068*e4b17023SJohn Marino }
9069*e4b17023SJohn Marino
9070*e4b17023SJohn Marino /* OpenMP 2.5:
9071*e4b17023SJohn Marino private ( variable-list ) */
9072*e4b17023SJohn Marino
9073*e4b17023SJohn Marino static tree
c_parser_omp_clause_private(c_parser * parser,tree list)9074*e4b17023SJohn Marino c_parser_omp_clause_private (c_parser *parser, tree list)
9075*e4b17023SJohn Marino {
9076*e4b17023SJohn Marino return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
9077*e4b17023SJohn Marino }
9078*e4b17023SJohn Marino
9079*e4b17023SJohn Marino /* OpenMP 2.5:
9080*e4b17023SJohn Marino reduction ( reduction-operator : variable-list )
9081*e4b17023SJohn Marino
9082*e4b17023SJohn Marino reduction-operator:
9083*e4b17023SJohn Marino One of: + * - & ^ | && ||
9084*e4b17023SJohn Marino
9085*e4b17023SJohn Marino OpenMP 3.1:
9086*e4b17023SJohn Marino
9087*e4b17023SJohn Marino reduction-operator:
9088*e4b17023SJohn Marino One of: + * - & ^ | && || max min */
9089*e4b17023SJohn Marino
9090*e4b17023SJohn Marino static tree
c_parser_omp_clause_reduction(c_parser * parser,tree list)9091*e4b17023SJohn Marino c_parser_omp_clause_reduction (c_parser *parser, tree list)
9092*e4b17023SJohn Marino {
9093*e4b17023SJohn Marino location_t clause_loc = c_parser_peek_token (parser)->location;
9094*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
9095*e4b17023SJohn Marino {
9096*e4b17023SJohn Marino enum tree_code code;
9097*e4b17023SJohn Marino
9098*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
9099*e4b17023SJohn Marino {
9100*e4b17023SJohn Marino case CPP_PLUS:
9101*e4b17023SJohn Marino code = PLUS_EXPR;
9102*e4b17023SJohn Marino break;
9103*e4b17023SJohn Marino case CPP_MULT:
9104*e4b17023SJohn Marino code = MULT_EXPR;
9105*e4b17023SJohn Marino break;
9106*e4b17023SJohn Marino case CPP_MINUS:
9107*e4b17023SJohn Marino code = MINUS_EXPR;
9108*e4b17023SJohn Marino break;
9109*e4b17023SJohn Marino case CPP_AND:
9110*e4b17023SJohn Marino code = BIT_AND_EXPR;
9111*e4b17023SJohn Marino break;
9112*e4b17023SJohn Marino case CPP_XOR:
9113*e4b17023SJohn Marino code = BIT_XOR_EXPR;
9114*e4b17023SJohn Marino break;
9115*e4b17023SJohn Marino case CPP_OR:
9116*e4b17023SJohn Marino code = BIT_IOR_EXPR;
9117*e4b17023SJohn Marino break;
9118*e4b17023SJohn Marino case CPP_AND_AND:
9119*e4b17023SJohn Marino code = TRUTH_ANDIF_EXPR;
9120*e4b17023SJohn Marino break;
9121*e4b17023SJohn Marino case CPP_OR_OR:
9122*e4b17023SJohn Marino code = TRUTH_ORIF_EXPR;
9123*e4b17023SJohn Marino break;
9124*e4b17023SJohn Marino case CPP_NAME:
9125*e4b17023SJohn Marino {
9126*e4b17023SJohn Marino const char *p
9127*e4b17023SJohn Marino = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
9128*e4b17023SJohn Marino if (strcmp (p, "min") == 0)
9129*e4b17023SJohn Marino {
9130*e4b17023SJohn Marino code = MIN_EXPR;
9131*e4b17023SJohn Marino break;
9132*e4b17023SJohn Marino }
9133*e4b17023SJohn Marino if (strcmp (p, "max") == 0)
9134*e4b17023SJohn Marino {
9135*e4b17023SJohn Marino code = MAX_EXPR;
9136*e4b17023SJohn Marino break;
9137*e4b17023SJohn Marino }
9138*e4b17023SJohn Marino }
9139*e4b17023SJohn Marino /* FALLTHRU */
9140*e4b17023SJohn Marino default:
9141*e4b17023SJohn Marino c_parser_error (parser,
9142*e4b17023SJohn Marino "expected %<+%>, %<*%>, %<-%>, %<&%>, "
9143*e4b17023SJohn Marino "%<^%>, %<|%>, %<&&%>, %<||%>, %<min%> or %<max%>");
9144*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
9145*e4b17023SJohn Marino return list;
9146*e4b17023SJohn Marino }
9147*e4b17023SJohn Marino c_parser_consume_token (parser);
9148*e4b17023SJohn Marino if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
9149*e4b17023SJohn Marino {
9150*e4b17023SJohn Marino tree nl, c;
9151*e4b17023SJohn Marino
9152*e4b17023SJohn Marino nl = c_parser_omp_variable_list (parser, clause_loc,
9153*e4b17023SJohn Marino OMP_CLAUSE_REDUCTION, list);
9154*e4b17023SJohn Marino for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
9155*e4b17023SJohn Marino OMP_CLAUSE_REDUCTION_CODE (c) = code;
9156*e4b17023SJohn Marino
9157*e4b17023SJohn Marino list = nl;
9158*e4b17023SJohn Marino }
9159*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9160*e4b17023SJohn Marino }
9161*e4b17023SJohn Marino return list;
9162*e4b17023SJohn Marino }
9163*e4b17023SJohn Marino
9164*e4b17023SJohn Marino /* OpenMP 2.5:
9165*e4b17023SJohn Marino schedule ( schedule-kind )
9166*e4b17023SJohn Marino schedule ( schedule-kind , expression )
9167*e4b17023SJohn Marino
9168*e4b17023SJohn Marino schedule-kind:
9169*e4b17023SJohn Marino static | dynamic | guided | runtime | auto
9170*e4b17023SJohn Marino */
9171*e4b17023SJohn Marino
9172*e4b17023SJohn Marino static tree
c_parser_omp_clause_schedule(c_parser * parser,tree list)9173*e4b17023SJohn Marino c_parser_omp_clause_schedule (c_parser *parser, tree list)
9174*e4b17023SJohn Marino {
9175*e4b17023SJohn Marino tree c, t;
9176*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
9177*e4b17023SJohn Marino
9178*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
9179*e4b17023SJohn Marino return list;
9180*e4b17023SJohn Marino
9181*e4b17023SJohn Marino c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
9182*e4b17023SJohn Marino
9183*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
9184*e4b17023SJohn Marino {
9185*e4b17023SJohn Marino tree kind = c_parser_peek_token (parser)->value;
9186*e4b17023SJohn Marino const char *p = IDENTIFIER_POINTER (kind);
9187*e4b17023SJohn Marino
9188*e4b17023SJohn Marino switch (p[0])
9189*e4b17023SJohn Marino {
9190*e4b17023SJohn Marino case 'd':
9191*e4b17023SJohn Marino if (strcmp ("dynamic", p) != 0)
9192*e4b17023SJohn Marino goto invalid_kind;
9193*e4b17023SJohn Marino OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
9194*e4b17023SJohn Marino break;
9195*e4b17023SJohn Marino
9196*e4b17023SJohn Marino case 'g':
9197*e4b17023SJohn Marino if (strcmp ("guided", p) != 0)
9198*e4b17023SJohn Marino goto invalid_kind;
9199*e4b17023SJohn Marino OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
9200*e4b17023SJohn Marino break;
9201*e4b17023SJohn Marino
9202*e4b17023SJohn Marino case 'r':
9203*e4b17023SJohn Marino if (strcmp ("runtime", p) != 0)
9204*e4b17023SJohn Marino goto invalid_kind;
9205*e4b17023SJohn Marino OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
9206*e4b17023SJohn Marino break;
9207*e4b17023SJohn Marino
9208*e4b17023SJohn Marino default:
9209*e4b17023SJohn Marino goto invalid_kind;
9210*e4b17023SJohn Marino }
9211*e4b17023SJohn Marino }
9212*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
9213*e4b17023SJohn Marino OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
9214*e4b17023SJohn Marino else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
9215*e4b17023SJohn Marino OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
9216*e4b17023SJohn Marino else
9217*e4b17023SJohn Marino goto invalid_kind;
9218*e4b17023SJohn Marino
9219*e4b17023SJohn Marino c_parser_consume_token (parser);
9220*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_COMMA))
9221*e4b17023SJohn Marino {
9222*e4b17023SJohn Marino location_t here;
9223*e4b17023SJohn Marino c_parser_consume_token (parser);
9224*e4b17023SJohn Marino
9225*e4b17023SJohn Marino here = c_parser_peek_token (parser)->location;
9226*e4b17023SJohn Marino t = c_parser_expr_no_commas (parser, NULL).value;
9227*e4b17023SJohn Marino mark_exp_read (t);
9228*e4b17023SJohn Marino t = c_fully_fold (t, false, NULL);
9229*e4b17023SJohn Marino
9230*e4b17023SJohn Marino if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
9231*e4b17023SJohn Marino error_at (here, "schedule %<runtime%> does not take "
9232*e4b17023SJohn Marino "a %<chunk_size%> parameter");
9233*e4b17023SJohn Marino else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
9234*e4b17023SJohn Marino error_at (here,
9235*e4b17023SJohn Marino "schedule %<auto%> does not take "
9236*e4b17023SJohn Marino "a %<chunk_size%> parameter");
9237*e4b17023SJohn Marino else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
9238*e4b17023SJohn Marino OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
9239*e4b17023SJohn Marino else
9240*e4b17023SJohn Marino c_parser_error (parser, "expected integer expression");
9241*e4b17023SJohn Marino
9242*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9243*e4b17023SJohn Marino }
9244*e4b17023SJohn Marino else
9245*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9246*e4b17023SJohn Marino "expected %<,%> or %<)%>");
9247*e4b17023SJohn Marino
9248*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
9249*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
9250*e4b17023SJohn Marino return c;
9251*e4b17023SJohn Marino
9252*e4b17023SJohn Marino invalid_kind:
9253*e4b17023SJohn Marino c_parser_error (parser, "invalid schedule kind");
9254*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
9255*e4b17023SJohn Marino return list;
9256*e4b17023SJohn Marino }
9257*e4b17023SJohn Marino
9258*e4b17023SJohn Marino /* OpenMP 2.5:
9259*e4b17023SJohn Marino shared ( variable-list ) */
9260*e4b17023SJohn Marino
9261*e4b17023SJohn Marino static tree
c_parser_omp_clause_shared(c_parser * parser,tree list)9262*e4b17023SJohn Marino c_parser_omp_clause_shared (c_parser *parser, tree list)
9263*e4b17023SJohn Marino {
9264*e4b17023SJohn Marino return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
9265*e4b17023SJohn Marino }
9266*e4b17023SJohn Marino
9267*e4b17023SJohn Marino /* OpenMP 3.0:
9268*e4b17023SJohn Marino untied */
9269*e4b17023SJohn Marino
9270*e4b17023SJohn Marino static tree
c_parser_omp_clause_untied(c_parser * parser ATTRIBUTE_UNUSED,tree list)9271*e4b17023SJohn Marino c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
9272*e4b17023SJohn Marino {
9273*e4b17023SJohn Marino tree c;
9274*e4b17023SJohn Marino
9275*e4b17023SJohn Marino /* FIXME: Should we allow duplicates? */
9276*e4b17023SJohn Marino check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
9277*e4b17023SJohn Marino
9278*e4b17023SJohn Marino c = build_omp_clause (c_parser_peek_token (parser)->location,
9279*e4b17023SJohn Marino OMP_CLAUSE_UNTIED);
9280*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (c) = list;
9281*e4b17023SJohn Marino
9282*e4b17023SJohn Marino return c;
9283*e4b17023SJohn Marino }
9284*e4b17023SJohn Marino
9285*e4b17023SJohn Marino /* Parse all OpenMP clauses. The set clauses allowed by the directive
9286*e4b17023SJohn Marino is a bitmask in MASK. Return the list of clauses found; the result
9287*e4b17023SJohn Marino of clause default goes in *pdefault. */
9288*e4b17023SJohn Marino
9289*e4b17023SJohn Marino static tree
c_parser_omp_all_clauses(c_parser * parser,unsigned int mask,const char * where)9290*e4b17023SJohn Marino c_parser_omp_all_clauses (c_parser *parser, unsigned int mask,
9291*e4b17023SJohn Marino const char *where)
9292*e4b17023SJohn Marino {
9293*e4b17023SJohn Marino tree clauses = NULL;
9294*e4b17023SJohn Marino bool first = true;
9295*e4b17023SJohn Marino
9296*e4b17023SJohn Marino while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
9297*e4b17023SJohn Marino {
9298*e4b17023SJohn Marino location_t here;
9299*e4b17023SJohn Marino pragma_omp_clause c_kind;
9300*e4b17023SJohn Marino const char *c_name;
9301*e4b17023SJohn Marino tree prev = clauses;
9302*e4b17023SJohn Marino
9303*e4b17023SJohn Marino if (!first && c_parser_next_token_is (parser, CPP_COMMA))
9304*e4b17023SJohn Marino c_parser_consume_token (parser);
9305*e4b17023SJohn Marino
9306*e4b17023SJohn Marino first = false;
9307*e4b17023SJohn Marino here = c_parser_peek_token (parser)->location;
9308*e4b17023SJohn Marino c_kind = c_parser_omp_clause_name (parser);
9309*e4b17023SJohn Marino
9310*e4b17023SJohn Marino switch (c_kind)
9311*e4b17023SJohn Marino {
9312*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_COLLAPSE:
9313*e4b17023SJohn Marino clauses = c_parser_omp_clause_collapse (parser, clauses);
9314*e4b17023SJohn Marino c_name = "collapse";
9315*e4b17023SJohn Marino break;
9316*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_COPYIN:
9317*e4b17023SJohn Marino clauses = c_parser_omp_clause_copyin (parser, clauses);
9318*e4b17023SJohn Marino c_name = "copyin";
9319*e4b17023SJohn Marino break;
9320*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
9321*e4b17023SJohn Marino clauses = c_parser_omp_clause_copyprivate (parser, clauses);
9322*e4b17023SJohn Marino c_name = "copyprivate";
9323*e4b17023SJohn Marino break;
9324*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_DEFAULT:
9325*e4b17023SJohn Marino clauses = c_parser_omp_clause_default (parser, clauses);
9326*e4b17023SJohn Marino c_name = "default";
9327*e4b17023SJohn Marino break;
9328*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
9329*e4b17023SJohn Marino clauses = c_parser_omp_clause_firstprivate (parser, clauses);
9330*e4b17023SJohn Marino c_name = "firstprivate";
9331*e4b17023SJohn Marino break;
9332*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_FINAL:
9333*e4b17023SJohn Marino clauses = c_parser_omp_clause_final (parser, clauses);
9334*e4b17023SJohn Marino c_name = "final";
9335*e4b17023SJohn Marino break;
9336*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_IF:
9337*e4b17023SJohn Marino clauses = c_parser_omp_clause_if (parser, clauses);
9338*e4b17023SJohn Marino c_name = "if";
9339*e4b17023SJohn Marino break;
9340*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
9341*e4b17023SJohn Marino clauses = c_parser_omp_clause_lastprivate (parser, clauses);
9342*e4b17023SJohn Marino c_name = "lastprivate";
9343*e4b17023SJohn Marino break;
9344*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_MERGEABLE:
9345*e4b17023SJohn Marino clauses = c_parser_omp_clause_mergeable (parser, clauses);
9346*e4b17023SJohn Marino c_name = "mergeable";
9347*e4b17023SJohn Marino break;
9348*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_NOWAIT:
9349*e4b17023SJohn Marino clauses = c_parser_omp_clause_nowait (parser, clauses);
9350*e4b17023SJohn Marino c_name = "nowait";
9351*e4b17023SJohn Marino break;
9352*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_NUM_THREADS:
9353*e4b17023SJohn Marino clauses = c_parser_omp_clause_num_threads (parser, clauses);
9354*e4b17023SJohn Marino c_name = "num_threads";
9355*e4b17023SJohn Marino break;
9356*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_ORDERED:
9357*e4b17023SJohn Marino clauses = c_parser_omp_clause_ordered (parser, clauses);
9358*e4b17023SJohn Marino c_name = "ordered";
9359*e4b17023SJohn Marino break;
9360*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_PRIVATE:
9361*e4b17023SJohn Marino clauses = c_parser_omp_clause_private (parser, clauses);
9362*e4b17023SJohn Marino c_name = "private";
9363*e4b17023SJohn Marino break;
9364*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_REDUCTION:
9365*e4b17023SJohn Marino clauses = c_parser_omp_clause_reduction (parser, clauses);
9366*e4b17023SJohn Marino c_name = "reduction";
9367*e4b17023SJohn Marino break;
9368*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_SCHEDULE:
9369*e4b17023SJohn Marino clauses = c_parser_omp_clause_schedule (parser, clauses);
9370*e4b17023SJohn Marino c_name = "schedule";
9371*e4b17023SJohn Marino break;
9372*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_SHARED:
9373*e4b17023SJohn Marino clauses = c_parser_omp_clause_shared (parser, clauses);
9374*e4b17023SJohn Marino c_name = "shared";
9375*e4b17023SJohn Marino break;
9376*e4b17023SJohn Marino case PRAGMA_OMP_CLAUSE_UNTIED:
9377*e4b17023SJohn Marino clauses = c_parser_omp_clause_untied (parser, clauses);
9378*e4b17023SJohn Marino c_name = "untied";
9379*e4b17023SJohn Marino break;
9380*e4b17023SJohn Marino default:
9381*e4b17023SJohn Marino c_parser_error (parser, "expected %<#pragma omp%> clause");
9382*e4b17023SJohn Marino goto saw_error;
9383*e4b17023SJohn Marino }
9384*e4b17023SJohn Marino
9385*e4b17023SJohn Marino if (((mask >> c_kind) & 1) == 0 && !parser->error)
9386*e4b17023SJohn Marino {
9387*e4b17023SJohn Marino /* Remove the invalid clause(s) from the list to avoid
9388*e4b17023SJohn Marino confusing the rest of the compiler. */
9389*e4b17023SJohn Marino clauses = prev;
9390*e4b17023SJohn Marino error_at (here, "%qs is not valid for %qs", c_name, where);
9391*e4b17023SJohn Marino }
9392*e4b17023SJohn Marino }
9393*e4b17023SJohn Marino
9394*e4b17023SJohn Marino saw_error:
9395*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
9396*e4b17023SJohn Marino
9397*e4b17023SJohn Marino return c_finish_omp_clauses (clauses);
9398*e4b17023SJohn Marino }
9399*e4b17023SJohn Marino
9400*e4b17023SJohn Marino /* OpenMP 2.5:
9401*e4b17023SJohn Marino structured-block:
9402*e4b17023SJohn Marino statement
9403*e4b17023SJohn Marino
9404*e4b17023SJohn Marino In practice, we're also interested in adding the statement to an
9405*e4b17023SJohn Marino outer node. So it is convenient if we work around the fact that
9406*e4b17023SJohn Marino c_parser_statement calls add_stmt. */
9407*e4b17023SJohn Marino
9408*e4b17023SJohn Marino static tree
c_parser_omp_structured_block(c_parser * parser)9409*e4b17023SJohn Marino c_parser_omp_structured_block (c_parser *parser)
9410*e4b17023SJohn Marino {
9411*e4b17023SJohn Marino tree stmt = push_stmt_list ();
9412*e4b17023SJohn Marino c_parser_statement (parser);
9413*e4b17023SJohn Marino return pop_stmt_list (stmt);
9414*e4b17023SJohn Marino }
9415*e4b17023SJohn Marino
9416*e4b17023SJohn Marino /* OpenMP 2.5:
9417*e4b17023SJohn Marino # pragma omp atomic new-line
9418*e4b17023SJohn Marino expression-stmt
9419*e4b17023SJohn Marino
9420*e4b17023SJohn Marino expression-stmt:
9421*e4b17023SJohn Marino x binop= expr | x++ | ++x | x-- | --x
9422*e4b17023SJohn Marino binop:
9423*e4b17023SJohn Marino +, *, -, /, &, ^, |, <<, >>
9424*e4b17023SJohn Marino
9425*e4b17023SJohn Marino where x is an lvalue expression with scalar type.
9426*e4b17023SJohn Marino
9427*e4b17023SJohn Marino OpenMP 3.1:
9428*e4b17023SJohn Marino # pragma omp atomic new-line
9429*e4b17023SJohn Marino update-stmt
9430*e4b17023SJohn Marino
9431*e4b17023SJohn Marino # pragma omp atomic read new-line
9432*e4b17023SJohn Marino read-stmt
9433*e4b17023SJohn Marino
9434*e4b17023SJohn Marino # pragma omp atomic write new-line
9435*e4b17023SJohn Marino write-stmt
9436*e4b17023SJohn Marino
9437*e4b17023SJohn Marino # pragma omp atomic update new-line
9438*e4b17023SJohn Marino update-stmt
9439*e4b17023SJohn Marino
9440*e4b17023SJohn Marino # pragma omp atomic capture new-line
9441*e4b17023SJohn Marino capture-stmt
9442*e4b17023SJohn Marino
9443*e4b17023SJohn Marino # pragma omp atomic capture new-line
9444*e4b17023SJohn Marino capture-block
9445*e4b17023SJohn Marino
9446*e4b17023SJohn Marino read-stmt:
9447*e4b17023SJohn Marino v = x
9448*e4b17023SJohn Marino write-stmt:
9449*e4b17023SJohn Marino x = expr
9450*e4b17023SJohn Marino update-stmt:
9451*e4b17023SJohn Marino expression-stmt | x = x binop expr
9452*e4b17023SJohn Marino capture-stmt:
9453*e4b17023SJohn Marino v = x binop= expr | v = x++ | v = ++x | v = x-- | v = --x
9454*e4b17023SJohn Marino capture-block:
9455*e4b17023SJohn Marino { v = x; update-stmt; } | { update-stmt; v = x; }
9456*e4b17023SJohn Marino
9457*e4b17023SJohn Marino where x and v are lvalue expressions with scalar type.
9458*e4b17023SJohn Marino
9459*e4b17023SJohn Marino LOC is the location of the #pragma token. */
9460*e4b17023SJohn Marino
9461*e4b17023SJohn Marino static void
c_parser_omp_atomic(location_t loc,c_parser * parser)9462*e4b17023SJohn Marino c_parser_omp_atomic (location_t loc, c_parser *parser)
9463*e4b17023SJohn Marino {
9464*e4b17023SJohn Marino tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
9465*e4b17023SJohn Marino tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
9466*e4b17023SJohn Marino tree stmt, orig_lhs;
9467*e4b17023SJohn Marino enum tree_code code = OMP_ATOMIC, opcode = NOP_EXPR;
9468*e4b17023SJohn Marino struct c_expr rhs_expr;
9469*e4b17023SJohn Marino bool structured_block = false;
9470*e4b17023SJohn Marino
9471*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
9472*e4b17023SJohn Marino {
9473*e4b17023SJohn Marino const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
9474*e4b17023SJohn Marino
9475*e4b17023SJohn Marino if (!strcmp (p, "read"))
9476*e4b17023SJohn Marino code = OMP_ATOMIC_READ;
9477*e4b17023SJohn Marino else if (!strcmp (p, "write"))
9478*e4b17023SJohn Marino code = NOP_EXPR;
9479*e4b17023SJohn Marino else if (!strcmp (p, "update"))
9480*e4b17023SJohn Marino code = OMP_ATOMIC;
9481*e4b17023SJohn Marino else if (!strcmp (p, "capture"))
9482*e4b17023SJohn Marino code = OMP_ATOMIC_CAPTURE_NEW;
9483*e4b17023SJohn Marino else
9484*e4b17023SJohn Marino p = NULL;
9485*e4b17023SJohn Marino if (p)
9486*e4b17023SJohn Marino c_parser_consume_token (parser);
9487*e4b17023SJohn Marino }
9488*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
9489*e4b17023SJohn Marino
9490*e4b17023SJohn Marino switch (code)
9491*e4b17023SJohn Marino {
9492*e4b17023SJohn Marino case OMP_ATOMIC_READ:
9493*e4b17023SJohn Marino case NOP_EXPR: /* atomic write */
9494*e4b17023SJohn Marino v = c_parser_unary_expression (parser).value;
9495*e4b17023SJohn Marino v = c_fully_fold (v, false, NULL);
9496*e4b17023SJohn Marino if (v == error_mark_node)
9497*e4b17023SJohn Marino goto saw_error;
9498*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
9499*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
9500*e4b17023SJohn Marino goto saw_error;
9501*e4b17023SJohn Marino if (code == NOP_EXPR)
9502*e4b17023SJohn Marino lhs = c_parser_expression (parser).value;
9503*e4b17023SJohn Marino else
9504*e4b17023SJohn Marino lhs = c_parser_unary_expression (parser).value;
9505*e4b17023SJohn Marino lhs = c_fully_fold (lhs, false, NULL);
9506*e4b17023SJohn Marino if (lhs == error_mark_node)
9507*e4b17023SJohn Marino goto saw_error;
9508*e4b17023SJohn Marino if (code == NOP_EXPR)
9509*e4b17023SJohn Marino {
9510*e4b17023SJohn Marino /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
9511*e4b17023SJohn Marino opcode. */
9512*e4b17023SJohn Marino code = OMP_ATOMIC;
9513*e4b17023SJohn Marino rhs = lhs;
9514*e4b17023SJohn Marino lhs = v;
9515*e4b17023SJohn Marino v = NULL_TREE;
9516*e4b17023SJohn Marino }
9517*e4b17023SJohn Marino goto done;
9518*e4b17023SJohn Marino case OMP_ATOMIC_CAPTURE_NEW:
9519*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
9520*e4b17023SJohn Marino {
9521*e4b17023SJohn Marino c_parser_consume_token (parser);
9522*e4b17023SJohn Marino structured_block = true;
9523*e4b17023SJohn Marino }
9524*e4b17023SJohn Marino else
9525*e4b17023SJohn Marino {
9526*e4b17023SJohn Marino v = c_parser_unary_expression (parser).value;
9527*e4b17023SJohn Marino v = c_fully_fold (v, false, NULL);
9528*e4b17023SJohn Marino if (v == error_mark_node)
9529*e4b17023SJohn Marino goto saw_error;
9530*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
9531*e4b17023SJohn Marino goto saw_error;
9532*e4b17023SJohn Marino }
9533*e4b17023SJohn Marino break;
9534*e4b17023SJohn Marino default:
9535*e4b17023SJohn Marino break;
9536*e4b17023SJohn Marino }
9537*e4b17023SJohn Marino
9538*e4b17023SJohn Marino /* For structured_block case we don't know yet whether
9539*e4b17023SJohn Marino old or new x should be captured. */
9540*e4b17023SJohn Marino restart:
9541*e4b17023SJohn Marino lhs = c_parser_unary_expression (parser).value;
9542*e4b17023SJohn Marino lhs = c_fully_fold (lhs, false, NULL);
9543*e4b17023SJohn Marino orig_lhs = lhs;
9544*e4b17023SJohn Marino switch (TREE_CODE (lhs))
9545*e4b17023SJohn Marino {
9546*e4b17023SJohn Marino case ERROR_MARK:
9547*e4b17023SJohn Marino saw_error:
9548*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
9549*e4b17023SJohn Marino if (structured_block)
9550*e4b17023SJohn Marino {
9551*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
9552*e4b17023SJohn Marino c_parser_consume_token (parser);
9553*e4b17023SJohn Marino else if (code == OMP_ATOMIC_CAPTURE_NEW)
9554*e4b17023SJohn Marino {
9555*e4b17023SJohn Marino c_parser_skip_to_end_of_block_or_statement (parser);
9556*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
9557*e4b17023SJohn Marino c_parser_consume_token (parser);
9558*e4b17023SJohn Marino }
9559*e4b17023SJohn Marino }
9560*e4b17023SJohn Marino return;
9561*e4b17023SJohn Marino
9562*e4b17023SJohn Marino case POSTINCREMENT_EXPR:
9563*e4b17023SJohn Marino if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
9564*e4b17023SJohn Marino code = OMP_ATOMIC_CAPTURE_OLD;
9565*e4b17023SJohn Marino /* FALLTHROUGH */
9566*e4b17023SJohn Marino case PREINCREMENT_EXPR:
9567*e4b17023SJohn Marino lhs = TREE_OPERAND (lhs, 0);
9568*e4b17023SJohn Marino opcode = PLUS_EXPR;
9569*e4b17023SJohn Marino rhs = integer_one_node;
9570*e4b17023SJohn Marino break;
9571*e4b17023SJohn Marino
9572*e4b17023SJohn Marino case POSTDECREMENT_EXPR:
9573*e4b17023SJohn Marino if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
9574*e4b17023SJohn Marino code = OMP_ATOMIC_CAPTURE_OLD;
9575*e4b17023SJohn Marino /* FALLTHROUGH */
9576*e4b17023SJohn Marino case PREDECREMENT_EXPR:
9577*e4b17023SJohn Marino lhs = TREE_OPERAND (lhs, 0);
9578*e4b17023SJohn Marino opcode = MINUS_EXPR;
9579*e4b17023SJohn Marino rhs = integer_one_node;
9580*e4b17023SJohn Marino break;
9581*e4b17023SJohn Marino
9582*e4b17023SJohn Marino case COMPOUND_EXPR:
9583*e4b17023SJohn Marino if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
9584*e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
9585*e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
9586*e4b17023SJohn Marino && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
9587*e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
9588*e4b17023SJohn Marino (TREE_OPERAND (lhs, 1), 0), 0)))
9589*e4b17023SJohn Marino == BOOLEAN_TYPE)
9590*e4b17023SJohn Marino /* Undo effects of boolean_increment for post {in,de}crement. */
9591*e4b17023SJohn Marino lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
9592*e4b17023SJohn Marino /* FALLTHRU */
9593*e4b17023SJohn Marino case MODIFY_EXPR:
9594*e4b17023SJohn Marino if (TREE_CODE (lhs) == MODIFY_EXPR
9595*e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
9596*e4b17023SJohn Marino {
9597*e4b17023SJohn Marino /* Undo effects of boolean_increment. */
9598*e4b17023SJohn Marino if (integer_onep (TREE_OPERAND (lhs, 1)))
9599*e4b17023SJohn Marino {
9600*e4b17023SJohn Marino /* This is pre or post increment. */
9601*e4b17023SJohn Marino rhs = TREE_OPERAND (lhs, 1);
9602*e4b17023SJohn Marino lhs = TREE_OPERAND (lhs, 0);
9603*e4b17023SJohn Marino opcode = NOP_EXPR;
9604*e4b17023SJohn Marino if (code == OMP_ATOMIC_CAPTURE_NEW
9605*e4b17023SJohn Marino && !structured_block
9606*e4b17023SJohn Marino && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
9607*e4b17023SJohn Marino code = OMP_ATOMIC_CAPTURE_OLD;
9608*e4b17023SJohn Marino break;
9609*e4b17023SJohn Marino }
9610*e4b17023SJohn Marino if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
9611*e4b17023SJohn Marino && TREE_OPERAND (lhs, 0)
9612*e4b17023SJohn Marino == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
9613*e4b17023SJohn Marino {
9614*e4b17023SJohn Marino /* This is pre or post decrement. */
9615*e4b17023SJohn Marino rhs = TREE_OPERAND (lhs, 1);
9616*e4b17023SJohn Marino lhs = TREE_OPERAND (lhs, 0);
9617*e4b17023SJohn Marino opcode = NOP_EXPR;
9618*e4b17023SJohn Marino if (code == OMP_ATOMIC_CAPTURE_NEW
9619*e4b17023SJohn Marino && !structured_block
9620*e4b17023SJohn Marino && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
9621*e4b17023SJohn Marino code = OMP_ATOMIC_CAPTURE_OLD;
9622*e4b17023SJohn Marino break;
9623*e4b17023SJohn Marino }
9624*e4b17023SJohn Marino }
9625*e4b17023SJohn Marino /* FALLTHRU */
9626*e4b17023SJohn Marino default:
9627*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
9628*e4b17023SJohn Marino {
9629*e4b17023SJohn Marino case CPP_MULT_EQ:
9630*e4b17023SJohn Marino opcode = MULT_EXPR;
9631*e4b17023SJohn Marino break;
9632*e4b17023SJohn Marino case CPP_DIV_EQ:
9633*e4b17023SJohn Marino opcode = TRUNC_DIV_EXPR;
9634*e4b17023SJohn Marino break;
9635*e4b17023SJohn Marino case CPP_PLUS_EQ:
9636*e4b17023SJohn Marino opcode = PLUS_EXPR;
9637*e4b17023SJohn Marino break;
9638*e4b17023SJohn Marino case CPP_MINUS_EQ:
9639*e4b17023SJohn Marino opcode = MINUS_EXPR;
9640*e4b17023SJohn Marino break;
9641*e4b17023SJohn Marino case CPP_LSHIFT_EQ:
9642*e4b17023SJohn Marino opcode = LSHIFT_EXPR;
9643*e4b17023SJohn Marino break;
9644*e4b17023SJohn Marino case CPP_RSHIFT_EQ:
9645*e4b17023SJohn Marino opcode = RSHIFT_EXPR;
9646*e4b17023SJohn Marino break;
9647*e4b17023SJohn Marino case CPP_AND_EQ:
9648*e4b17023SJohn Marino opcode = BIT_AND_EXPR;
9649*e4b17023SJohn Marino break;
9650*e4b17023SJohn Marino case CPP_OR_EQ:
9651*e4b17023SJohn Marino opcode = BIT_IOR_EXPR;
9652*e4b17023SJohn Marino break;
9653*e4b17023SJohn Marino case CPP_XOR_EQ:
9654*e4b17023SJohn Marino opcode = BIT_XOR_EXPR;
9655*e4b17023SJohn Marino break;
9656*e4b17023SJohn Marino case CPP_EQ:
9657*e4b17023SJohn Marino if (structured_block || code == OMP_ATOMIC)
9658*e4b17023SJohn Marino {
9659*e4b17023SJohn Marino location_t aloc = c_parser_peek_token (parser)->location;
9660*e4b17023SJohn Marino location_t rhs_loc;
9661*e4b17023SJohn Marino enum c_parser_prec oprec = PREC_NONE;
9662*e4b17023SJohn Marino
9663*e4b17023SJohn Marino c_parser_consume_token (parser);
9664*e4b17023SJohn Marino rhs1 = c_parser_unary_expression (parser).value;
9665*e4b17023SJohn Marino rhs1 = c_fully_fold (rhs1, false, NULL);
9666*e4b17023SJohn Marino if (rhs1 == error_mark_node)
9667*e4b17023SJohn Marino goto saw_error;
9668*e4b17023SJohn Marino switch (c_parser_peek_token (parser)->type)
9669*e4b17023SJohn Marino {
9670*e4b17023SJohn Marino case CPP_SEMICOLON:
9671*e4b17023SJohn Marino if (code == OMP_ATOMIC_CAPTURE_NEW)
9672*e4b17023SJohn Marino {
9673*e4b17023SJohn Marino code = OMP_ATOMIC_CAPTURE_OLD;
9674*e4b17023SJohn Marino v = lhs;
9675*e4b17023SJohn Marino lhs = NULL_TREE;
9676*e4b17023SJohn Marino lhs1 = rhs1;
9677*e4b17023SJohn Marino rhs1 = NULL_TREE;
9678*e4b17023SJohn Marino c_parser_consume_token (parser);
9679*e4b17023SJohn Marino goto restart;
9680*e4b17023SJohn Marino }
9681*e4b17023SJohn Marino c_parser_error (parser,
9682*e4b17023SJohn Marino "invalid form of %<#pragma omp atomic%>");
9683*e4b17023SJohn Marino goto saw_error;
9684*e4b17023SJohn Marino case CPP_MULT:
9685*e4b17023SJohn Marino opcode = MULT_EXPR;
9686*e4b17023SJohn Marino oprec = PREC_MULT;
9687*e4b17023SJohn Marino break;
9688*e4b17023SJohn Marino case CPP_DIV:
9689*e4b17023SJohn Marino opcode = TRUNC_DIV_EXPR;
9690*e4b17023SJohn Marino oprec = PREC_MULT;
9691*e4b17023SJohn Marino break;
9692*e4b17023SJohn Marino case CPP_PLUS:
9693*e4b17023SJohn Marino opcode = PLUS_EXPR;
9694*e4b17023SJohn Marino oprec = PREC_ADD;
9695*e4b17023SJohn Marino break;
9696*e4b17023SJohn Marino case CPP_MINUS:
9697*e4b17023SJohn Marino opcode = MINUS_EXPR;
9698*e4b17023SJohn Marino oprec = PREC_ADD;
9699*e4b17023SJohn Marino break;
9700*e4b17023SJohn Marino case CPP_LSHIFT:
9701*e4b17023SJohn Marino opcode = LSHIFT_EXPR;
9702*e4b17023SJohn Marino oprec = PREC_SHIFT;
9703*e4b17023SJohn Marino break;
9704*e4b17023SJohn Marino case CPP_RSHIFT:
9705*e4b17023SJohn Marino opcode = RSHIFT_EXPR;
9706*e4b17023SJohn Marino oprec = PREC_SHIFT;
9707*e4b17023SJohn Marino break;
9708*e4b17023SJohn Marino case CPP_AND:
9709*e4b17023SJohn Marino opcode = BIT_AND_EXPR;
9710*e4b17023SJohn Marino oprec = PREC_BITAND;
9711*e4b17023SJohn Marino break;
9712*e4b17023SJohn Marino case CPP_OR:
9713*e4b17023SJohn Marino opcode = BIT_IOR_EXPR;
9714*e4b17023SJohn Marino oprec = PREC_BITOR;
9715*e4b17023SJohn Marino break;
9716*e4b17023SJohn Marino case CPP_XOR:
9717*e4b17023SJohn Marino opcode = BIT_XOR_EXPR;
9718*e4b17023SJohn Marino oprec = PREC_BITXOR;
9719*e4b17023SJohn Marino break;
9720*e4b17023SJohn Marino default:
9721*e4b17023SJohn Marino c_parser_error (parser,
9722*e4b17023SJohn Marino "invalid operator for %<#pragma omp atomic%>");
9723*e4b17023SJohn Marino goto saw_error;
9724*e4b17023SJohn Marino }
9725*e4b17023SJohn Marino loc = aloc;
9726*e4b17023SJohn Marino c_parser_consume_token (parser);
9727*e4b17023SJohn Marino rhs_loc = c_parser_peek_token (parser)->location;
9728*e4b17023SJohn Marino if (commutative_tree_code (opcode))
9729*e4b17023SJohn Marino oprec = (enum c_parser_prec) (oprec - 1);
9730*e4b17023SJohn Marino rhs_expr = c_parser_binary_expression (parser, NULL, oprec);
9731*e4b17023SJohn Marino rhs_expr = default_function_array_read_conversion (rhs_loc,
9732*e4b17023SJohn Marino rhs_expr);
9733*e4b17023SJohn Marino rhs = rhs_expr.value;
9734*e4b17023SJohn Marino rhs = c_fully_fold (rhs, false, NULL);
9735*e4b17023SJohn Marino goto stmt_done;
9736*e4b17023SJohn Marino }
9737*e4b17023SJohn Marino /* FALLTHROUGH */
9738*e4b17023SJohn Marino default:
9739*e4b17023SJohn Marino c_parser_error (parser,
9740*e4b17023SJohn Marino "invalid operator for %<#pragma omp atomic%>");
9741*e4b17023SJohn Marino goto saw_error;
9742*e4b17023SJohn Marino }
9743*e4b17023SJohn Marino
9744*e4b17023SJohn Marino /* Arrange to pass the location of the assignment operator to
9745*e4b17023SJohn Marino c_finish_omp_atomic. */
9746*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
9747*e4b17023SJohn Marino c_parser_consume_token (parser);
9748*e4b17023SJohn Marino {
9749*e4b17023SJohn Marino location_t rhs_loc = c_parser_peek_token (parser)->location;
9750*e4b17023SJohn Marino rhs_expr = c_parser_expression (parser);
9751*e4b17023SJohn Marino rhs_expr = default_function_array_read_conversion (rhs_loc, rhs_expr);
9752*e4b17023SJohn Marino }
9753*e4b17023SJohn Marino rhs = rhs_expr.value;
9754*e4b17023SJohn Marino rhs = c_fully_fold (rhs, false, NULL);
9755*e4b17023SJohn Marino break;
9756*e4b17023SJohn Marino }
9757*e4b17023SJohn Marino stmt_done:
9758*e4b17023SJohn Marino if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
9759*e4b17023SJohn Marino {
9760*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
9761*e4b17023SJohn Marino goto saw_error;
9762*e4b17023SJohn Marino v = c_parser_unary_expression (parser).value;
9763*e4b17023SJohn Marino v = c_fully_fold (v, false, NULL);
9764*e4b17023SJohn Marino if (v == error_mark_node)
9765*e4b17023SJohn Marino goto saw_error;
9766*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
9767*e4b17023SJohn Marino goto saw_error;
9768*e4b17023SJohn Marino lhs1 = c_parser_unary_expression (parser).value;
9769*e4b17023SJohn Marino lhs1 = c_fully_fold (lhs1, false, NULL);
9770*e4b17023SJohn Marino if (lhs1 == error_mark_node)
9771*e4b17023SJohn Marino goto saw_error;
9772*e4b17023SJohn Marino }
9773*e4b17023SJohn Marino if (structured_block)
9774*e4b17023SJohn Marino {
9775*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9776*e4b17023SJohn Marino c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
9777*e4b17023SJohn Marino }
9778*e4b17023SJohn Marino done:
9779*e4b17023SJohn Marino stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1);
9780*e4b17023SJohn Marino if (stmt != error_mark_node)
9781*e4b17023SJohn Marino add_stmt (stmt);
9782*e4b17023SJohn Marino
9783*e4b17023SJohn Marino if (!structured_block)
9784*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9785*e4b17023SJohn Marino }
9786*e4b17023SJohn Marino
9787*e4b17023SJohn Marino
9788*e4b17023SJohn Marino /* OpenMP 2.5:
9789*e4b17023SJohn Marino # pragma omp barrier new-line
9790*e4b17023SJohn Marino */
9791*e4b17023SJohn Marino
9792*e4b17023SJohn Marino static void
c_parser_omp_barrier(c_parser * parser)9793*e4b17023SJohn Marino c_parser_omp_barrier (c_parser *parser)
9794*e4b17023SJohn Marino {
9795*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
9796*e4b17023SJohn Marino c_parser_consume_pragma (parser);
9797*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
9798*e4b17023SJohn Marino
9799*e4b17023SJohn Marino c_finish_omp_barrier (loc);
9800*e4b17023SJohn Marino }
9801*e4b17023SJohn Marino
9802*e4b17023SJohn Marino /* OpenMP 2.5:
9803*e4b17023SJohn Marino # pragma omp critical [(name)] new-line
9804*e4b17023SJohn Marino structured-block
9805*e4b17023SJohn Marino
9806*e4b17023SJohn Marino LOC is the location of the #pragma itself. */
9807*e4b17023SJohn Marino
9808*e4b17023SJohn Marino static tree
c_parser_omp_critical(location_t loc,c_parser * parser)9809*e4b17023SJohn Marino c_parser_omp_critical (location_t loc, c_parser *parser)
9810*e4b17023SJohn Marino {
9811*e4b17023SJohn Marino tree stmt, name = NULL;
9812*e4b17023SJohn Marino
9813*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
9814*e4b17023SJohn Marino {
9815*e4b17023SJohn Marino c_parser_consume_token (parser);
9816*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_NAME))
9817*e4b17023SJohn Marino {
9818*e4b17023SJohn Marino name = c_parser_peek_token (parser)->value;
9819*e4b17023SJohn Marino c_parser_consume_token (parser);
9820*e4b17023SJohn Marino c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9821*e4b17023SJohn Marino }
9822*e4b17023SJohn Marino else
9823*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
9824*e4b17023SJohn Marino }
9825*e4b17023SJohn Marino else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
9826*e4b17023SJohn Marino c_parser_error (parser, "expected %<(%> or end of line");
9827*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
9828*e4b17023SJohn Marino
9829*e4b17023SJohn Marino stmt = c_parser_omp_structured_block (parser);
9830*e4b17023SJohn Marino return c_finish_omp_critical (loc, stmt, name);
9831*e4b17023SJohn Marino }
9832*e4b17023SJohn Marino
9833*e4b17023SJohn Marino /* OpenMP 2.5:
9834*e4b17023SJohn Marino # pragma omp flush flush-vars[opt] new-line
9835*e4b17023SJohn Marino
9836*e4b17023SJohn Marino flush-vars:
9837*e4b17023SJohn Marino ( variable-list ) */
9838*e4b17023SJohn Marino
9839*e4b17023SJohn Marino static void
c_parser_omp_flush(c_parser * parser)9840*e4b17023SJohn Marino c_parser_omp_flush (c_parser *parser)
9841*e4b17023SJohn Marino {
9842*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
9843*e4b17023SJohn Marino c_parser_consume_pragma (parser);
9844*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
9845*e4b17023SJohn Marino c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
9846*e4b17023SJohn Marino else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
9847*e4b17023SJohn Marino c_parser_error (parser, "expected %<(%> or end of line");
9848*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
9849*e4b17023SJohn Marino
9850*e4b17023SJohn Marino c_finish_omp_flush (loc);
9851*e4b17023SJohn Marino }
9852*e4b17023SJohn Marino
9853*e4b17023SJohn Marino /* Parse the restricted form of the for statement allowed by OpenMP.
9854*e4b17023SJohn Marino The real trick here is to determine the loop control variable early
9855*e4b17023SJohn Marino so that we can push a new decl if necessary to make it private.
9856*e4b17023SJohn Marino LOC is the location of the OMP in "#pragma omp". */
9857*e4b17023SJohn Marino
9858*e4b17023SJohn Marino static tree
c_parser_omp_for_loop(location_t loc,c_parser * parser,tree clauses,tree * par_clauses)9859*e4b17023SJohn Marino c_parser_omp_for_loop (location_t loc,
9860*e4b17023SJohn Marino c_parser *parser, tree clauses, tree *par_clauses)
9861*e4b17023SJohn Marino {
9862*e4b17023SJohn Marino tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
9863*e4b17023SJohn Marino tree declv, condv, incrv, initv, ret = NULL;
9864*e4b17023SJohn Marino bool fail = false, open_brace_parsed = false;
9865*e4b17023SJohn Marino int i, collapse = 1, nbraces = 0;
9866*e4b17023SJohn Marino location_t for_loc;
9867*e4b17023SJohn Marino VEC(tree,gc) *for_block = make_tree_vector ();
9868*e4b17023SJohn Marino
9869*e4b17023SJohn Marino for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
9870*e4b17023SJohn Marino if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
9871*e4b17023SJohn Marino collapse = tree_low_cst (OMP_CLAUSE_COLLAPSE_EXPR (cl), 0);
9872*e4b17023SJohn Marino
9873*e4b17023SJohn Marino gcc_assert (collapse >= 1);
9874*e4b17023SJohn Marino
9875*e4b17023SJohn Marino declv = make_tree_vec (collapse);
9876*e4b17023SJohn Marino initv = make_tree_vec (collapse);
9877*e4b17023SJohn Marino condv = make_tree_vec (collapse);
9878*e4b17023SJohn Marino incrv = make_tree_vec (collapse);
9879*e4b17023SJohn Marino
9880*e4b17023SJohn Marino if (!c_parser_next_token_is_keyword (parser, RID_FOR))
9881*e4b17023SJohn Marino {
9882*e4b17023SJohn Marino c_parser_error (parser, "for statement expected");
9883*e4b17023SJohn Marino return NULL;
9884*e4b17023SJohn Marino }
9885*e4b17023SJohn Marino for_loc = c_parser_peek_token (parser)->location;
9886*e4b17023SJohn Marino c_parser_consume_token (parser);
9887*e4b17023SJohn Marino
9888*e4b17023SJohn Marino for (i = 0; i < collapse; i++)
9889*e4b17023SJohn Marino {
9890*e4b17023SJohn Marino int bracecount = 0;
9891*e4b17023SJohn Marino
9892*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
9893*e4b17023SJohn Marino goto pop_scopes;
9894*e4b17023SJohn Marino
9895*e4b17023SJohn Marino /* Parse the initialization declaration or expression. */
9896*e4b17023SJohn Marino if (c_parser_next_tokens_start_declaration (parser))
9897*e4b17023SJohn Marino {
9898*e4b17023SJohn Marino if (i > 0)
9899*e4b17023SJohn Marino VEC_safe_push (tree, gc, for_block, c_begin_compound_stmt (true));
9900*e4b17023SJohn Marino c_parser_declaration_or_fndef (parser, true, true, true, true, true, NULL);
9901*e4b17023SJohn Marino decl = check_for_loop_decls (for_loc, flag_isoc99);
9902*e4b17023SJohn Marino if (decl == NULL)
9903*e4b17023SJohn Marino goto error_init;
9904*e4b17023SJohn Marino if (DECL_INITIAL (decl) == error_mark_node)
9905*e4b17023SJohn Marino decl = error_mark_node;
9906*e4b17023SJohn Marino init = decl;
9907*e4b17023SJohn Marino }
9908*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_NAME)
9909*e4b17023SJohn Marino && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
9910*e4b17023SJohn Marino {
9911*e4b17023SJohn Marino struct c_expr decl_exp;
9912*e4b17023SJohn Marino struct c_expr init_exp;
9913*e4b17023SJohn Marino location_t init_loc;
9914*e4b17023SJohn Marino
9915*e4b17023SJohn Marino decl_exp = c_parser_postfix_expression (parser);
9916*e4b17023SJohn Marino decl = decl_exp.value;
9917*e4b17023SJohn Marino
9918*e4b17023SJohn Marino c_parser_require (parser, CPP_EQ, "expected %<=%>");
9919*e4b17023SJohn Marino
9920*e4b17023SJohn Marino init_loc = c_parser_peek_token (parser)->location;
9921*e4b17023SJohn Marino init_exp = c_parser_expr_no_commas (parser, NULL);
9922*e4b17023SJohn Marino init_exp = default_function_array_read_conversion (init_loc,
9923*e4b17023SJohn Marino init_exp);
9924*e4b17023SJohn Marino init = build_modify_expr (init_loc, decl, decl_exp.original_type,
9925*e4b17023SJohn Marino NOP_EXPR, init_loc, init_exp.value,
9926*e4b17023SJohn Marino init_exp.original_type);
9927*e4b17023SJohn Marino init = c_process_expr_stmt (init_loc, init);
9928*e4b17023SJohn Marino
9929*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9930*e4b17023SJohn Marino }
9931*e4b17023SJohn Marino else
9932*e4b17023SJohn Marino {
9933*e4b17023SJohn Marino error_init:
9934*e4b17023SJohn Marino c_parser_error (parser,
9935*e4b17023SJohn Marino "expected iteration declaration or initialization");
9936*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9937*e4b17023SJohn Marino "expected %<)%>");
9938*e4b17023SJohn Marino fail = true;
9939*e4b17023SJohn Marino goto parse_next;
9940*e4b17023SJohn Marino }
9941*e4b17023SJohn Marino
9942*e4b17023SJohn Marino /* Parse the loop condition. */
9943*e4b17023SJohn Marino cond = NULL_TREE;
9944*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
9945*e4b17023SJohn Marino {
9946*e4b17023SJohn Marino location_t cond_loc = c_parser_peek_token (parser)->location;
9947*e4b17023SJohn Marino struct c_expr cond_expr = c_parser_binary_expression (parser, NULL,
9948*e4b17023SJohn Marino PREC_NONE);
9949*e4b17023SJohn Marino
9950*e4b17023SJohn Marino cond = cond_expr.value;
9951*e4b17023SJohn Marino cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
9952*e4b17023SJohn Marino cond = c_fully_fold (cond, false, NULL);
9953*e4b17023SJohn Marino switch (cond_expr.original_code)
9954*e4b17023SJohn Marino {
9955*e4b17023SJohn Marino case GT_EXPR:
9956*e4b17023SJohn Marino case GE_EXPR:
9957*e4b17023SJohn Marino case LT_EXPR:
9958*e4b17023SJohn Marino case LE_EXPR:
9959*e4b17023SJohn Marino break;
9960*e4b17023SJohn Marino default:
9961*e4b17023SJohn Marino /* Can't be cond = error_mark_node, because we want to preserve
9962*e4b17023SJohn Marino the location until c_finish_omp_for. */
9963*e4b17023SJohn Marino cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
9964*e4b17023SJohn Marino break;
9965*e4b17023SJohn Marino }
9966*e4b17023SJohn Marino protected_set_expr_location (cond, cond_loc);
9967*e4b17023SJohn Marino }
9968*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
9969*e4b17023SJohn Marino
9970*e4b17023SJohn Marino /* Parse the increment expression. */
9971*e4b17023SJohn Marino incr = NULL_TREE;
9972*e4b17023SJohn Marino if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
9973*e4b17023SJohn Marino {
9974*e4b17023SJohn Marino location_t incr_loc = c_parser_peek_token (parser)->location;
9975*e4b17023SJohn Marino
9976*e4b17023SJohn Marino incr = c_process_expr_stmt (incr_loc,
9977*e4b17023SJohn Marino c_parser_expression (parser).value);
9978*e4b17023SJohn Marino }
9979*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
9980*e4b17023SJohn Marino
9981*e4b17023SJohn Marino if (decl == NULL || decl == error_mark_node || init == error_mark_node)
9982*e4b17023SJohn Marino fail = true;
9983*e4b17023SJohn Marino else
9984*e4b17023SJohn Marino {
9985*e4b17023SJohn Marino TREE_VEC_ELT (declv, i) = decl;
9986*e4b17023SJohn Marino TREE_VEC_ELT (initv, i) = init;
9987*e4b17023SJohn Marino TREE_VEC_ELT (condv, i) = cond;
9988*e4b17023SJohn Marino TREE_VEC_ELT (incrv, i) = incr;
9989*e4b17023SJohn Marino }
9990*e4b17023SJohn Marino
9991*e4b17023SJohn Marino parse_next:
9992*e4b17023SJohn Marino if (i == collapse - 1)
9993*e4b17023SJohn Marino break;
9994*e4b17023SJohn Marino
9995*e4b17023SJohn Marino /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
9996*e4b17023SJohn Marino in between the collapsed for loops to be still considered perfectly
9997*e4b17023SJohn Marino nested. Hopefully the final version clarifies this.
9998*e4b17023SJohn Marino For now handle (multiple) {'s and empty statements. */
9999*e4b17023SJohn Marino do
10000*e4b17023SJohn Marino {
10001*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_FOR))
10002*e4b17023SJohn Marino {
10003*e4b17023SJohn Marino c_parser_consume_token (parser);
10004*e4b17023SJohn Marino break;
10005*e4b17023SJohn Marino }
10006*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10007*e4b17023SJohn Marino {
10008*e4b17023SJohn Marino c_parser_consume_token (parser);
10009*e4b17023SJohn Marino bracecount++;
10010*e4b17023SJohn Marino }
10011*e4b17023SJohn Marino else if (bracecount
10012*e4b17023SJohn Marino && c_parser_next_token_is (parser, CPP_SEMICOLON))
10013*e4b17023SJohn Marino c_parser_consume_token (parser);
10014*e4b17023SJohn Marino else
10015*e4b17023SJohn Marino {
10016*e4b17023SJohn Marino c_parser_error (parser, "not enough perfectly nested loops");
10017*e4b17023SJohn Marino if (bracecount)
10018*e4b17023SJohn Marino {
10019*e4b17023SJohn Marino open_brace_parsed = true;
10020*e4b17023SJohn Marino bracecount--;
10021*e4b17023SJohn Marino }
10022*e4b17023SJohn Marino fail = true;
10023*e4b17023SJohn Marino collapse = 0;
10024*e4b17023SJohn Marino break;
10025*e4b17023SJohn Marino }
10026*e4b17023SJohn Marino }
10027*e4b17023SJohn Marino while (1);
10028*e4b17023SJohn Marino
10029*e4b17023SJohn Marino nbraces += bracecount;
10030*e4b17023SJohn Marino }
10031*e4b17023SJohn Marino
10032*e4b17023SJohn Marino save_break = c_break_label;
10033*e4b17023SJohn Marino c_break_label = size_one_node;
10034*e4b17023SJohn Marino save_cont = c_cont_label;
10035*e4b17023SJohn Marino c_cont_label = NULL_TREE;
10036*e4b17023SJohn Marino body = push_stmt_list ();
10037*e4b17023SJohn Marino
10038*e4b17023SJohn Marino if (open_brace_parsed)
10039*e4b17023SJohn Marino {
10040*e4b17023SJohn Marino location_t here = c_parser_peek_token (parser)->location;
10041*e4b17023SJohn Marino stmt = c_begin_compound_stmt (true);
10042*e4b17023SJohn Marino c_parser_compound_statement_nostart (parser);
10043*e4b17023SJohn Marino add_stmt (c_end_compound_stmt (here, stmt, true));
10044*e4b17023SJohn Marino }
10045*e4b17023SJohn Marino else
10046*e4b17023SJohn Marino add_stmt (c_parser_c99_block_statement (parser));
10047*e4b17023SJohn Marino if (c_cont_label)
10048*e4b17023SJohn Marino {
10049*e4b17023SJohn Marino tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
10050*e4b17023SJohn Marino SET_EXPR_LOCATION (t, loc);
10051*e4b17023SJohn Marino add_stmt (t);
10052*e4b17023SJohn Marino }
10053*e4b17023SJohn Marino
10054*e4b17023SJohn Marino body = pop_stmt_list (body);
10055*e4b17023SJohn Marino c_break_label = save_break;
10056*e4b17023SJohn Marino c_cont_label = save_cont;
10057*e4b17023SJohn Marino
10058*e4b17023SJohn Marino while (nbraces)
10059*e4b17023SJohn Marino {
10060*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10061*e4b17023SJohn Marino {
10062*e4b17023SJohn Marino c_parser_consume_token (parser);
10063*e4b17023SJohn Marino nbraces--;
10064*e4b17023SJohn Marino }
10065*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10066*e4b17023SJohn Marino c_parser_consume_token (parser);
10067*e4b17023SJohn Marino else
10068*e4b17023SJohn Marino {
10069*e4b17023SJohn Marino c_parser_error (parser, "collapsed loops not perfectly nested");
10070*e4b17023SJohn Marino while (nbraces)
10071*e4b17023SJohn Marino {
10072*e4b17023SJohn Marino location_t here = c_parser_peek_token (parser)->location;
10073*e4b17023SJohn Marino stmt = c_begin_compound_stmt (true);
10074*e4b17023SJohn Marino add_stmt (body);
10075*e4b17023SJohn Marino c_parser_compound_statement_nostart (parser);
10076*e4b17023SJohn Marino body = c_end_compound_stmt (here, stmt, true);
10077*e4b17023SJohn Marino nbraces--;
10078*e4b17023SJohn Marino }
10079*e4b17023SJohn Marino goto pop_scopes;
10080*e4b17023SJohn Marino }
10081*e4b17023SJohn Marino }
10082*e4b17023SJohn Marino
10083*e4b17023SJohn Marino /* Only bother calling c_finish_omp_for if we haven't already generated
10084*e4b17023SJohn Marino an error from the initialization parsing. */
10085*e4b17023SJohn Marino if (!fail)
10086*e4b17023SJohn Marino {
10087*e4b17023SJohn Marino stmt = c_finish_omp_for (loc, declv, initv, condv, incrv, body, NULL);
10088*e4b17023SJohn Marino if (stmt)
10089*e4b17023SJohn Marino {
10090*e4b17023SJohn Marino if (par_clauses != NULL)
10091*e4b17023SJohn Marino {
10092*e4b17023SJohn Marino tree *c;
10093*e4b17023SJohn Marino for (c = par_clauses; *c ; )
10094*e4b17023SJohn Marino if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
10095*e4b17023SJohn Marino && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
10096*e4b17023SJohn Marino c = &OMP_CLAUSE_CHAIN (*c);
10097*e4b17023SJohn Marino else
10098*e4b17023SJohn Marino {
10099*e4b17023SJohn Marino for (i = 0; i < collapse; i++)
10100*e4b17023SJohn Marino if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
10101*e4b17023SJohn Marino break;
10102*e4b17023SJohn Marino if (i == collapse)
10103*e4b17023SJohn Marino c = &OMP_CLAUSE_CHAIN (*c);
10104*e4b17023SJohn Marino else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
10105*e4b17023SJohn Marino {
10106*e4b17023SJohn Marino error_at (loc,
10107*e4b17023SJohn Marino "iteration variable %qD should not be firstprivate",
10108*e4b17023SJohn Marino OMP_CLAUSE_DECL (*c));
10109*e4b17023SJohn Marino *c = OMP_CLAUSE_CHAIN (*c);
10110*e4b17023SJohn Marino }
10111*e4b17023SJohn Marino else
10112*e4b17023SJohn Marino {
10113*e4b17023SJohn Marino /* Copy lastprivate (decl) clause to OMP_FOR_CLAUSES,
10114*e4b17023SJohn Marino change it to shared (decl) in
10115*e4b17023SJohn Marino OMP_PARALLEL_CLAUSES. */
10116*e4b17023SJohn Marino tree l = build_omp_clause (OMP_CLAUSE_LOCATION (*c),
10117*e4b17023SJohn Marino OMP_CLAUSE_LASTPRIVATE);
10118*e4b17023SJohn Marino OMP_CLAUSE_DECL (l) = OMP_CLAUSE_DECL (*c);
10119*e4b17023SJohn Marino OMP_CLAUSE_CHAIN (l) = clauses;
10120*e4b17023SJohn Marino clauses = l;
10121*e4b17023SJohn Marino OMP_CLAUSE_SET_CODE (*c, OMP_CLAUSE_SHARED);
10122*e4b17023SJohn Marino }
10123*e4b17023SJohn Marino }
10124*e4b17023SJohn Marino }
10125*e4b17023SJohn Marino OMP_FOR_CLAUSES (stmt) = clauses;
10126*e4b17023SJohn Marino }
10127*e4b17023SJohn Marino ret = stmt;
10128*e4b17023SJohn Marino }
10129*e4b17023SJohn Marino pop_scopes:
10130*e4b17023SJohn Marino while (!VEC_empty (tree, for_block))
10131*e4b17023SJohn Marino {
10132*e4b17023SJohn Marino /* FIXME diagnostics: LOC below should be the actual location of
10133*e4b17023SJohn Marino this particular for block. We need to build a list of
10134*e4b17023SJohn Marino locations to go along with FOR_BLOCK. */
10135*e4b17023SJohn Marino stmt = c_end_compound_stmt (loc, VEC_pop (tree, for_block), true);
10136*e4b17023SJohn Marino add_stmt (stmt);
10137*e4b17023SJohn Marino }
10138*e4b17023SJohn Marino release_tree_vector (for_block);
10139*e4b17023SJohn Marino return ret;
10140*e4b17023SJohn Marino }
10141*e4b17023SJohn Marino
10142*e4b17023SJohn Marino /* OpenMP 2.5:
10143*e4b17023SJohn Marino #pragma omp for for-clause[optseq] new-line
10144*e4b17023SJohn Marino for-loop
10145*e4b17023SJohn Marino
10146*e4b17023SJohn Marino LOC is the location of the #pragma token.
10147*e4b17023SJohn Marino */
10148*e4b17023SJohn Marino
10149*e4b17023SJohn Marino #define OMP_FOR_CLAUSE_MASK \
10150*e4b17023SJohn Marino ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \
10151*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
10152*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
10153*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \
10154*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_ORDERED) \
10155*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_SCHEDULE) \
10156*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_COLLAPSE) \
10157*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
10158*e4b17023SJohn Marino
10159*e4b17023SJohn Marino static tree
c_parser_omp_for(location_t loc,c_parser * parser)10160*e4b17023SJohn Marino c_parser_omp_for (location_t loc, c_parser *parser)
10161*e4b17023SJohn Marino {
10162*e4b17023SJohn Marino tree block, clauses, ret;
10163*e4b17023SJohn Marino
10164*e4b17023SJohn Marino clauses = c_parser_omp_all_clauses (parser, OMP_FOR_CLAUSE_MASK,
10165*e4b17023SJohn Marino "#pragma omp for");
10166*e4b17023SJohn Marino
10167*e4b17023SJohn Marino block = c_begin_compound_stmt (true);
10168*e4b17023SJohn Marino ret = c_parser_omp_for_loop (loc, parser, clauses, NULL);
10169*e4b17023SJohn Marino block = c_end_compound_stmt (loc, block, true);
10170*e4b17023SJohn Marino add_stmt (block);
10171*e4b17023SJohn Marino
10172*e4b17023SJohn Marino return ret;
10173*e4b17023SJohn Marino }
10174*e4b17023SJohn Marino
10175*e4b17023SJohn Marino /* OpenMP 2.5:
10176*e4b17023SJohn Marino # pragma omp master new-line
10177*e4b17023SJohn Marino structured-block
10178*e4b17023SJohn Marino
10179*e4b17023SJohn Marino LOC is the location of the #pragma token.
10180*e4b17023SJohn Marino */
10181*e4b17023SJohn Marino
10182*e4b17023SJohn Marino static tree
c_parser_omp_master(location_t loc,c_parser * parser)10183*e4b17023SJohn Marino c_parser_omp_master (location_t loc, c_parser *parser)
10184*e4b17023SJohn Marino {
10185*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
10186*e4b17023SJohn Marino return c_finish_omp_master (loc, c_parser_omp_structured_block (parser));
10187*e4b17023SJohn Marino }
10188*e4b17023SJohn Marino
10189*e4b17023SJohn Marino /* OpenMP 2.5:
10190*e4b17023SJohn Marino # pragma omp ordered new-line
10191*e4b17023SJohn Marino structured-block
10192*e4b17023SJohn Marino
10193*e4b17023SJohn Marino LOC is the location of the #pragma itself.
10194*e4b17023SJohn Marino */
10195*e4b17023SJohn Marino
10196*e4b17023SJohn Marino static tree
c_parser_omp_ordered(location_t loc,c_parser * parser)10197*e4b17023SJohn Marino c_parser_omp_ordered (location_t loc, c_parser *parser)
10198*e4b17023SJohn Marino {
10199*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
10200*e4b17023SJohn Marino return c_finish_omp_ordered (loc, c_parser_omp_structured_block (parser));
10201*e4b17023SJohn Marino }
10202*e4b17023SJohn Marino
10203*e4b17023SJohn Marino /* OpenMP 2.5:
10204*e4b17023SJohn Marino
10205*e4b17023SJohn Marino section-scope:
10206*e4b17023SJohn Marino { section-sequence }
10207*e4b17023SJohn Marino
10208*e4b17023SJohn Marino section-sequence:
10209*e4b17023SJohn Marino section-directive[opt] structured-block
10210*e4b17023SJohn Marino section-sequence section-directive structured-block
10211*e4b17023SJohn Marino
10212*e4b17023SJohn Marino SECTIONS_LOC is the location of the #pragma omp sections. */
10213*e4b17023SJohn Marino
10214*e4b17023SJohn Marino static tree
c_parser_omp_sections_scope(location_t sections_loc,c_parser * parser)10215*e4b17023SJohn Marino c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
10216*e4b17023SJohn Marino {
10217*e4b17023SJohn Marino tree stmt, substmt;
10218*e4b17023SJohn Marino bool error_suppress = false;
10219*e4b17023SJohn Marino location_t loc;
10220*e4b17023SJohn Marino
10221*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
10222*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
10223*e4b17023SJohn Marino {
10224*e4b17023SJohn Marino /* Avoid skipping until the end of the block. */
10225*e4b17023SJohn Marino parser->error = false;
10226*e4b17023SJohn Marino return NULL_TREE;
10227*e4b17023SJohn Marino }
10228*e4b17023SJohn Marino
10229*e4b17023SJohn Marino stmt = push_stmt_list ();
10230*e4b17023SJohn Marino
10231*e4b17023SJohn Marino if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
10232*e4b17023SJohn Marino {
10233*e4b17023SJohn Marino substmt = push_stmt_list ();
10234*e4b17023SJohn Marino
10235*e4b17023SJohn Marino while (1)
10236*e4b17023SJohn Marino {
10237*e4b17023SJohn Marino c_parser_statement (parser);
10238*e4b17023SJohn Marino
10239*e4b17023SJohn Marino if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
10240*e4b17023SJohn Marino break;
10241*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10242*e4b17023SJohn Marino break;
10243*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_EOF))
10244*e4b17023SJohn Marino break;
10245*e4b17023SJohn Marino }
10246*e4b17023SJohn Marino
10247*e4b17023SJohn Marino substmt = pop_stmt_list (substmt);
10248*e4b17023SJohn Marino substmt = build1 (OMP_SECTION, void_type_node, substmt);
10249*e4b17023SJohn Marino SET_EXPR_LOCATION (substmt, loc);
10250*e4b17023SJohn Marino add_stmt (substmt);
10251*e4b17023SJohn Marino }
10252*e4b17023SJohn Marino
10253*e4b17023SJohn Marino while (1)
10254*e4b17023SJohn Marino {
10255*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10256*e4b17023SJohn Marino break;
10257*e4b17023SJohn Marino if (c_parser_next_token_is (parser, CPP_EOF))
10258*e4b17023SJohn Marino break;
10259*e4b17023SJohn Marino
10260*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
10261*e4b17023SJohn Marino if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
10262*e4b17023SJohn Marino {
10263*e4b17023SJohn Marino c_parser_consume_pragma (parser);
10264*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
10265*e4b17023SJohn Marino error_suppress = false;
10266*e4b17023SJohn Marino }
10267*e4b17023SJohn Marino else if (!error_suppress)
10268*e4b17023SJohn Marino {
10269*e4b17023SJohn Marino error_at (loc, "expected %<#pragma omp section%> or %<}%>");
10270*e4b17023SJohn Marino error_suppress = true;
10271*e4b17023SJohn Marino }
10272*e4b17023SJohn Marino
10273*e4b17023SJohn Marino substmt = c_parser_omp_structured_block (parser);
10274*e4b17023SJohn Marino substmt = build1 (OMP_SECTION, void_type_node, substmt);
10275*e4b17023SJohn Marino SET_EXPR_LOCATION (substmt, loc);
10276*e4b17023SJohn Marino add_stmt (substmt);
10277*e4b17023SJohn Marino }
10278*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
10279*e4b17023SJohn Marino "expected %<#pragma omp section%> or %<}%>");
10280*e4b17023SJohn Marino
10281*e4b17023SJohn Marino substmt = pop_stmt_list (stmt);
10282*e4b17023SJohn Marino
10283*e4b17023SJohn Marino stmt = make_node (OMP_SECTIONS);
10284*e4b17023SJohn Marino SET_EXPR_LOCATION (stmt, sections_loc);
10285*e4b17023SJohn Marino TREE_TYPE (stmt) = void_type_node;
10286*e4b17023SJohn Marino OMP_SECTIONS_BODY (stmt) = substmt;
10287*e4b17023SJohn Marino
10288*e4b17023SJohn Marino return add_stmt (stmt);
10289*e4b17023SJohn Marino }
10290*e4b17023SJohn Marino
10291*e4b17023SJohn Marino /* OpenMP 2.5:
10292*e4b17023SJohn Marino # pragma omp sections sections-clause[optseq] newline
10293*e4b17023SJohn Marino sections-scope
10294*e4b17023SJohn Marino
10295*e4b17023SJohn Marino LOC is the location of the #pragma token.
10296*e4b17023SJohn Marino */
10297*e4b17023SJohn Marino
10298*e4b17023SJohn Marino #define OMP_SECTIONS_CLAUSE_MASK \
10299*e4b17023SJohn Marino ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \
10300*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
10301*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
10302*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \
10303*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
10304*e4b17023SJohn Marino
10305*e4b17023SJohn Marino static tree
c_parser_omp_sections(location_t loc,c_parser * parser)10306*e4b17023SJohn Marino c_parser_omp_sections (location_t loc, c_parser *parser)
10307*e4b17023SJohn Marino {
10308*e4b17023SJohn Marino tree block, clauses, ret;
10309*e4b17023SJohn Marino
10310*e4b17023SJohn Marino clauses = c_parser_omp_all_clauses (parser, OMP_SECTIONS_CLAUSE_MASK,
10311*e4b17023SJohn Marino "#pragma omp sections");
10312*e4b17023SJohn Marino
10313*e4b17023SJohn Marino block = c_begin_compound_stmt (true);
10314*e4b17023SJohn Marino ret = c_parser_omp_sections_scope (loc, parser);
10315*e4b17023SJohn Marino if (ret)
10316*e4b17023SJohn Marino OMP_SECTIONS_CLAUSES (ret) = clauses;
10317*e4b17023SJohn Marino block = c_end_compound_stmt (loc, block, true);
10318*e4b17023SJohn Marino add_stmt (block);
10319*e4b17023SJohn Marino
10320*e4b17023SJohn Marino return ret;
10321*e4b17023SJohn Marino }
10322*e4b17023SJohn Marino
10323*e4b17023SJohn Marino /* OpenMP 2.5:
10324*e4b17023SJohn Marino # pragma parallel parallel-clause new-line
10325*e4b17023SJohn Marino # pragma parallel for parallel-for-clause new-line
10326*e4b17023SJohn Marino # pragma parallel sections parallel-sections-clause new-line
10327*e4b17023SJohn Marino
10328*e4b17023SJohn Marino LOC is the location of the #pragma token.
10329*e4b17023SJohn Marino */
10330*e4b17023SJohn Marino
10331*e4b17023SJohn Marino #define OMP_PARALLEL_CLAUSE_MASK \
10332*e4b17023SJohn Marino ( (1u << PRAGMA_OMP_CLAUSE_IF) \
10333*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \
10334*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
10335*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \
10336*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_SHARED) \
10337*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_COPYIN) \
10338*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \
10339*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS))
10340*e4b17023SJohn Marino
10341*e4b17023SJohn Marino static tree
c_parser_omp_parallel(location_t loc,c_parser * parser)10342*e4b17023SJohn Marino c_parser_omp_parallel (location_t loc, c_parser *parser)
10343*e4b17023SJohn Marino {
10344*e4b17023SJohn Marino enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL;
10345*e4b17023SJohn Marino const char *p_name = "#pragma omp parallel";
10346*e4b17023SJohn Marino tree stmt, clauses, par_clause, ws_clause, block;
10347*e4b17023SJohn Marino unsigned int mask = OMP_PARALLEL_CLAUSE_MASK;
10348*e4b17023SJohn Marino
10349*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_FOR))
10350*e4b17023SJohn Marino {
10351*e4b17023SJohn Marino c_parser_consume_token (parser);
10352*e4b17023SJohn Marino p_kind = PRAGMA_OMP_PARALLEL_FOR;
10353*e4b17023SJohn Marino p_name = "#pragma omp parallel for";
10354*e4b17023SJohn Marino mask |= OMP_FOR_CLAUSE_MASK;
10355*e4b17023SJohn Marino mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT);
10356*e4b17023SJohn Marino }
10357*e4b17023SJohn Marino else if (c_parser_next_token_is (parser, CPP_NAME))
10358*e4b17023SJohn Marino {
10359*e4b17023SJohn Marino const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
10360*e4b17023SJohn Marino if (strcmp (p, "sections") == 0)
10361*e4b17023SJohn Marino {
10362*e4b17023SJohn Marino c_parser_consume_token (parser);
10363*e4b17023SJohn Marino p_kind = PRAGMA_OMP_PARALLEL_SECTIONS;
10364*e4b17023SJohn Marino p_name = "#pragma omp parallel sections";
10365*e4b17023SJohn Marino mask |= OMP_SECTIONS_CLAUSE_MASK;
10366*e4b17023SJohn Marino mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT);
10367*e4b17023SJohn Marino }
10368*e4b17023SJohn Marino }
10369*e4b17023SJohn Marino
10370*e4b17023SJohn Marino clauses = c_parser_omp_all_clauses (parser, mask, p_name);
10371*e4b17023SJohn Marino
10372*e4b17023SJohn Marino switch (p_kind)
10373*e4b17023SJohn Marino {
10374*e4b17023SJohn Marino case PRAGMA_OMP_PARALLEL:
10375*e4b17023SJohn Marino block = c_begin_omp_parallel ();
10376*e4b17023SJohn Marino c_parser_statement (parser);
10377*e4b17023SJohn Marino stmt = c_finish_omp_parallel (loc, clauses, block);
10378*e4b17023SJohn Marino break;
10379*e4b17023SJohn Marino
10380*e4b17023SJohn Marino case PRAGMA_OMP_PARALLEL_FOR:
10381*e4b17023SJohn Marino block = c_begin_omp_parallel ();
10382*e4b17023SJohn Marino c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
10383*e4b17023SJohn Marino c_parser_omp_for_loop (loc, parser, ws_clause, &par_clause);
10384*e4b17023SJohn Marino stmt = c_finish_omp_parallel (loc, par_clause, block);
10385*e4b17023SJohn Marino OMP_PARALLEL_COMBINED (stmt) = 1;
10386*e4b17023SJohn Marino break;
10387*e4b17023SJohn Marino
10388*e4b17023SJohn Marino case PRAGMA_OMP_PARALLEL_SECTIONS:
10389*e4b17023SJohn Marino block = c_begin_omp_parallel ();
10390*e4b17023SJohn Marino c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
10391*e4b17023SJohn Marino stmt = c_parser_omp_sections_scope (loc, parser);
10392*e4b17023SJohn Marino if (stmt)
10393*e4b17023SJohn Marino OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
10394*e4b17023SJohn Marino stmt = c_finish_omp_parallel (loc, par_clause, block);
10395*e4b17023SJohn Marino OMP_PARALLEL_COMBINED (stmt) = 1;
10396*e4b17023SJohn Marino break;
10397*e4b17023SJohn Marino
10398*e4b17023SJohn Marino default:
10399*e4b17023SJohn Marino gcc_unreachable ();
10400*e4b17023SJohn Marino }
10401*e4b17023SJohn Marino
10402*e4b17023SJohn Marino return stmt;
10403*e4b17023SJohn Marino }
10404*e4b17023SJohn Marino
10405*e4b17023SJohn Marino /* OpenMP 2.5:
10406*e4b17023SJohn Marino # pragma omp single single-clause[optseq] new-line
10407*e4b17023SJohn Marino structured-block
10408*e4b17023SJohn Marino
10409*e4b17023SJohn Marino LOC is the location of the #pragma.
10410*e4b17023SJohn Marino */
10411*e4b17023SJohn Marino
10412*e4b17023SJohn Marino #define OMP_SINGLE_CLAUSE_MASK \
10413*e4b17023SJohn Marino ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \
10414*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
10415*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
10416*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
10417*e4b17023SJohn Marino
10418*e4b17023SJohn Marino static tree
c_parser_omp_single(location_t loc,c_parser * parser)10419*e4b17023SJohn Marino c_parser_omp_single (location_t loc, c_parser *parser)
10420*e4b17023SJohn Marino {
10421*e4b17023SJohn Marino tree stmt = make_node (OMP_SINGLE);
10422*e4b17023SJohn Marino SET_EXPR_LOCATION (stmt, loc);
10423*e4b17023SJohn Marino TREE_TYPE (stmt) = void_type_node;
10424*e4b17023SJohn Marino
10425*e4b17023SJohn Marino OMP_SINGLE_CLAUSES (stmt)
10426*e4b17023SJohn Marino = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
10427*e4b17023SJohn Marino "#pragma omp single");
10428*e4b17023SJohn Marino OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser);
10429*e4b17023SJohn Marino
10430*e4b17023SJohn Marino return add_stmt (stmt);
10431*e4b17023SJohn Marino }
10432*e4b17023SJohn Marino
10433*e4b17023SJohn Marino /* OpenMP 3.0:
10434*e4b17023SJohn Marino # pragma omp task task-clause[optseq] new-line
10435*e4b17023SJohn Marino
10436*e4b17023SJohn Marino LOC is the location of the #pragma.
10437*e4b17023SJohn Marino */
10438*e4b17023SJohn Marino
10439*e4b17023SJohn Marino #define OMP_TASK_CLAUSE_MASK \
10440*e4b17023SJohn Marino ( (1u << PRAGMA_OMP_CLAUSE_IF) \
10441*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_UNTIED) \
10442*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \
10443*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \
10444*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
10445*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_SHARED) \
10446*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_FINAL) \
10447*e4b17023SJohn Marino | (1u << PRAGMA_OMP_CLAUSE_MERGEABLE))
10448*e4b17023SJohn Marino
10449*e4b17023SJohn Marino static tree
c_parser_omp_task(location_t loc,c_parser * parser)10450*e4b17023SJohn Marino c_parser_omp_task (location_t loc, c_parser *parser)
10451*e4b17023SJohn Marino {
10452*e4b17023SJohn Marino tree clauses, block;
10453*e4b17023SJohn Marino
10454*e4b17023SJohn Marino clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
10455*e4b17023SJohn Marino "#pragma omp task");
10456*e4b17023SJohn Marino
10457*e4b17023SJohn Marino block = c_begin_omp_task ();
10458*e4b17023SJohn Marino c_parser_statement (parser);
10459*e4b17023SJohn Marino return c_finish_omp_task (loc, clauses, block);
10460*e4b17023SJohn Marino }
10461*e4b17023SJohn Marino
10462*e4b17023SJohn Marino /* OpenMP 3.0:
10463*e4b17023SJohn Marino # pragma omp taskwait new-line
10464*e4b17023SJohn Marino */
10465*e4b17023SJohn Marino
10466*e4b17023SJohn Marino static void
c_parser_omp_taskwait(c_parser * parser)10467*e4b17023SJohn Marino c_parser_omp_taskwait (c_parser *parser)
10468*e4b17023SJohn Marino {
10469*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
10470*e4b17023SJohn Marino c_parser_consume_pragma (parser);
10471*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
10472*e4b17023SJohn Marino
10473*e4b17023SJohn Marino c_finish_omp_taskwait (loc);
10474*e4b17023SJohn Marino }
10475*e4b17023SJohn Marino
10476*e4b17023SJohn Marino /* OpenMP 3.1:
10477*e4b17023SJohn Marino # pragma omp taskyield new-line
10478*e4b17023SJohn Marino */
10479*e4b17023SJohn Marino
10480*e4b17023SJohn Marino static void
c_parser_omp_taskyield(c_parser * parser)10481*e4b17023SJohn Marino c_parser_omp_taskyield (c_parser *parser)
10482*e4b17023SJohn Marino {
10483*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
10484*e4b17023SJohn Marino c_parser_consume_pragma (parser);
10485*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
10486*e4b17023SJohn Marino
10487*e4b17023SJohn Marino c_finish_omp_taskyield (loc);
10488*e4b17023SJohn Marino }
10489*e4b17023SJohn Marino
10490*e4b17023SJohn Marino /* Main entry point to parsing most OpenMP pragmas. */
10491*e4b17023SJohn Marino
10492*e4b17023SJohn Marino static void
c_parser_omp_construct(c_parser * parser)10493*e4b17023SJohn Marino c_parser_omp_construct (c_parser *parser)
10494*e4b17023SJohn Marino {
10495*e4b17023SJohn Marino enum pragma_kind p_kind;
10496*e4b17023SJohn Marino location_t loc;
10497*e4b17023SJohn Marino tree stmt;
10498*e4b17023SJohn Marino
10499*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
10500*e4b17023SJohn Marino p_kind = c_parser_peek_token (parser)->pragma_kind;
10501*e4b17023SJohn Marino c_parser_consume_pragma (parser);
10502*e4b17023SJohn Marino
10503*e4b17023SJohn Marino switch (p_kind)
10504*e4b17023SJohn Marino {
10505*e4b17023SJohn Marino case PRAGMA_OMP_ATOMIC:
10506*e4b17023SJohn Marino c_parser_omp_atomic (loc, parser);
10507*e4b17023SJohn Marino return;
10508*e4b17023SJohn Marino case PRAGMA_OMP_CRITICAL:
10509*e4b17023SJohn Marino stmt = c_parser_omp_critical (loc, parser);
10510*e4b17023SJohn Marino break;
10511*e4b17023SJohn Marino case PRAGMA_OMP_FOR:
10512*e4b17023SJohn Marino stmt = c_parser_omp_for (loc, parser);
10513*e4b17023SJohn Marino break;
10514*e4b17023SJohn Marino case PRAGMA_OMP_MASTER:
10515*e4b17023SJohn Marino stmt = c_parser_omp_master (loc, parser);
10516*e4b17023SJohn Marino break;
10517*e4b17023SJohn Marino case PRAGMA_OMP_ORDERED:
10518*e4b17023SJohn Marino stmt = c_parser_omp_ordered (loc, parser);
10519*e4b17023SJohn Marino break;
10520*e4b17023SJohn Marino case PRAGMA_OMP_PARALLEL:
10521*e4b17023SJohn Marino stmt = c_parser_omp_parallel (loc, parser);
10522*e4b17023SJohn Marino break;
10523*e4b17023SJohn Marino case PRAGMA_OMP_SECTIONS:
10524*e4b17023SJohn Marino stmt = c_parser_omp_sections (loc, parser);
10525*e4b17023SJohn Marino break;
10526*e4b17023SJohn Marino case PRAGMA_OMP_SINGLE:
10527*e4b17023SJohn Marino stmt = c_parser_omp_single (loc, parser);
10528*e4b17023SJohn Marino break;
10529*e4b17023SJohn Marino case PRAGMA_OMP_TASK:
10530*e4b17023SJohn Marino stmt = c_parser_omp_task (loc, parser);
10531*e4b17023SJohn Marino break;
10532*e4b17023SJohn Marino default:
10533*e4b17023SJohn Marino gcc_unreachable ();
10534*e4b17023SJohn Marino }
10535*e4b17023SJohn Marino
10536*e4b17023SJohn Marino if (stmt)
10537*e4b17023SJohn Marino gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
10538*e4b17023SJohn Marino }
10539*e4b17023SJohn Marino
10540*e4b17023SJohn Marino
10541*e4b17023SJohn Marino /* OpenMP 2.5:
10542*e4b17023SJohn Marino # pragma omp threadprivate (variable-list) */
10543*e4b17023SJohn Marino
10544*e4b17023SJohn Marino static void
c_parser_omp_threadprivate(c_parser * parser)10545*e4b17023SJohn Marino c_parser_omp_threadprivate (c_parser *parser)
10546*e4b17023SJohn Marino {
10547*e4b17023SJohn Marino tree vars, t;
10548*e4b17023SJohn Marino location_t loc;
10549*e4b17023SJohn Marino
10550*e4b17023SJohn Marino c_parser_consume_pragma (parser);
10551*e4b17023SJohn Marino loc = c_parser_peek_token (parser)->location;
10552*e4b17023SJohn Marino vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
10553*e4b17023SJohn Marino
10554*e4b17023SJohn Marino /* Mark every variable in VARS to be assigned thread local storage. */
10555*e4b17023SJohn Marino for (t = vars; t; t = TREE_CHAIN (t))
10556*e4b17023SJohn Marino {
10557*e4b17023SJohn Marino tree v = TREE_PURPOSE (t);
10558*e4b17023SJohn Marino
10559*e4b17023SJohn Marino /* FIXME diagnostics: Ideally we should keep individual
10560*e4b17023SJohn Marino locations for all the variables in the var list to make the
10561*e4b17023SJohn Marino following errors more precise. Perhaps
10562*e4b17023SJohn Marino c_parser_omp_var_list_parens() should construct a list of
10563*e4b17023SJohn Marino locations to go along with the var list. */
10564*e4b17023SJohn Marino
10565*e4b17023SJohn Marino /* If V had already been marked threadprivate, it doesn't matter
10566*e4b17023SJohn Marino whether it had been used prior to this point. */
10567*e4b17023SJohn Marino if (TREE_CODE (v) != VAR_DECL)
10568*e4b17023SJohn Marino error_at (loc, "%qD is not a variable", v);
10569*e4b17023SJohn Marino else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
10570*e4b17023SJohn Marino error_at (loc, "%qE declared %<threadprivate%> after first use", v);
10571*e4b17023SJohn Marino else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
10572*e4b17023SJohn Marino error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
10573*e4b17023SJohn Marino else if (TREE_TYPE (v) == error_mark_node)
10574*e4b17023SJohn Marino ;
10575*e4b17023SJohn Marino else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
10576*e4b17023SJohn Marino error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
10577*e4b17023SJohn Marino else
10578*e4b17023SJohn Marino {
10579*e4b17023SJohn Marino if (! DECL_THREAD_LOCAL_P (v))
10580*e4b17023SJohn Marino {
10581*e4b17023SJohn Marino DECL_TLS_MODEL (v) = decl_default_tls_model (v);
10582*e4b17023SJohn Marino /* If rtl has been already set for this var, call
10583*e4b17023SJohn Marino make_decl_rtl once again, so that encode_section_info
10584*e4b17023SJohn Marino has a chance to look at the new decl flags. */
10585*e4b17023SJohn Marino if (DECL_RTL_SET_P (v))
10586*e4b17023SJohn Marino make_decl_rtl (v);
10587*e4b17023SJohn Marino }
10588*e4b17023SJohn Marino C_DECL_THREADPRIVATE_P (v) = 1;
10589*e4b17023SJohn Marino }
10590*e4b17023SJohn Marino }
10591*e4b17023SJohn Marino
10592*e4b17023SJohn Marino c_parser_skip_to_pragma_eol (parser);
10593*e4b17023SJohn Marino }
10594*e4b17023SJohn Marino
10595*e4b17023SJohn Marino /* Parse a transaction attribute (GCC Extension).
10596*e4b17023SJohn Marino
10597*e4b17023SJohn Marino transaction-attribute:
10598*e4b17023SJohn Marino attributes
10599*e4b17023SJohn Marino [ [ any-word ] ]
10600*e4b17023SJohn Marino
10601*e4b17023SJohn Marino The transactional memory language description is written for C++,
10602*e4b17023SJohn Marino and uses the C++0x attribute syntax. For compatibility, allow the
10603*e4b17023SJohn Marino bracket style for transactions in C as well. */
10604*e4b17023SJohn Marino
10605*e4b17023SJohn Marino static tree
c_parser_transaction_attributes(c_parser * parser)10606*e4b17023SJohn Marino c_parser_transaction_attributes (c_parser *parser)
10607*e4b17023SJohn Marino {
10608*e4b17023SJohn Marino tree attr_name, attr = NULL;
10609*e4b17023SJohn Marino
10610*e4b17023SJohn Marino if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
10611*e4b17023SJohn Marino return c_parser_attributes (parser);
10612*e4b17023SJohn Marino
10613*e4b17023SJohn Marino if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
10614*e4b17023SJohn Marino return NULL_TREE;
10615*e4b17023SJohn Marino c_parser_consume_token (parser);
10616*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
10617*e4b17023SJohn Marino goto error1;
10618*e4b17023SJohn Marino
10619*e4b17023SJohn Marino attr_name = c_parser_attribute_any_word (parser);
10620*e4b17023SJohn Marino if (attr_name)
10621*e4b17023SJohn Marino {
10622*e4b17023SJohn Marino c_parser_consume_token (parser);
10623*e4b17023SJohn Marino attr = build_tree_list (attr_name, NULL_TREE);
10624*e4b17023SJohn Marino }
10625*e4b17023SJohn Marino else
10626*e4b17023SJohn Marino c_parser_error (parser, "expected identifier");
10627*e4b17023SJohn Marino
10628*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
10629*e4b17023SJohn Marino error1:
10630*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
10631*e4b17023SJohn Marino return attr;
10632*e4b17023SJohn Marino }
10633*e4b17023SJohn Marino
10634*e4b17023SJohn Marino /* Parse a __transaction_atomic or __transaction_relaxed statement
10635*e4b17023SJohn Marino (GCC Extension).
10636*e4b17023SJohn Marino
10637*e4b17023SJohn Marino transaction-statement:
10638*e4b17023SJohn Marino __transaction_atomic transaction-attribute[opt] compound-statement
10639*e4b17023SJohn Marino __transaction_relaxed compound-statement
10640*e4b17023SJohn Marino
10641*e4b17023SJohn Marino Note that the only valid attribute is: "outer".
10642*e4b17023SJohn Marino */
10643*e4b17023SJohn Marino
10644*e4b17023SJohn Marino static tree
c_parser_transaction(c_parser * parser,enum rid keyword)10645*e4b17023SJohn Marino c_parser_transaction (c_parser *parser, enum rid keyword)
10646*e4b17023SJohn Marino {
10647*e4b17023SJohn Marino unsigned int old_in = parser->in_transaction;
10648*e4b17023SJohn Marino unsigned int this_in = 1, new_in;
10649*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
10650*e4b17023SJohn Marino tree stmt, attrs;
10651*e4b17023SJohn Marino
10652*e4b17023SJohn Marino gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
10653*e4b17023SJohn Marino || keyword == RID_TRANSACTION_RELAXED)
10654*e4b17023SJohn Marino && c_parser_next_token_is_keyword (parser, keyword));
10655*e4b17023SJohn Marino c_parser_consume_token (parser);
10656*e4b17023SJohn Marino
10657*e4b17023SJohn Marino if (keyword == RID_TRANSACTION_RELAXED)
10658*e4b17023SJohn Marino this_in |= TM_STMT_ATTR_RELAXED;
10659*e4b17023SJohn Marino else
10660*e4b17023SJohn Marino {
10661*e4b17023SJohn Marino attrs = c_parser_transaction_attributes (parser);
10662*e4b17023SJohn Marino if (attrs)
10663*e4b17023SJohn Marino this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
10664*e4b17023SJohn Marino }
10665*e4b17023SJohn Marino
10666*e4b17023SJohn Marino /* Keep track if we're in the lexical scope of an outer transaction. */
10667*e4b17023SJohn Marino new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
10668*e4b17023SJohn Marino
10669*e4b17023SJohn Marino parser->in_transaction = new_in;
10670*e4b17023SJohn Marino stmt = c_parser_compound_statement (parser);
10671*e4b17023SJohn Marino parser->in_transaction = old_in;
10672*e4b17023SJohn Marino
10673*e4b17023SJohn Marino if (flag_tm)
10674*e4b17023SJohn Marino stmt = c_finish_transaction (loc, stmt, this_in);
10675*e4b17023SJohn Marino else
10676*e4b17023SJohn Marino error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
10677*e4b17023SJohn Marino "%<__transaction_atomic%> without transactional memory support enabled"
10678*e4b17023SJohn Marino : "%<__transaction_relaxed %> "
10679*e4b17023SJohn Marino "without transactional memory support enabled"));
10680*e4b17023SJohn Marino
10681*e4b17023SJohn Marino return stmt;
10682*e4b17023SJohn Marino }
10683*e4b17023SJohn Marino
10684*e4b17023SJohn Marino /* Parse a __transaction_atomic or __transaction_relaxed expression
10685*e4b17023SJohn Marino (GCC Extension).
10686*e4b17023SJohn Marino
10687*e4b17023SJohn Marino transaction-expression:
10688*e4b17023SJohn Marino __transaction_atomic ( expression )
10689*e4b17023SJohn Marino __transaction_relaxed ( expression )
10690*e4b17023SJohn Marino */
10691*e4b17023SJohn Marino
10692*e4b17023SJohn Marino static struct c_expr
c_parser_transaction_expression(c_parser * parser,enum rid keyword)10693*e4b17023SJohn Marino c_parser_transaction_expression (c_parser *parser, enum rid keyword)
10694*e4b17023SJohn Marino {
10695*e4b17023SJohn Marino struct c_expr ret;
10696*e4b17023SJohn Marino unsigned int old_in = parser->in_transaction;
10697*e4b17023SJohn Marino unsigned int this_in = 1;
10698*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
10699*e4b17023SJohn Marino tree attrs;
10700*e4b17023SJohn Marino
10701*e4b17023SJohn Marino gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
10702*e4b17023SJohn Marino || keyword == RID_TRANSACTION_RELAXED)
10703*e4b17023SJohn Marino && c_parser_next_token_is_keyword (parser, keyword));
10704*e4b17023SJohn Marino c_parser_consume_token (parser);
10705*e4b17023SJohn Marino
10706*e4b17023SJohn Marino if (keyword == RID_TRANSACTION_RELAXED)
10707*e4b17023SJohn Marino this_in |= TM_STMT_ATTR_RELAXED;
10708*e4b17023SJohn Marino else
10709*e4b17023SJohn Marino {
10710*e4b17023SJohn Marino attrs = c_parser_transaction_attributes (parser);
10711*e4b17023SJohn Marino if (attrs)
10712*e4b17023SJohn Marino this_in |= parse_tm_stmt_attr (attrs, 0);
10713*e4b17023SJohn Marino }
10714*e4b17023SJohn Marino
10715*e4b17023SJohn Marino parser->in_transaction = this_in;
10716*e4b17023SJohn Marino if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
10717*e4b17023SJohn Marino {
10718*e4b17023SJohn Marino tree expr = c_parser_expression (parser).value;
10719*e4b17023SJohn Marino ret.original_type = TREE_TYPE (expr);
10720*e4b17023SJohn Marino ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
10721*e4b17023SJohn Marino if (this_in & TM_STMT_ATTR_RELAXED)
10722*e4b17023SJohn Marino TRANSACTION_EXPR_RELAXED (ret.value) = 1;
10723*e4b17023SJohn Marino SET_EXPR_LOCATION (ret.value, loc);
10724*e4b17023SJohn Marino ret.original_code = TRANSACTION_EXPR;
10725*e4b17023SJohn Marino if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
10726*e4b17023SJohn Marino {
10727*e4b17023SJohn Marino c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10728*e4b17023SJohn Marino goto error;
10729*e4b17023SJohn Marino }
10730*e4b17023SJohn Marino }
10731*e4b17023SJohn Marino else
10732*e4b17023SJohn Marino {
10733*e4b17023SJohn Marino error:
10734*e4b17023SJohn Marino ret.value = error_mark_node;
10735*e4b17023SJohn Marino ret.original_code = ERROR_MARK;
10736*e4b17023SJohn Marino ret.original_type = NULL;
10737*e4b17023SJohn Marino }
10738*e4b17023SJohn Marino parser->in_transaction = old_in;
10739*e4b17023SJohn Marino
10740*e4b17023SJohn Marino if (!flag_tm)
10741*e4b17023SJohn Marino error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
10742*e4b17023SJohn Marino "%<__transaction_atomic%> without transactional memory support enabled"
10743*e4b17023SJohn Marino : "%<__transaction_relaxed %> "
10744*e4b17023SJohn Marino "without transactional memory support enabled"));
10745*e4b17023SJohn Marino
10746*e4b17023SJohn Marino return ret;
10747*e4b17023SJohn Marino }
10748*e4b17023SJohn Marino
10749*e4b17023SJohn Marino /* Parse a __transaction_cancel statement (GCC Extension).
10750*e4b17023SJohn Marino
10751*e4b17023SJohn Marino transaction-cancel-statement:
10752*e4b17023SJohn Marino __transaction_cancel transaction-attribute[opt] ;
10753*e4b17023SJohn Marino
10754*e4b17023SJohn Marino Note that the only valid attribute is "outer".
10755*e4b17023SJohn Marino */
10756*e4b17023SJohn Marino
10757*e4b17023SJohn Marino static tree
c_parser_transaction_cancel(c_parser * parser)10758*e4b17023SJohn Marino c_parser_transaction_cancel(c_parser *parser)
10759*e4b17023SJohn Marino {
10760*e4b17023SJohn Marino location_t loc = c_parser_peek_token (parser)->location;
10761*e4b17023SJohn Marino tree attrs;
10762*e4b17023SJohn Marino bool is_outer = false;
10763*e4b17023SJohn Marino
10764*e4b17023SJohn Marino gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
10765*e4b17023SJohn Marino c_parser_consume_token (parser);
10766*e4b17023SJohn Marino
10767*e4b17023SJohn Marino attrs = c_parser_transaction_attributes (parser);
10768*e4b17023SJohn Marino if (attrs)
10769*e4b17023SJohn Marino is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
10770*e4b17023SJohn Marino
10771*e4b17023SJohn Marino if (!flag_tm)
10772*e4b17023SJohn Marino {
10773*e4b17023SJohn Marino error_at (loc, "%<__transaction_cancel%> without "
10774*e4b17023SJohn Marino "transactional memory support enabled");
10775*e4b17023SJohn Marino goto ret_error;
10776*e4b17023SJohn Marino }
10777*e4b17023SJohn Marino else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
10778*e4b17023SJohn Marino {
10779*e4b17023SJohn Marino error_at (loc, "%<__transaction_cancel%> within a "
10780*e4b17023SJohn Marino "%<__transaction_relaxed%>");
10781*e4b17023SJohn Marino goto ret_error;
10782*e4b17023SJohn Marino }
10783*e4b17023SJohn Marino else if (is_outer)
10784*e4b17023SJohn Marino {
10785*e4b17023SJohn Marino if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
10786*e4b17023SJohn Marino && !is_tm_may_cancel_outer (current_function_decl))
10787*e4b17023SJohn Marino {
10788*e4b17023SJohn Marino error_at (loc, "outer %<__transaction_cancel%> not "
10789*e4b17023SJohn Marino "within outer %<__transaction_atomic%>");
10790*e4b17023SJohn Marino error_at (loc, " or a %<transaction_may_cancel_outer%> function");
10791*e4b17023SJohn Marino goto ret_error;
10792*e4b17023SJohn Marino }
10793*e4b17023SJohn Marino }
10794*e4b17023SJohn Marino else if (parser->in_transaction == 0)
10795*e4b17023SJohn Marino {
10796*e4b17023SJohn Marino error_at (loc, "%<__transaction_cancel%> not within "
10797*e4b17023SJohn Marino "%<__transaction_atomic%>");
10798*e4b17023SJohn Marino goto ret_error;
10799*e4b17023SJohn Marino }
10800*e4b17023SJohn Marino
10801*e4b17023SJohn Marino return add_stmt (build_tm_abort_call (loc, is_outer));
10802*e4b17023SJohn Marino
10803*e4b17023SJohn Marino ret_error:
10804*e4b17023SJohn Marino return build1 (NOP_EXPR, void_type_node, error_mark_node);
10805*e4b17023SJohn Marino }
10806*e4b17023SJohn Marino
10807*e4b17023SJohn Marino /* Parse a single source file. */
10808*e4b17023SJohn Marino
10809*e4b17023SJohn Marino void
c_parse_file(void)10810*e4b17023SJohn Marino c_parse_file (void)
10811*e4b17023SJohn Marino {
10812*e4b17023SJohn Marino /* Use local storage to begin. If the first token is a pragma, parse it.
10813*e4b17023SJohn Marino If it is #pragma GCC pch_preprocess, then this will load a PCH file
10814*e4b17023SJohn Marino which will cause garbage collection. */
10815*e4b17023SJohn Marino c_parser tparser;
10816*e4b17023SJohn Marino
10817*e4b17023SJohn Marino memset (&tparser, 0, sizeof tparser);
10818*e4b17023SJohn Marino the_parser = &tparser;
10819*e4b17023SJohn Marino
10820*e4b17023SJohn Marino if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
10821*e4b17023SJohn Marino c_parser_pragma_pch_preprocess (&tparser);
10822*e4b17023SJohn Marino
10823*e4b17023SJohn Marino the_parser = ggc_alloc_c_parser ();
10824*e4b17023SJohn Marino *the_parser = tparser;
10825*e4b17023SJohn Marino
10826*e4b17023SJohn Marino /* Initialize EH, if we've been told to do so. */
10827*e4b17023SJohn Marino if (flag_exceptions)
10828*e4b17023SJohn Marino using_eh_for_cleanups ();
10829*e4b17023SJohn Marino
10830*e4b17023SJohn Marino c_parser_translation_unit (the_parser);
10831*e4b17023SJohn Marino the_parser = NULL;
10832*e4b17023SJohn Marino }
10833*e4b17023SJohn Marino
10834*e4b17023SJohn Marino #include "gt-c-parser.h"
10835