1169689Skan/* Parser for C and Objective-C. 2169689Skan Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3169689Skan 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4169689Skan 5169689Skan Parser actions based on the old Bison parser; structure somewhat 6169689Skan influenced by and fragments based on the C++ parser. 7169689Skan 8169689SkanThis file is part of GCC. 9169689Skan 10169689SkanGCC is free software; you can redistribute it and/or modify it under 11169689Skanthe terms of the GNU General Public License as published by the Free 12169689SkanSoftware Foundation; either version 2, or (at your option) any later 13169689Skanversion. 14169689Skan 15169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 16169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 17169689SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18169689Skanfor more details. 19169689Skan 20169689SkanYou should have received a copy of the GNU General Public License 21169689Skanalong with GCC; see the file COPYING. If not, write to the Free 22169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 23169689Skan02110-1301, USA. */ 24169689Skan 25169689Skan/* TODO: 26169689Skan 27169689Skan Make sure all relevant comments, and all relevant code from all 28169689Skan actions, brought over from old parser. Verify exact correspondence 29169689Skan of syntax accepted. 30169689Skan 31169689Skan Add testcases covering every input symbol in every state in old and 32169689Skan new parsers. 33169689Skan 34169689Skan Include full syntax for GNU C, including erroneous cases accepted 35169689Skan with error messages, in syntax productions in comments. 36169689Skan 37169689Skan Make more diagnostics in the front end generally take an explicit 38169689Skan location rather than implicitly using input_location. */ 39169689Skan 40169689Skan#include "config.h" 41169689Skan#include "system.h" 42169689Skan#include "coretypes.h" 43169689Skan#include "tm.h" 44169689Skan#include "tree.h" 45169689Skan#include "rtl.h" 46169689Skan#include "langhooks.h" 47169689Skan#include "input.h" 48169689Skan#include "cpplib.h" 49169689Skan#include "timevar.h" 50169689Skan#include "c-pragma.h" 51169689Skan#include "c-tree.h" 52169689Skan#include "flags.h" 53169689Skan#include "output.h" 54169689Skan#include "toplev.h" 55169689Skan#include "ggc.h" 56169689Skan#include "c-common.h" 57169689Skan#include "vec.h" 58169689Skan#include "target.h" 59169689Skan#include "cgraph.h" 60169689Skan 61169689Skan 62169689Skan/* Miscellaneous data and functions needed for the parser. */ 63169689Skan 64169689Skanint yydebug; 65169689Skan 66169689Skan/* Objective-C specific parser/lexer information. */ 67169689Skan 68169689Skanstatic int objc_pq_context = 0; 69169689Skan 70169689Skan/* The following flag is needed to contextualize Objective-C lexical 71169689Skan analysis. In some cases (e.g., 'int NSObject;'), it is undesirable 72169689Skan to bind an identifier to an Objective-C class, even if a class with 73169689Skan that name exists. */ 74169689Skanstatic int objc_need_raw_identifier = 0; 75169689Skan#define OBJC_NEED_RAW_IDENTIFIER(VAL) \ 76169689Skan do { \ 77169689Skan if (c_dialect_objc ()) \ 78169689Skan objc_need_raw_identifier = VAL; \ 79169689Skan } while (0) 80169689Skan 81260311Spfg/* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 d) */ 82260311Spfg/* For checking property attribute keywords */ 83260311Spfgstatic int objc_property_attr_context; 84260311Spfg/* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 d) */ 85260311Spfg/* APPLE LOCAL radar 3803157 - objc attribute (in 4.2 e) */ 86260311Spfgstatic tree objc_method_attributes; 87260311Spfg/* APPLE LOCAL begin C* language (in 4.2 f) */ 88260311Spfg/* For checking for 'foreach' context. */ 89260311Spfgstatic int objc_foreach_context; 90260311Spfg/* APPLE LOCAL end C* language (in 4.2 f) */ 91260311Spfg 92169689Skan/* The reserved keyword table. */ 93169689Skanstruct resword 94169689Skan{ 95169689Skan const char *word; 96169689Skan ENUM_BITFIELD(rid) rid : 16; 97169689Skan unsigned int disable : 16; 98169689Skan}; 99169689Skan 100169689Skan/* Disable mask. Keywords are disabled if (reswords[i].disable & 101169689Skan mask) is _true_. */ 102169689Skan#define D_C89 0x01 /* not in C89 */ 103169689Skan#define D_EXT 0x02 /* GCC extension */ 104169689Skan#define D_EXT89 0x04 /* GCC extension incorporated in C99 */ 105169689Skan#define D_OBJC 0x08 /* Objective C only */ 106169689Skan 107169689Skanstatic const struct resword reswords[] = 108169689Skan{ 109169689Skan { "_Bool", RID_BOOL, 0 }, 110169689Skan { "_Complex", RID_COMPLEX, 0 }, 111169689Skan { "_Decimal32", RID_DFLOAT32, D_EXT }, 112169689Skan { "_Decimal64", RID_DFLOAT64, D_EXT }, 113169689Skan { "_Decimal128", RID_DFLOAT128, D_EXT }, 114169689Skan { "__FUNCTION__", RID_FUNCTION_NAME, 0 }, 115169689Skan { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 }, 116169689Skan { "__alignof", RID_ALIGNOF, 0 }, 117169689Skan { "__alignof__", RID_ALIGNOF, 0 }, 118169689Skan { "__asm", RID_ASM, 0 }, 119169689Skan { "__asm__", RID_ASM, 0 }, 120169689Skan { "__attribute", RID_ATTRIBUTE, 0 }, 121169689Skan { "__attribute__", RID_ATTRIBUTE, 0 }, 122169689Skan { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 }, 123169689Skan { "__builtin_offsetof", RID_OFFSETOF, 0 }, 124169689Skan { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 }, 125169689Skan { "__builtin_va_arg", RID_VA_ARG, 0 }, 126169689Skan { "__complex", RID_COMPLEX, 0 }, 127169689Skan { "__complex__", RID_COMPLEX, 0 }, 128169689Skan { "__const", RID_CONST, 0 }, 129169689Skan { "__const__", RID_CONST, 0 }, 130169689Skan { "__extension__", RID_EXTENSION, 0 }, 131169689Skan { "__func__", RID_C99_FUNCTION_NAME, 0 }, 132169689Skan { "__imag", RID_IMAGPART, 0 }, 133169689Skan { "__imag__", RID_IMAGPART, 0 }, 134169689Skan { "__inline", RID_INLINE, 0 }, 135169689Skan { "__inline__", RID_INLINE, 0 }, 136169689Skan { "__label__", RID_LABEL, 0 }, 137169689Skan { "__real", RID_REALPART, 0 }, 138169689Skan { "__real__", RID_REALPART, 0 }, 139169689Skan { "__restrict", RID_RESTRICT, 0 }, 140169689Skan { "__restrict__", RID_RESTRICT, 0 }, 141169689Skan { "__signed", RID_SIGNED, 0 }, 142169689Skan { "__signed__", RID_SIGNED, 0 }, 143169689Skan { "__thread", RID_THREAD, 0 }, 144169689Skan { "__typeof", RID_TYPEOF, 0 }, 145169689Skan { "__typeof__", RID_TYPEOF, 0 }, 146169689Skan { "__volatile", RID_VOLATILE, 0 }, 147169689Skan { "__volatile__", RID_VOLATILE, 0 }, 148169689Skan { "asm", RID_ASM, D_EXT }, 149169689Skan { "auto", RID_AUTO, 0 }, 150169689Skan { "break", RID_BREAK, 0 }, 151169689Skan { "case", RID_CASE, 0 }, 152169689Skan { "char", RID_CHAR, 0 }, 153169689Skan { "const", RID_CONST, 0 }, 154169689Skan { "continue", RID_CONTINUE, 0 }, 155169689Skan { "default", RID_DEFAULT, 0 }, 156169689Skan { "do", RID_DO, 0 }, 157169689Skan { "double", RID_DOUBLE, 0 }, 158169689Skan { "else", RID_ELSE, 0 }, 159169689Skan { "enum", RID_ENUM, 0 }, 160169689Skan { "extern", RID_EXTERN, 0 }, 161169689Skan { "float", RID_FLOAT, 0 }, 162169689Skan { "for", RID_FOR, 0 }, 163169689Skan { "goto", RID_GOTO, 0 }, 164169689Skan { "if", RID_IF, 0 }, 165169689Skan { "inline", RID_INLINE, D_EXT89 }, 166169689Skan { "int", RID_INT, 0 }, 167169689Skan { "long", RID_LONG, 0 }, 168169689Skan { "register", RID_REGISTER, 0 }, 169169689Skan { "restrict", RID_RESTRICT, D_C89 }, 170169689Skan { "return", RID_RETURN, 0 }, 171169689Skan { "short", RID_SHORT, 0 }, 172169689Skan { "signed", RID_SIGNED, 0 }, 173169689Skan { "sizeof", RID_SIZEOF, 0 }, 174169689Skan { "static", RID_STATIC, 0 }, 175169689Skan { "struct", RID_STRUCT, 0 }, 176169689Skan { "switch", RID_SWITCH, 0 }, 177169689Skan { "typedef", RID_TYPEDEF, 0 }, 178169689Skan { "typeof", RID_TYPEOF, D_EXT }, 179169689Skan { "union", RID_UNION, 0 }, 180169689Skan { "unsigned", RID_UNSIGNED, 0 }, 181169689Skan { "void", RID_VOID, 0 }, 182169689Skan { "volatile", RID_VOLATILE, 0 }, 183169689Skan { "while", RID_WHILE, 0 }, 184169689Skan /* These Objective-C keywords are recognized only immediately after 185169689Skan an '@'. */ 186169689Skan { "class", RID_AT_CLASS, D_OBJC }, 187169689Skan { "compatibility_alias", RID_AT_ALIAS, D_OBJC }, 188169689Skan { "defs", RID_AT_DEFS, D_OBJC }, 189169689Skan { "encode", RID_AT_ENCODE, D_OBJC }, 190169689Skan { "end", RID_AT_END, D_OBJC }, 191169689Skan { "implementation", RID_AT_IMPLEMENTATION, D_OBJC }, 192169689Skan { "interface", RID_AT_INTERFACE, D_OBJC }, 193260311Spfg /* APPLE LOCAL begin C* language (in 4.2 j) */ 194260311Spfg { "optional", RID_AT_OPTIONAL, D_OBJC }, 195260311Spfg { "required", RID_AT_REQUIRED, D_OBJC }, 196260311Spfg /* APPLE LOCAL end C* language (in 4.2 j) */ 197260311Spfg /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 k) */ 198260311Spfg { "property", RID_AT_PROPERTY, D_OBJC }, 199260311Spfg /* APPLE LOCAL radar 4564694 */ 200260311Spfg { "package", RID_AT_PACKAGE, D_OBJC }, 201169689Skan { "private", RID_AT_PRIVATE, D_OBJC }, 202169689Skan { "protected", RID_AT_PROTECTED, D_OBJC }, 203169689Skan { "protocol", RID_AT_PROTOCOL, D_OBJC }, 204169689Skan { "public", RID_AT_PUBLIC, D_OBJC }, 205169689Skan { "selector", RID_AT_SELECTOR, D_OBJC }, 206169689Skan { "throw", RID_AT_THROW, D_OBJC }, 207169689Skan { "try", RID_AT_TRY, D_OBJC }, 208169689Skan { "catch", RID_AT_CATCH, D_OBJC }, 209169689Skan { "finally", RID_AT_FINALLY, D_OBJC }, 210169689Skan { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC }, 211169689Skan /* These are recognized only in protocol-qualifier context 212169689Skan (see above) */ 213169689Skan { "bycopy", RID_BYCOPY, D_OBJC }, 214169689Skan { "byref", RID_BYREF, D_OBJC }, 215169689Skan { "in", RID_IN, D_OBJC }, 216169689Skan { "inout", RID_INOUT, D_OBJC }, 217169689Skan { "oneway", RID_ONEWAY, D_OBJC }, 218169689Skan { "out", RID_OUT, D_OBJC }, 219260311Spfg /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 l) */ 220260311Spfg /* These are recognized inside a property attribute list */ 221260311Spfg { "readonly", RID_READONLY, D_OBJC }, 222260311Spfg { "getter", RID_GETTER, D_OBJC }, 223260311Spfg { "setter", RID_SETTER, D_OBJC }, 224260311Spfg /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 l) */ 225260311Spfg /* APPLE LOCAL radar 4947014 - objc atomic property */ 226260311Spfg { "nonatomic", RID_NONATOMIC, D_OBJC }, 227169689Skan}; 228169689Skan#define N_reswords (sizeof reswords / sizeof (struct resword)) 229169689Skan 230169689Skan/* All OpenMP clauses. OpenMP 2.5. */ 231169689Skantypedef enum pragma_omp_clause { 232169689Skan PRAGMA_OMP_CLAUSE_NONE = 0, 233169689Skan 234169689Skan PRAGMA_OMP_CLAUSE_COPYIN, 235169689Skan PRAGMA_OMP_CLAUSE_COPYPRIVATE, 236169689Skan PRAGMA_OMP_CLAUSE_DEFAULT, 237169689Skan PRAGMA_OMP_CLAUSE_FIRSTPRIVATE, 238169689Skan PRAGMA_OMP_CLAUSE_IF, 239169689Skan PRAGMA_OMP_CLAUSE_LASTPRIVATE, 240169689Skan PRAGMA_OMP_CLAUSE_NOWAIT, 241169689Skan PRAGMA_OMP_CLAUSE_NUM_THREADS, 242169689Skan PRAGMA_OMP_CLAUSE_ORDERED, 243169689Skan PRAGMA_OMP_CLAUSE_PRIVATE, 244169689Skan PRAGMA_OMP_CLAUSE_REDUCTION, 245169689Skan PRAGMA_OMP_CLAUSE_SCHEDULE, 246169689Skan PRAGMA_OMP_CLAUSE_SHARED 247169689Skan} pragma_omp_clause; 248169689Skan 249169689Skan 250169689Skan/* Initialization routine for this file. */ 251169689Skan 252169689Skanvoid 253169689Skanc_parse_init (void) 254169689Skan{ 255169689Skan /* The only initialization required is of the reserved word 256169689Skan identifiers. */ 257169689Skan unsigned int i; 258169689Skan tree id; 259169689Skan int mask = (flag_isoc99 ? 0 : D_C89) 260169689Skan | (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0); 261169689Skan 262169689Skan if (!c_dialect_objc ()) 263169689Skan mask |= D_OBJC; 264169689Skan 265169689Skan ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX); 266169689Skan for (i = 0; i < N_reswords; i++) 267169689Skan { 268169689Skan /* If a keyword is disabled, do not enter it into the table 269169689Skan and so create a canonical spelling that isn't a keyword. */ 270169689Skan if (reswords[i].disable & mask) 271169689Skan continue; 272169689Skan 273169689Skan id = get_identifier (reswords[i].word); 274169689Skan C_RID_CODE (id) = reswords[i].rid; 275169689Skan C_IS_RESERVED_WORD (id) = 1; 276169689Skan ridpointers [(int) reswords[i].rid] = id; 277169689Skan } 278169689Skan} 279169689Skan 280169689Skan/* The C lexer intermediates between the lexer in cpplib and c-lex.c 281169689Skan and the C parser. Unlike the C++ lexer, the parser structure 282169689Skan stores the lexer information instead of using a separate structure. 283169689Skan Identifiers are separated into ordinary identifiers, type names, 284169689Skan keywords and some other Objective-C types of identifiers, and some 285169689Skan look-ahead is maintained. 286169689Skan 287169689Skan ??? It might be a good idea to lex the whole file up front (as for 288169689Skan C++). It would then be possible to share more of the C and C++ 289169689Skan lexer code, if desired. */ 290169689Skan 291169689Skan/* The following local token type is used. */ 292169689Skan 293169689Skan/* A keyword. */ 294169689Skan#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1)) 295169689Skan 296169689Skan/* More information about the type of a CPP_NAME token. */ 297169689Skantypedef enum c_id_kind { 298169689Skan /* An ordinary identifier. */ 299169689Skan C_ID_ID, 300169689Skan /* An identifier declared as a typedef name. */ 301169689Skan C_ID_TYPENAME, 302169689Skan /* An identifier declared as an Objective-C class name. */ 303169689Skan C_ID_CLASSNAME, 304169689Skan /* Not an identifier. */ 305169689Skan C_ID_NONE 306169689Skan} c_id_kind; 307169689Skan 308169689Skan/* A single C token after string literal concatenation and conversion 309169689Skan of preprocessing tokens to tokens. */ 310169689Skantypedef struct c_token GTY (()) 311169689Skan{ 312169689Skan /* The kind of token. */ 313169689Skan ENUM_BITFIELD (cpp_ttype) type : 8; 314169689Skan /* If this token is a CPP_NAME, this value indicates whether also 315169689Skan declared as some kind of type. Otherwise, it is C_ID_NONE. */ 316169689Skan ENUM_BITFIELD (c_id_kind) id_kind : 8; 317169689Skan /* If this token is a keyword, this value indicates which keyword. 318169689Skan Otherwise, this value is RID_MAX. */ 319169689Skan ENUM_BITFIELD (rid) keyword : 8; 320169689Skan /* If this token is a CPP_PRAGMA, this indicates the pragma that 321169689Skan was seen. Otherwise it is PRAGMA_NONE. */ 322169689Skan ENUM_BITFIELD (pragma_kind) pragma_kind : 7; 323169689Skan /* True if this token is from a system header. */ 324169689Skan BOOL_BITFIELD in_system_header : 1; 325169689Skan /* The value associated with this token, if any. */ 326169689Skan tree value; 327169689Skan /* The location at which this token was found. */ 328169689Skan location_t location; 329169689Skan} c_token; 330169689Skan 331169689Skan/* A parser structure recording information about the state and 332169689Skan context of parsing. Includes lexer information with up to two 333169689Skan tokens of look-ahead; more are not needed for C. */ 334169689Skantypedef struct c_parser GTY(()) 335169689Skan{ 336169689Skan /* The look-ahead tokens. */ 337169689Skan c_token tokens[2]; 338169689Skan /* How many look-ahead tokens are available (0, 1 or 2). */ 339169689Skan short tokens_avail; 340169689Skan /* True if a syntax error is being recovered from; false otherwise. 341169689Skan c_parser_error sets this flag. It should clear this flag when 342169689Skan enough tokens have been consumed to recover from the error. */ 343169689Skan BOOL_BITFIELD error : 1; 344169689Skan /* True if we're processing a pragma, and shouldn't automatically 345169689Skan consume CPP_PRAGMA_EOL. */ 346169689Skan BOOL_BITFIELD in_pragma : 1; 347169689Skan} c_parser; 348169689Skan 349169689Skan 350169689Skan/* The actual parser and external interface. ??? Does this need to be 351169689Skan garbage-collected? */ 352169689Skan 353169689Skanstatic GTY (()) c_parser *the_parser; 354169689Skan 355260311Spfg/* APPLE LOCAL C* language (in 4.2 ae) */ 356260311Spfgstatic c_token * c_parser_peek_2nd_token (c_parser *); 357169689Skan 358169689Skan/* Read in and lex a single token, storing it in *TOKEN. */ 359169689Skan 360169689Skanstatic void 361260311Spfgc_lex_one_token (c_token *token, c_parser *parser) 362169689Skan{ 363169689Skan timevar_push (TV_LEX); 364169689Skan 365169689Skan token->type = c_lex_with_flags (&token->value, &token->location, NULL); 366169689Skan token->id_kind = C_ID_NONE; 367169689Skan token->keyword = RID_MAX; 368169689Skan token->pragma_kind = PRAGMA_NONE; 369169689Skan token->in_system_header = in_system_header; 370169689Skan 371169689Skan switch (token->type) 372169689Skan { 373169689Skan case CPP_NAME: 374169689Skan { 375169689Skan tree decl; 376169689Skan 377169689Skan int objc_force_identifier = objc_need_raw_identifier; 378169689Skan OBJC_NEED_RAW_IDENTIFIER (0); 379169689Skan 380169689Skan if (C_IS_RESERVED_WORD (token->value)) 381169689Skan { 382169689Skan enum rid rid_code = C_RID_CODE (token->value); 383169689Skan 384169689Skan if (c_dialect_objc ()) 385169689Skan { 386169689Skan if (!OBJC_IS_AT_KEYWORD (rid_code) 387169689Skan && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context)) 388169689Skan { 389169689Skan /* Return the canonical spelling for this keyword. */ 390169689Skan token->value = ridpointers[(int) rid_code]; 391169689Skan token->type = CPP_KEYWORD; 392169689Skan token->keyword = rid_code; 393169689Skan break; 394169689Skan } 395260311Spfg /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */ 396260311Spfg else if (objc_foreach_context && rid_code == RID_IN) 397260311Spfg { 398260311Spfg /* This is dangerous, we assume we don't need 3 input tokens look ahead. */ 399260311Spfg c_token *tk = c_parser_peek_2nd_token (parser); 400260311Spfg if (tk->type == CPP_NAME 401260311Spfg || tk->type == CPP_OPEN_PAREN 402260311Spfg || tk->type == CPP_MULT 403260311Spfg || tk->type == CPP_PLUS 404260311Spfg || tk->type == CPP_PLUS_PLUS 405260311Spfg || tk->type == CPP_MINUS 406260311Spfg || tk->type == CPP_MINUS_MINUS 407260311Spfg /* APPLE LOCAL radar 4529200 (in 4.2 af) */ 408260311Spfg || tk->type == CPP_OPEN_SQUARE) 409260311Spfg { 410260311Spfg token->type = CPP_KEYWORD; 411260311Spfg token->keyword = rid_code; 412260311Spfg break; 413260311Spfg } 414260311Spfg } 415260311Spfg /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */ 416169689Skan } 417169689Skan else 418169689Skan { 419169689Skan /* Return the canonical spelling for this keyword. */ 420169689Skan token->value = ridpointers[(int) rid_code]; 421169689Skan token->type = CPP_KEYWORD; 422169689Skan token->keyword = rid_code; 423169689Skan break; 424169689Skan } 425169689Skan } 426169689Skan 427169689Skan decl = lookup_name (token->value); 428169689Skan if (decl) 429169689Skan { 430169689Skan if (TREE_CODE (decl) == TYPE_DECL) 431169689Skan { 432169689Skan token->id_kind = C_ID_TYPENAME; 433169689Skan break; 434169689Skan } 435169689Skan } 436169689Skan else if (c_dialect_objc ()) 437169689Skan { 438169689Skan tree objc_interface_decl = objc_is_class_name (token->value); 439169689Skan /* Objective-C class names are in the same namespace as 440169689Skan variables and typedefs, and hence are shadowed by local 441169689Skan declarations. */ 442169689Skan if (objc_interface_decl 443169689Skan && (global_bindings_p () 444169689Skan || (!objc_force_identifier && !decl))) 445169689Skan { 446169689Skan token->value = objc_interface_decl; 447169689Skan token->id_kind = C_ID_CLASSNAME; 448169689Skan break; 449169689Skan } 450169689Skan } 451169689Skan token->id_kind = C_ID_ID; 452169689Skan } 453169689Skan break; 454169689Skan case CPP_AT_NAME: 455169689Skan /* This only happens in Objective-C; it must be a keyword. */ 456169689Skan token->type = CPP_KEYWORD; 457169689Skan token->keyword = C_RID_CODE (token->value); 458169689Skan break; 459169689Skan case CPP_COLON: 460169689Skan case CPP_COMMA: 461169689Skan case CPP_CLOSE_PAREN: 462169689Skan case CPP_SEMICOLON: 463169689Skan /* These tokens may affect the interpretation of any identifiers 464169689Skan following, if doing Objective-C. */ 465169689Skan OBJC_NEED_RAW_IDENTIFIER (0); 466169689Skan break; 467169689Skan case CPP_PRAGMA: 468169689Skan /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */ 469169689Skan token->pragma_kind = TREE_INT_CST_LOW (token->value); 470169689Skan token->value = NULL; 471169689Skan break; 472169689Skan default: 473169689Skan break; 474169689Skan } 475169689Skan timevar_pop (TV_LEX); 476169689Skan} 477169689Skan 478169689Skan/* Return a pointer to the next token from PARSER, reading it in if 479169689Skan necessary. */ 480169689Skan 481169689Skanstatic inline c_token * 482169689Skanc_parser_peek_token (c_parser *parser) 483169689Skan{ 484169689Skan if (parser->tokens_avail == 0) 485169689Skan { 486260311Spfg /* APPLE LOCAL begin switch these two */ 487169689Skan parser->tokens_avail = 1; 488260311Spfg /* APPLE LOCAL C* language (in 4.2 ae) */ 489260311Spfg c_lex_one_token (&parser->tokens[0], parser); 490260311Spfg /* APPLE LOCAL end switch these two */ 491169689Skan } 492169689Skan return &parser->tokens[0]; 493169689Skan} 494169689Skan 495169689Skan/* Return true if the next token from PARSER has the indicated 496169689Skan TYPE. */ 497169689Skan 498169689Skanstatic inline bool 499169689Skanc_parser_next_token_is (c_parser *parser, enum cpp_ttype type) 500169689Skan{ 501169689Skan return c_parser_peek_token (parser)->type == type; 502169689Skan} 503169689Skan 504169689Skan/* Return true if the next token from PARSER does not have the 505169689Skan indicated TYPE. */ 506169689Skan 507169689Skanstatic inline bool 508169689Skanc_parser_next_token_is_not (c_parser *parser, enum cpp_ttype type) 509169689Skan{ 510169689Skan return !c_parser_next_token_is (parser, type); 511169689Skan} 512169689Skan 513169689Skan/* Return true if the next token from PARSER is the indicated 514169689Skan KEYWORD. */ 515169689Skan 516169689Skanstatic inline bool 517169689Skanc_parser_next_token_is_keyword (c_parser *parser, enum rid keyword) 518169689Skan{ 519169689Skan c_token *token; 520169689Skan 521169689Skan /* Peek at the next token. */ 522169689Skan token = c_parser_peek_token (parser); 523169689Skan /* Check to see if it is the indicated keyword. */ 524169689Skan return token->keyword == keyword; 525169689Skan} 526169689Skan 527169689Skan/* Return true if TOKEN can start a type name, 528169689Skan false otherwise. */ 529169689Skanstatic bool 530169689Skanc_token_starts_typename (c_token *token) 531169689Skan{ 532169689Skan switch (token->type) 533169689Skan { 534169689Skan case CPP_NAME: 535169689Skan switch (token->id_kind) 536169689Skan { 537169689Skan case C_ID_ID: 538169689Skan return false; 539169689Skan case C_ID_TYPENAME: 540169689Skan return true; 541169689Skan case C_ID_CLASSNAME: 542169689Skan gcc_assert (c_dialect_objc ()); 543169689Skan return true; 544169689Skan default: 545169689Skan gcc_unreachable (); 546169689Skan } 547169689Skan case CPP_KEYWORD: 548169689Skan switch (token->keyword) 549169689Skan { 550169689Skan case RID_UNSIGNED: 551169689Skan case RID_LONG: 552169689Skan case RID_SHORT: 553169689Skan case RID_SIGNED: 554169689Skan case RID_COMPLEX: 555169689Skan case RID_INT: 556169689Skan case RID_CHAR: 557169689Skan case RID_FLOAT: 558169689Skan case RID_DOUBLE: 559169689Skan case RID_VOID: 560169689Skan case RID_DFLOAT32: 561169689Skan case RID_DFLOAT64: 562169689Skan case RID_DFLOAT128: 563169689Skan case RID_BOOL: 564169689Skan case RID_ENUM: 565169689Skan case RID_STRUCT: 566169689Skan case RID_UNION: 567169689Skan case RID_TYPEOF: 568169689Skan case RID_CONST: 569169689Skan case RID_VOLATILE: 570169689Skan case RID_RESTRICT: 571169689Skan case RID_ATTRIBUTE: 572169689Skan return true; 573169689Skan default: 574169689Skan return false; 575169689Skan } 576169689Skan case CPP_LESS: 577169689Skan if (c_dialect_objc ()) 578169689Skan return true; 579169689Skan return false; 580169689Skan default: 581169689Skan return false; 582169689Skan } 583169689Skan} 584169689Skan 585169689Skan/* Return true if the next token from PARSER can start a type name, 586169689Skan false otherwise. */ 587169689Skanstatic inline bool 588169689Skanc_parser_next_token_starts_typename (c_parser *parser) 589169689Skan{ 590169689Skan c_token *token = c_parser_peek_token (parser); 591169689Skan return c_token_starts_typename (token); 592169689Skan} 593169689Skan 594169689Skan/* Return true if TOKEN can start declaration specifiers, false 595169689Skan otherwise. */ 596169689Skanstatic bool 597169689Skanc_token_starts_declspecs (c_token *token) 598169689Skan{ 599169689Skan switch (token->type) 600169689Skan { 601169689Skan case CPP_NAME: 602169689Skan switch (token->id_kind) 603169689Skan { 604169689Skan case C_ID_ID: 605169689Skan return false; 606169689Skan case C_ID_TYPENAME: 607169689Skan return true; 608169689Skan case C_ID_CLASSNAME: 609169689Skan gcc_assert (c_dialect_objc ()); 610169689Skan return true; 611169689Skan default: 612169689Skan gcc_unreachable (); 613169689Skan } 614169689Skan case CPP_KEYWORD: 615169689Skan switch (token->keyword) 616169689Skan { 617169689Skan case RID_STATIC: 618169689Skan case RID_EXTERN: 619169689Skan case RID_REGISTER: 620169689Skan case RID_TYPEDEF: 621169689Skan case RID_INLINE: 622169689Skan case RID_AUTO: 623169689Skan case RID_THREAD: 624169689Skan case RID_UNSIGNED: 625169689Skan case RID_LONG: 626169689Skan case RID_SHORT: 627169689Skan case RID_SIGNED: 628169689Skan case RID_COMPLEX: 629169689Skan case RID_INT: 630169689Skan case RID_CHAR: 631169689Skan case RID_FLOAT: 632169689Skan case RID_DOUBLE: 633169689Skan case RID_VOID: 634169689Skan case RID_DFLOAT32: 635169689Skan case RID_DFLOAT64: 636169689Skan case RID_DFLOAT128: 637169689Skan case RID_BOOL: 638169689Skan case RID_ENUM: 639169689Skan case RID_STRUCT: 640169689Skan case RID_UNION: 641169689Skan case RID_TYPEOF: 642169689Skan case RID_CONST: 643169689Skan case RID_VOLATILE: 644169689Skan case RID_RESTRICT: 645169689Skan case RID_ATTRIBUTE: 646169689Skan return true; 647169689Skan default: 648169689Skan return false; 649169689Skan } 650169689Skan case CPP_LESS: 651169689Skan if (c_dialect_objc ()) 652169689Skan return true; 653169689Skan return false; 654169689Skan default: 655169689Skan return false; 656169689Skan } 657169689Skan} 658169689Skan 659169689Skan/* Return true if the next token from PARSER can start declaration 660169689Skan specifiers, false otherwise. */ 661169689Skanstatic inline bool 662169689Skanc_parser_next_token_starts_declspecs (c_parser *parser) 663169689Skan{ 664169689Skan c_token *token = c_parser_peek_token (parser); 665260311Spfg /* APPLE LOCAL begin radar 5277239 */ 666260311Spfg /* Yes, we can have CLASS.method to mean property-style dot-syntax 667260311Spfg notation to call a class method (equiv to [CLASS meth]). */ 668260311Spfg return c_token_starts_declspecs (token) 669260311Spfg && (token->id_kind != C_ID_CLASSNAME 670260311Spfg || c_parser_peek_2nd_token (parser)->type != CPP_DOT); 671260311Spfg /* APPLE LOCAL end radar 5277239 */ 672169689Skan} 673169689Skan 674169689Skan/* Return a pointer to the next-but-one token from PARSER, reading it 675169689Skan in if necessary. The next token is already read in. */ 676169689Skan 677169689Skanstatic c_token * 678169689Skanc_parser_peek_2nd_token (c_parser *parser) 679169689Skan{ 680169689Skan if (parser->tokens_avail >= 2) 681169689Skan return &parser->tokens[1]; 682169689Skan gcc_assert (parser->tokens_avail == 1); 683169689Skan gcc_assert (parser->tokens[0].type != CPP_EOF); 684169689Skan gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL); 685260311Spfg /* APPLE LOCAL begin switch these two */ 686169689Skan parser->tokens_avail = 2; 687260311Spfg /* APPLE LOCAL C* language (in 4.2 ae) */ 688260311Spfg c_lex_one_token (&parser->tokens[1], parser); 689260311Spfg /* APPLE LOCAL end switch these two */ 690169689Skan return &parser->tokens[1]; 691169689Skan} 692169689Skan 693169689Skan/* Consume the next token from PARSER. */ 694169689Skan 695169689Skanstatic void 696169689Skanc_parser_consume_token (c_parser *parser) 697169689Skan{ 698169689Skan gcc_assert (parser->tokens_avail >= 1); 699169689Skan gcc_assert (parser->tokens[0].type != CPP_EOF); 700169689Skan gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL); 701169689Skan gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA); 702169689Skan if (parser->tokens_avail == 2) 703169689Skan parser->tokens[0] = parser->tokens[1]; 704169689Skan parser->tokens_avail--; 705169689Skan} 706169689Skan 707169689Skan/* Expect the current token to be a #pragma. Consume it and remember 708169689Skan that we've begun parsing a pragma. */ 709169689Skan 710169689Skanstatic void 711169689Skanc_parser_consume_pragma (c_parser *parser) 712169689Skan{ 713169689Skan gcc_assert (!parser->in_pragma); 714169689Skan gcc_assert (parser->tokens_avail >= 1); 715169689Skan gcc_assert (parser->tokens[0].type == CPP_PRAGMA); 716169689Skan if (parser->tokens_avail == 2) 717169689Skan parser->tokens[0] = parser->tokens[1]; 718169689Skan parser->tokens_avail--; 719169689Skan parser->in_pragma = true; 720169689Skan} 721169689Skan 722169689Skan/* Update the globals input_location and in_system_header from 723169689Skan TOKEN. */ 724169689Skanstatic inline void 725169689Skanc_parser_set_source_position_from_token (c_token *token) 726169689Skan{ 727169689Skan if (token->type != CPP_EOF) 728169689Skan { 729169689Skan input_location = token->location; 730169689Skan in_system_header = token->in_system_header; 731169689Skan } 732169689Skan} 733169689Skan 734169689Skan/* Issue a diagnostic of the form 735169689Skan FILE:LINE: MESSAGE before TOKEN 736169689Skan where TOKEN is the next token in the input stream of PARSER. 737169689Skan MESSAGE (specified by the caller) is usually of the form "expected 738169689Skan OTHER-TOKEN". 739169689Skan 740169689Skan Do not issue a diagnostic if still recovering from an error. 741169689Skan 742169689Skan ??? This is taken from the C++ parser, but building up messages in 743169689Skan this way is not i18n-friendly and some other approach should be 744169689Skan used. */ 745169689Skan 746169689Skanstatic void 747169689Skanc_parser_error (c_parser *parser, const char *gmsgid) 748169689Skan{ 749169689Skan c_token *token = c_parser_peek_token (parser); 750169689Skan if (parser->error) 751169689Skan return; 752169689Skan parser->error = true; 753169689Skan if (!gmsgid) 754169689Skan return; 755169689Skan /* This diagnostic makes more sense if it is tagged to the line of 756169689Skan the token we just peeked at. */ 757169689Skan c_parser_set_source_position_from_token (token); 758169689Skan c_parse_error (gmsgid, 759169689Skan /* Because c_parse_error does not understand 760169689Skan CPP_KEYWORD, keywords are treated like 761169689Skan identifiers. */ 762169689Skan (token->type == CPP_KEYWORD ? CPP_NAME : token->type), 763169689Skan token->value); 764169689Skan} 765169689Skan 766169689Skan/* If the next token is of the indicated TYPE, consume it. Otherwise, 767169689Skan issue the error MSGID. If MSGID is NULL then a message has already 768169689Skan been produced and no message will be produced this time. Returns 769169689Skan true if found, false otherwise. */ 770169689Skan 771169689Skanstatic bool 772169689Skanc_parser_require (c_parser *parser, 773169689Skan enum cpp_ttype type, 774169689Skan const char *msgid) 775169689Skan{ 776169689Skan if (c_parser_next_token_is (parser, type)) 777169689Skan { 778169689Skan c_parser_consume_token (parser); 779169689Skan return true; 780169689Skan } 781169689Skan else 782169689Skan { 783169689Skan c_parser_error (parser, msgid); 784169689Skan return false; 785169689Skan } 786169689Skan} 787169689Skan 788169689Skan/* If the next token is the indicated keyword, consume it. Otherwise, 789169689Skan issue the error MSGID. Returns true if found, false otherwise. */ 790169689Skan 791169689Skanstatic bool 792169689Skanc_parser_require_keyword (c_parser *parser, 793169689Skan enum rid keyword, 794169689Skan const char *msgid) 795169689Skan{ 796169689Skan if (c_parser_next_token_is_keyword (parser, keyword)) 797169689Skan { 798169689Skan c_parser_consume_token (parser); 799169689Skan return true; 800169689Skan } 801169689Skan else 802169689Skan { 803169689Skan c_parser_error (parser, msgid); 804169689Skan return false; 805169689Skan } 806169689Skan} 807169689Skan 808169689Skan/* Like c_parser_require, except that tokens will be skipped until the 809169689Skan desired token is found. An error message is still produced if the 810169689Skan next token is not as expected. If MSGID is NULL then a message has 811169689Skan already been produced and no message will be produced this 812169689Skan time. */ 813169689Skan 814169689Skanstatic void 815169689Skanc_parser_skip_until_found (c_parser *parser, 816169689Skan enum cpp_ttype type, 817169689Skan const char *msgid) 818169689Skan{ 819169689Skan unsigned nesting_depth = 0; 820169689Skan 821169689Skan if (c_parser_require (parser, type, msgid)) 822169689Skan return; 823169689Skan 824169689Skan /* Skip tokens until the desired token is found. */ 825169689Skan while (true) 826169689Skan { 827169689Skan /* Peek at the next token. */ 828169689Skan c_token *token = c_parser_peek_token (parser); 829169689Skan /* If we've reached the token we want, consume it and stop. */ 830169689Skan if (token->type == type && !nesting_depth) 831169689Skan { 832169689Skan c_parser_consume_token (parser); 833169689Skan break; 834169689Skan } 835169689Skan 836169689Skan /* If we've run out of tokens, stop. */ 837169689Skan if (token->type == CPP_EOF) 838169689Skan return; 839169689Skan if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) 840169689Skan return; 841169689Skan if (token->type == CPP_OPEN_BRACE 842169689Skan || token->type == CPP_OPEN_PAREN 843169689Skan || token->type == CPP_OPEN_SQUARE) 844169689Skan ++nesting_depth; 845169689Skan else if (token->type == CPP_CLOSE_BRACE 846169689Skan || token->type == CPP_CLOSE_PAREN 847169689Skan || token->type == CPP_CLOSE_SQUARE) 848169689Skan { 849169689Skan if (nesting_depth-- == 0) 850169689Skan break; 851169689Skan } 852169689Skan /* Consume this token. */ 853169689Skan c_parser_consume_token (parser); 854169689Skan } 855169689Skan parser->error = false; 856169689Skan} 857169689Skan 858169689Skan/* Skip tokens until the end of a parameter is found, but do not 859169689Skan consume the comma, semicolon or closing delimiter. */ 860169689Skan 861169689Skanstatic void 862169689Skanc_parser_skip_to_end_of_parameter (c_parser *parser) 863169689Skan{ 864169689Skan unsigned nesting_depth = 0; 865169689Skan 866169689Skan while (true) 867169689Skan { 868169689Skan c_token *token = c_parser_peek_token (parser); 869169689Skan if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON) 870169689Skan && !nesting_depth) 871169689Skan break; 872169689Skan /* If we've run out of tokens, stop. */ 873169689Skan if (token->type == CPP_EOF) 874169689Skan return; 875169689Skan if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) 876169689Skan return; 877169689Skan if (token->type == CPP_OPEN_BRACE 878169689Skan || token->type == CPP_OPEN_PAREN 879169689Skan || token->type == CPP_OPEN_SQUARE) 880169689Skan ++nesting_depth; 881169689Skan else if (token->type == CPP_CLOSE_BRACE 882169689Skan || token->type == CPP_CLOSE_PAREN 883169689Skan || token->type == CPP_CLOSE_SQUARE) 884169689Skan { 885169689Skan if (nesting_depth-- == 0) 886169689Skan break; 887169689Skan } 888169689Skan /* Consume this token. */ 889169689Skan c_parser_consume_token (parser); 890169689Skan } 891169689Skan parser->error = false; 892169689Skan} 893169689Skan 894169689Skan/* Expect to be at the end of the pragma directive and consume an 895169689Skan end of line marker. */ 896169689Skan 897169689Skanstatic void 898169689Skanc_parser_skip_to_pragma_eol (c_parser *parser) 899169689Skan{ 900169689Skan gcc_assert (parser->in_pragma); 901169689Skan parser->in_pragma = false; 902169689Skan 903169689Skan if (!c_parser_require (parser, CPP_PRAGMA_EOL, "expected end of line")) 904169689Skan while (true) 905169689Skan { 906169689Skan c_token *token = c_parser_peek_token (parser); 907169689Skan if (token->type == CPP_EOF) 908169689Skan break; 909169689Skan if (token->type == CPP_PRAGMA_EOL) 910169689Skan { 911169689Skan c_parser_consume_token (parser); 912169689Skan break; 913169689Skan } 914169689Skan c_parser_consume_token (parser); 915169689Skan } 916169689Skan 917169689Skan parser->error = false; 918169689Skan} 919169689Skan 920169689Skan/* Skip tokens until we have consumed an entire block, or until we 921169689Skan have consumed a non-nested ';'. */ 922169689Skan 923169689Skanstatic void 924169689Skanc_parser_skip_to_end_of_block_or_statement (c_parser *parser) 925169689Skan{ 926169689Skan unsigned nesting_depth = 0; 927169689Skan bool save_error = parser->error; 928169689Skan 929169689Skan while (true) 930169689Skan { 931169689Skan c_token *token; 932169689Skan 933169689Skan /* Peek at the next token. */ 934169689Skan token = c_parser_peek_token (parser); 935169689Skan 936169689Skan switch (token->type) 937169689Skan { 938169689Skan case CPP_EOF: 939169689Skan return; 940169689Skan 941169689Skan case CPP_PRAGMA_EOL: 942169689Skan if (parser->in_pragma) 943169689Skan return; 944169689Skan break; 945169689Skan 946169689Skan case CPP_SEMICOLON: 947169689Skan /* If the next token is a ';', we have reached the 948169689Skan end of the statement. */ 949169689Skan if (!nesting_depth) 950169689Skan { 951169689Skan /* Consume the ';'. */ 952169689Skan c_parser_consume_token (parser); 953169689Skan goto finished; 954169689Skan } 955169689Skan break; 956169689Skan 957169689Skan case CPP_CLOSE_BRACE: 958169689Skan /* If the next token is a non-nested '}', then we have 959169689Skan reached the end of the current block. */ 960169689Skan if (nesting_depth == 0 || --nesting_depth == 0) 961169689Skan { 962169689Skan c_parser_consume_token (parser); 963169689Skan goto finished; 964169689Skan } 965169689Skan break; 966169689Skan 967169689Skan case CPP_OPEN_BRACE: 968169689Skan /* If it the next token is a '{', then we are entering a new 969169689Skan block. Consume the entire block. */ 970169689Skan ++nesting_depth; 971169689Skan break; 972169689Skan 973169689Skan case CPP_PRAGMA: 974169689Skan /* If we see a pragma, consume the whole thing at once. We 975169689Skan have some safeguards against consuming pragmas willy-nilly. 976169689Skan Normally, we'd expect to be here with parser->error set, 977169689Skan which disables these safeguards. But it's possible to get 978169689Skan here for secondary error recovery, after parser->error has 979169689Skan been cleared. */ 980169689Skan c_parser_consume_pragma (parser); 981169689Skan c_parser_skip_to_pragma_eol (parser); 982169689Skan parser->error = save_error; 983169689Skan continue; 984169689Skan 985169689Skan default: 986169689Skan break; 987169689Skan } 988169689Skan 989169689Skan c_parser_consume_token (parser); 990169689Skan } 991169689Skan 992169689Skan finished: 993169689Skan parser->error = false; 994169689Skan} 995169689Skan 996169689Skan/* Save the warning flags which are controlled by __extension__. */ 997169689Skan 998169689Skanstatic inline int 999169689Skandisable_extension_diagnostics (void) 1000169689Skan{ 1001169689Skan int ret = (pedantic 1002169689Skan | (warn_pointer_arith << 1) 1003169689Skan | (warn_traditional << 2) 1004169689Skan | (flag_iso << 3)); 1005169689Skan pedantic = 0; 1006169689Skan warn_pointer_arith = 0; 1007169689Skan warn_traditional = 0; 1008169689Skan flag_iso = 0; 1009169689Skan return ret; 1010169689Skan} 1011169689Skan 1012169689Skan/* Restore the warning flags which are controlled by __extension__. 1013169689Skan FLAGS is the return value from disable_extension_diagnostics. */ 1014169689Skan 1015169689Skanstatic inline void 1016169689Skanrestore_extension_diagnostics (int flags) 1017169689Skan{ 1018169689Skan pedantic = flags & 1; 1019169689Skan warn_pointer_arith = (flags >> 1) & 1; 1020169689Skan warn_traditional = (flags >> 2) & 1; 1021169689Skan flag_iso = (flags >> 3) & 1; 1022169689Skan} 1023169689Skan 1024169689Skan/* Possibly kinds of declarator to parse. */ 1025169689Skantypedef enum c_dtr_syn { 1026169689Skan /* A normal declarator with an identifier. */ 1027169689Skan C_DTR_NORMAL, 1028169689Skan /* An abstract declarator (maybe empty). */ 1029169689Skan C_DTR_ABSTRACT, 1030260311Spfg /* APPLE LOCAL begin blocks 6339747 */ 1031260311Spfg /* A block declarator (maybe empty). */ 1032260311Spfg C_DTR_BLOCK, 1033260311Spfg /* APPLE LOCAL end blocks 6339747 */ 1034169689Skan /* A parameter declarator: may be either, but after a type name does 1035169689Skan not redeclare a typedef name as an identifier if it can 1036169689Skan alternatively be interpreted as a typedef name; see DR#009, 1037169689Skan applied in C90 TC1, omitted from C99 and reapplied in C99 TC2 1038169689Skan following DR#249. For example, given a typedef T, "int T" and 1039169689Skan "int *T" are valid parameter declarations redeclaring T, while 1040169689Skan "int (T)" and "int * (T)" and "int (T[])" and "int (T (int))" are 1041169689Skan abstract declarators rather than involving redundant parentheses; 1042169689Skan the same applies with attributes inside the parentheses before 1043169689Skan "T". */ 1044169689Skan C_DTR_PARM 1045169689Skan} c_dtr_syn; 1046169689Skan 1047169689Skanstatic void c_parser_external_declaration (c_parser *); 1048169689Skanstatic void c_parser_asm_definition (c_parser *); 1049260311Spfg/* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 1050260311Spfgstatic void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, bool, tree*); 1051169689Skanstatic void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool, 1052169689Skan bool); 1053169689Skanstatic struct c_typespec c_parser_enum_specifier (c_parser *); 1054169689Skanstatic struct c_typespec c_parser_struct_or_union_specifier (c_parser *); 1055169689Skanstatic tree c_parser_struct_declaration (c_parser *); 1056169689Skanstatic struct c_typespec c_parser_typeof_specifier (c_parser *); 1057169689Skanstatic struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn, 1058169689Skan bool *); 1059169689Skanstatic struct c_declarator *c_parser_direct_declarator (c_parser *, bool, 1060169689Skan c_dtr_syn, bool *); 1061169689Skanstatic struct c_declarator *c_parser_direct_declarator_inner (c_parser *, 1062169689Skan bool, 1063169689Skan struct c_declarator *); 1064169689Skanstatic struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree); 1065169689Skanstatic struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree); 1066169689Skanstatic struct c_parm *c_parser_parameter_declaration (c_parser *, tree); 1067169689Skanstatic tree c_parser_simple_asm_expr (c_parser *); 1068169689Skanstatic tree c_parser_attributes (c_parser *); 1069169689Skanstatic struct c_type_name *c_parser_type_name (c_parser *); 1070169689Skanstatic struct c_expr c_parser_initializer (c_parser *); 1071169689Skanstatic struct c_expr c_parser_braced_init (c_parser *, tree, bool); 1072169689Skanstatic void c_parser_initelt (c_parser *); 1073169689Skanstatic void c_parser_initval (c_parser *, struct c_expr *); 1074169689Skanstatic tree c_parser_compound_statement (c_parser *); 1075169689Skanstatic void c_parser_compound_statement_nostart (c_parser *); 1076169689Skanstatic void c_parser_label (c_parser *); 1077169689Skanstatic void c_parser_statement (c_parser *); 1078169689Skanstatic void c_parser_statement_after_labels (c_parser *); 1079169689Skanstatic void c_parser_if_statement (c_parser *); 1080169689Skanstatic void c_parser_switch_statement (c_parser *); 1081169689Skanstatic void c_parser_while_statement (c_parser *); 1082169689Skanstatic void c_parser_do_statement (c_parser *); 1083169689Skanstatic void c_parser_for_statement (c_parser *); 1084169689Skanstatic tree c_parser_asm_statement (c_parser *); 1085260311Spfg/* APPLE LOCAL begin radar 5732232 - blocks (C++ ca) */ 1086260311Spfgstatic tree c_parser_block_literal_expr (c_parser *); 1087260311Spfg/* APPLE LOCAL end radar 5732232 - blocks (C++ ca) */ 1088169689Skanstatic tree c_parser_asm_operands (c_parser *, bool); 1089169689Skanstatic tree c_parser_asm_clobbers (c_parser *); 1090169689Skanstatic struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *); 1091169689Skanstatic struct c_expr c_parser_conditional_expression (c_parser *, 1092169689Skan struct c_expr *); 1093169689Skanstatic struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *); 1094169689Skanstatic struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *); 1095169689Skanstatic struct c_expr c_parser_unary_expression (c_parser *); 1096169689Skanstatic struct c_expr c_parser_sizeof_expression (c_parser *); 1097169689Skanstatic struct c_expr c_parser_alignof_expression (c_parser *); 1098169689Skanstatic struct c_expr c_parser_postfix_expression (c_parser *); 1099169689Skanstatic struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *, 1100169689Skan struct c_type_name *); 1101169689Skanstatic struct c_expr c_parser_postfix_expression_after_primary (c_parser *, 1102169689Skan struct c_expr); 1103169689Skanstatic struct c_expr c_parser_expression (c_parser *); 1104169689Skanstatic struct c_expr c_parser_expression_conv (c_parser *); 1105169689Skanstatic tree c_parser_expr_list (c_parser *, bool); 1106169689Skanstatic void c_parser_omp_construct (c_parser *); 1107169689Skanstatic void c_parser_omp_threadprivate (c_parser *); 1108169689Skanstatic void c_parser_omp_barrier (c_parser *); 1109169689Skanstatic void c_parser_omp_flush (c_parser *); 1110169689Skan 1111169689Skanenum pragma_context { pragma_external, pragma_stmt, pragma_compound }; 1112169689Skanstatic bool c_parser_pragma (c_parser *, enum pragma_context); 1113169689Skan 1114169689Skan/* These Objective-C parser functions are only ever called when 1115169689Skan compiling Objective-C. */ 1116260311Spfg/* APPLE LOCAL radar 4548636 - class attributes. */ 1117260311Spfgstatic void c_parser_objc_class_definition (c_parser *, tree); 1118169689Skanstatic void c_parser_objc_class_instance_variables (c_parser *); 1119169689Skanstatic void c_parser_objc_class_declaration (c_parser *); 1120169689Skanstatic void c_parser_objc_alias_declaration (c_parser *); 1121260311Spfg/* APPLE LOCAL radar 4947311 - protocol attributes */ 1122260311Spfgstatic void c_parser_objc_protocol_definition (c_parser *, tree); 1123169689Skanstatic enum tree_code c_parser_objc_method_type (c_parser *); 1124169689Skanstatic void c_parser_objc_method_definition (c_parser *); 1125260311Spfg/* APPLE LOCAL C* property (Radar 4436866) (in 4.2 b) */ 1126260311Spfgstatic void c_parser_objc_interfacedecllist (c_parser *); 1127260311Spfg/* APPLE LOCAL C* property (Radar 4436866) (in 4.2 x) */ 1128260311Spfgstatic void c_parser_objc_property_declaration (c_parser *); 1129169689Skanstatic void c_parser_objc_methodproto (c_parser *); 1130169689Skanstatic tree c_parser_objc_method_decl (c_parser *); 1131169689Skanstatic tree c_parser_objc_type_name (c_parser *); 1132169689Skanstatic tree c_parser_objc_protocol_refs (c_parser *); 1133169689Skanstatic void c_parser_objc_try_catch_statement (c_parser *); 1134169689Skanstatic void c_parser_objc_synchronized_statement (c_parser *); 1135169689Skanstatic tree c_parser_objc_selector (c_parser *); 1136169689Skanstatic tree c_parser_objc_selector_arg (c_parser *); 1137169689Skanstatic tree c_parser_objc_receiver (c_parser *); 1138169689Skanstatic tree c_parser_objc_message_args (c_parser *); 1139169689Skanstatic tree c_parser_objc_keywordexpr (c_parser *); 1140169689Skan 1141169689Skan/* Parse a translation unit (C90 6.7, C99 6.9). 1142169689Skan 1143169689Skan translation-unit: 1144169689Skan external-declarations 1145169689Skan 1146169689Skan external-declarations: 1147169689Skan external-declaration 1148169689Skan external-declarations external-declaration 1149169689Skan 1150169689Skan GNU extensions: 1151169689Skan 1152169689Skan translation-unit: 1153169689Skan empty 1154169689Skan*/ 1155169689Skan 1156169689Skanstatic void 1157169689Skanc_parser_translation_unit (c_parser *parser) 1158169689Skan{ 1159169689Skan if (c_parser_next_token_is (parser, CPP_EOF)) 1160169689Skan { 1161169689Skan if (pedantic) 1162169689Skan pedwarn ("ISO C forbids an empty source file"); 1163169689Skan } 1164169689Skan else 1165169689Skan { 1166169689Skan void *obstack_position = obstack_alloc (&parser_obstack, 0); 1167169689Skan do 1168169689Skan { 1169169689Skan ggc_collect (); 1170169689Skan c_parser_external_declaration (parser); 1171169689Skan obstack_free (&parser_obstack, obstack_position); 1172169689Skan } 1173169689Skan while (c_parser_next_token_is_not (parser, CPP_EOF)); 1174169689Skan } 1175169689Skan} 1176169689Skan 1177169689Skan/* Parse an external declaration (C90 6.7, C99 6.9). 1178169689Skan 1179169689Skan external-declaration: 1180169689Skan function-definition 1181169689Skan declaration 1182169689Skan 1183169689Skan GNU extensions: 1184169689Skan 1185169689Skan external-declaration: 1186169689Skan asm-definition 1187169689Skan ; 1188169689Skan __extension__ external-declaration 1189169689Skan 1190169689Skan Objective-C: 1191169689Skan 1192169689Skan external-declaration: 1193169689Skan objc-class-definition 1194169689Skan objc-class-declaration 1195169689Skan objc-alias-declaration 1196169689Skan objc-protocol-definition 1197169689Skan objc-method-definition 1198169689Skan @end 1199169689Skan*/ 1200169689Skan 1201169689Skanstatic void 1202169689Skanc_parser_external_declaration (c_parser *parser) 1203169689Skan{ 1204169689Skan int ext; 1205169689Skan switch (c_parser_peek_token (parser)->type) 1206169689Skan { 1207169689Skan case CPP_KEYWORD: 1208169689Skan switch (c_parser_peek_token (parser)->keyword) 1209169689Skan { 1210169689Skan case RID_EXTENSION: 1211169689Skan ext = disable_extension_diagnostics (); 1212169689Skan c_parser_consume_token (parser); 1213169689Skan c_parser_external_declaration (parser); 1214169689Skan restore_extension_diagnostics (ext); 1215169689Skan break; 1216169689Skan case RID_ASM: 1217169689Skan c_parser_asm_definition (parser); 1218169689Skan break; 1219169689Skan case RID_AT_INTERFACE: 1220169689Skan case RID_AT_IMPLEMENTATION: 1221169689Skan gcc_assert (c_dialect_objc ()); 1222260311Spfg /* APPLE LOCAL radar 4548636 - class attributes. */ 1223260311Spfg c_parser_objc_class_definition (parser, NULL_TREE); 1224169689Skan break; 1225169689Skan case RID_AT_CLASS: 1226169689Skan gcc_assert (c_dialect_objc ()); 1227169689Skan c_parser_objc_class_declaration (parser); 1228169689Skan break; 1229169689Skan case RID_AT_ALIAS: 1230169689Skan gcc_assert (c_dialect_objc ()); 1231169689Skan c_parser_objc_alias_declaration (parser); 1232169689Skan break; 1233169689Skan case RID_AT_PROTOCOL: 1234169689Skan gcc_assert (c_dialect_objc ()); 1235260311Spfg /* APPLE LOCAL begin radar 4947311 - protocol attributes */ 1236260311Spfg c_parser_objc_protocol_definition (parser, NULL_TREE); 1237169689Skan break; 1238260311Spfg /* APPLE LOCAL end radar 4947311 - protocol attributes */ 1239260311Spfg /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 x) */ 1240260311Spfg case RID_AT_PROPERTY: 1241260311Spfg c_parser_objc_property_declaration (parser); 1242260311Spfg break; 1243260311Spfg /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 x) */ 1244169689Skan case RID_AT_END: 1245169689Skan gcc_assert (c_dialect_objc ()); 1246169689Skan c_parser_consume_token (parser); 1247169689Skan objc_finish_implementation (); 1248169689Skan break; 1249169689Skan default: 1250169689Skan goto decl_or_fndef; 1251169689Skan } 1252169689Skan break; 1253169689Skan case CPP_SEMICOLON: 1254169689Skan if (pedantic) 1255169689Skan pedwarn ("ISO C does not allow extra %<;%> outside of a function"); 1256169689Skan c_parser_consume_token (parser); 1257169689Skan break; 1258169689Skan case CPP_PRAGMA: 1259169689Skan c_parser_pragma (parser, pragma_external); 1260169689Skan break; 1261169689Skan case CPP_PLUS: 1262169689Skan case CPP_MINUS: 1263169689Skan if (c_dialect_objc ()) 1264169689Skan { 1265169689Skan c_parser_objc_method_definition (parser); 1266169689Skan break; 1267169689Skan } 1268169689Skan /* Else fall through, and yield a syntax error trying to parse 1269169689Skan as a declaration or function definition. */ 1270169689Skan default: 1271169689Skan decl_or_fndef: 1272169689Skan /* A declaration or a function definition. We can only tell 1273169689Skan which after parsing the declaration specifiers, if any, and 1274169689Skan the first declarator. */ 1275260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 1276260311Spfg c_parser_declaration_or_fndef (parser, true, true, false, true, NULL); 1277169689Skan break; 1278169689Skan } 1279169689Skan} 1280169689Skan 1281169689Skan 1282169689Skan/* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 1283169689Skan 6.7, 6.9.1). If FNDEF_OK is true, a function definition is 1284169689Skan accepted; otherwise (old-style parameter declarations) only other 1285169689Skan declarations are accepted. If NESTED is true, we are inside a 1286169689Skan function or parsing old-style parameter declarations; any functions 1287169689Skan encountered are nested functions and declaration specifiers are 1288169689Skan required; otherwise we are at top level and functions are normal 1289169689Skan functions and declaration specifiers may be optional. If EMPTY_OK 1290169689Skan is true, empty declarations are OK (subject to all other 1291169689Skan constraints); otherwise (old-style parameter declarations) they are 1292169689Skan diagnosed. If START_ATTR_OK is true, the declaration specifiers 1293169689Skan may start with attributes; otherwise they may not. 1294169689Skan 1295169689Skan declaration: 1296169689Skan declaration-specifiers init-declarator-list[opt] ; 1297169689Skan 1298169689Skan function-definition: 1299169689Skan declaration-specifiers[opt] declarator declaration-list[opt] 1300169689Skan compound-statement 1301169689Skan 1302169689Skan declaration-list: 1303169689Skan declaration 1304169689Skan declaration-list declaration 1305169689Skan 1306169689Skan init-declarator-list: 1307169689Skan init-declarator 1308169689Skan init-declarator-list , init-declarator 1309169689Skan 1310169689Skan init-declarator: 1311169689Skan declarator simple-asm-expr[opt] attributes[opt] 1312169689Skan declarator simple-asm-expr[opt] attributes[opt] = initializer 1313169689Skan 1314169689Skan GNU extensions: 1315169689Skan 1316169689Skan nested-function-definition: 1317169689Skan declaration-specifiers declarator declaration-list[opt] 1318169689Skan compound-statement 1319169689Skan 1320169689Skan The simple-asm-expr and attributes are GNU extensions. 1321169689Skan 1322169689Skan This function does not handle __extension__; that is handled in its 1323169689Skan callers. ??? Following the old parser, __extension__ may start 1324169689Skan external declarations, declarations in functions and declarations 1325169689Skan at the start of "for" loops, but not old-style parameter 1326169689Skan declarations. 1327169689Skan 1328169689Skan C99 requires declaration specifiers in a function definition; the 1329169689Skan absence is diagnosed through the diagnosis of implicit int. In GNU 1330169689Skan C we also allow but diagnose declarations without declaration 1331169689Skan specifiers, but only at top level (elsewhere they conflict with 1332169689Skan other syntax). 1333169689Skan 1334169689Skan OpenMP: 1335169689Skan 1336169689Skan declaration: 1337169689Skan threadprivate-directive */ 1338169689Skan 1339169689Skanstatic void 1340169689Skanc_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok, 1341260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 1342260311Spfg bool nested, bool start_attr_ok, tree *foreach_elem) 1343169689Skan{ 1344169689Skan struct c_declspecs *specs; 1345169689Skan tree prefix_attrs; 1346169689Skan tree all_prefix_attrs; 1347169689Skan bool diagnosed_no_specs = false; 1348169689Skan 1349169689Skan specs = build_null_declspecs (); 1350169689Skan c_parser_declspecs (parser, specs, true, true, start_attr_ok); 1351169689Skan if (parser->error) 1352169689Skan { 1353169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 1354169689Skan return; 1355169689Skan } 1356169689Skan if (nested && !specs->declspecs_seen_p) 1357169689Skan { 1358169689Skan c_parser_error (parser, "expected declaration specifiers"); 1359169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 1360169689Skan return; 1361169689Skan } 1362169689Skan finish_declspecs (specs); 1363169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 1364169689Skan { 1365169689Skan if (empty_ok) 1366169689Skan shadow_tag (specs); 1367169689Skan else 1368169689Skan { 1369169689Skan shadow_tag_warned (specs, 1); 1370169689Skan pedwarn ("empty declaration"); 1371169689Skan } 1372169689Skan c_parser_consume_token (parser); 1373169689Skan return; 1374169689Skan } 1375260311Spfg /* APPLE LOCAL begin radar 4548636 - class attributes. */ 1376260311Spfg else if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE) 1377260311Spfg || c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION)) 1378260311Spfg { 1379260311Spfg gcc_assert (c_dialect_objc ()); 1380260311Spfg if (!specs->declspecs_seen_p || specs->attrs == NULL_TREE 1381260311Spfg || specs->type_seen_p || specs->non_sc_seen_p) 1382260311Spfg c_parser_error (parser, "no type or storage class may be specified here"); 1383260311Spfg c_parser_objc_class_definition (parser, specs->attrs); 1384260311Spfg return; 1385260311Spfg } 1386260311Spfg /* APPLE LOCAL end radar 4548636 - class attributes. */ 1387260311Spfg /* APPLE LOCAL begin radar 4947311 - protocol attributes */ 1388260311Spfg else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL)) 1389260311Spfg { 1390260311Spfg gcc_assert (c_dialect_objc ()); 1391260311Spfg if (!specs->declspecs_seen_p || specs->attrs == NULL_TREE 1392260311Spfg || specs->type_seen_p || specs->non_sc_seen_p) 1393260311Spfg c_parser_error (parser, "no type or storage class may be specified here"); 1394260311Spfg c_parser_objc_protocol_definition (parser, specs->attrs); 1395260311Spfg return; 1396260311Spfg } 1397260311Spfg /* APPLE LOCAL end radar 4947311 - protocol attributes */ 1398169689Skan pending_xref_error (); 1399169689Skan prefix_attrs = specs->attrs; 1400169689Skan all_prefix_attrs = prefix_attrs; 1401169689Skan specs->attrs = NULL_TREE; 1402169689Skan while (true) 1403169689Skan { 1404169689Skan struct c_declarator *declarator; 1405169689Skan bool dummy = false; 1406169689Skan tree fnbody; 1407169689Skan /* Declaring either one or more declarators (in which case we 1408169689Skan should diagnose if there were no declaration specifiers) or a 1409169689Skan function definition (in which case the diagnostic for 1410169689Skan implicit int suffices). */ 1411169689Skan declarator = c_parser_declarator (parser, specs->type_seen_p, 1412169689Skan C_DTR_NORMAL, &dummy); 1413169689Skan if (declarator == NULL) 1414169689Skan { 1415169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 1416169689Skan return; 1417169689Skan } 1418169689Skan if (c_parser_next_token_is (parser, CPP_EQ) 1419169689Skan || c_parser_next_token_is (parser, CPP_COMMA) 1420169689Skan || c_parser_next_token_is (parser, CPP_SEMICOLON) 1421169689Skan || c_parser_next_token_is_keyword (parser, RID_ASM) 1422260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 1423260311Spfg || c_parser_next_token_is_keyword (parser, RID_IN) 1424169689Skan || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 1425169689Skan { 1426169689Skan tree asm_name = NULL_TREE; 1427169689Skan tree postfix_attrs = NULL_TREE; 1428169689Skan if (!diagnosed_no_specs && !specs->declspecs_seen_p) 1429169689Skan { 1430169689Skan diagnosed_no_specs = true; 1431169689Skan pedwarn ("data definition has no type or storage class"); 1432169689Skan } 1433169689Skan /* Having seen a data definition, there cannot now be a 1434169689Skan function definition. */ 1435169689Skan fndef_ok = false; 1436169689Skan if (c_parser_next_token_is_keyword (parser, RID_ASM)) 1437169689Skan asm_name = c_parser_simple_asm_expr (parser); 1438169689Skan if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 1439169689Skan postfix_attrs = c_parser_attributes (parser); 1440260311Spfg /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */ 1441260311Spfg if (c_parser_next_token_is_keyword (parser, RID_IN)) 1442260311Spfg { 1443260311Spfg gcc_assert (foreach_elem); 1444260311Spfg *foreach_elem = start_decl (declarator, specs, true, 1445260311Spfg chainon (postfix_attrs, all_prefix_attrs)); 1446260311Spfg if (!*foreach_elem) 1447260311Spfg *foreach_elem = error_mark_node; 1448260311Spfg start_init (*foreach_elem, asm_name, global_bindings_p ()); 1449260311Spfg return; 1450260311Spfg } 1451260311Spfg /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */ 1452169689Skan if (c_parser_next_token_is (parser, CPP_EQ)) 1453169689Skan { 1454169689Skan tree d; 1455169689Skan struct c_expr init; 1456169689Skan c_parser_consume_token (parser); 1457169689Skan /* The declaration of the variable is in effect while 1458169689Skan its initializer is parsed. */ 1459169689Skan d = start_decl (declarator, specs, true, 1460169689Skan chainon (postfix_attrs, all_prefix_attrs)); 1461169689Skan if (!d) 1462169689Skan d = error_mark_node; 1463169689Skan start_init (d, asm_name, global_bindings_p ()); 1464169689Skan init = c_parser_initializer (parser); 1465169689Skan finish_init (); 1466169689Skan if (d != error_mark_node) 1467169689Skan { 1468169689Skan maybe_warn_string_init (TREE_TYPE (d), init); 1469169689Skan finish_decl (d, init.value, asm_name); 1470169689Skan } 1471169689Skan } 1472169689Skan else 1473169689Skan { 1474169689Skan tree d = start_decl (declarator, specs, false, 1475169689Skan chainon (postfix_attrs, 1476169689Skan all_prefix_attrs)); 1477169689Skan if (d) 1478169689Skan finish_decl (d, NULL_TREE, asm_name); 1479169689Skan } 1480169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 1481169689Skan { 1482169689Skan c_parser_consume_token (parser); 1483169689Skan if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 1484169689Skan all_prefix_attrs = chainon (c_parser_attributes (parser), 1485169689Skan prefix_attrs); 1486169689Skan else 1487169689Skan all_prefix_attrs = prefix_attrs; 1488169689Skan continue; 1489169689Skan } 1490169689Skan else if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 1491169689Skan { 1492169689Skan c_parser_consume_token (parser); 1493169689Skan return; 1494169689Skan } 1495169689Skan else 1496169689Skan { 1497169689Skan c_parser_error (parser, "expected %<,%> or %<;%>"); 1498169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 1499169689Skan return; 1500169689Skan } 1501169689Skan } 1502169689Skan else if (!fndef_ok) 1503169689Skan { 1504169689Skan c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, " 1505169689Skan "%<asm%> or %<__attribute__%>"); 1506169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 1507169689Skan return; 1508169689Skan } 1509169689Skan /* Function definition (nested or otherwise). */ 1510169689Skan if (nested) 1511169689Skan { 1512260311Spfg /* APPLE LOCAL begin radar 5985368 */ 1513260311Spfg if (declarator->declarator && declarator->declarator->kind == cdk_block_pointer) 1514260311Spfg error ("bad definition of a block"); 1515260311Spfg else if (pedantic) 1516260311Spfg /* APPLE LOCAL end radar 5985368 */ 1517169689Skan pedwarn ("ISO C forbids nested functions"); 1518260311Spfg /* APPLE LOCAL begin nested functions 4258406 4357979 (in 4.2 m) */ 1519260311Spfg else if (flag_nested_functions == 0) 1520260311Spfg error ("nested functions are disabled, use -fnested-functions to re-enable"); 1521260311Spfg /* APPLE LOCAL end nested functions 4258406 4357979 (in 4.2 m) */ 1522260311Spfg 1523169689Skan push_function_context (); 1524169689Skan } 1525169689Skan if (!start_function (specs, declarator, all_prefix_attrs)) 1526169689Skan { 1527169689Skan /* This can appear in many cases looking nothing like a 1528169689Skan function definition, so we don't give a more specific 1529169689Skan error suggesting there was one. */ 1530169689Skan c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> " 1531169689Skan "or %<__attribute__%>"); 1532169689Skan if (nested) 1533169689Skan pop_function_context (); 1534169689Skan break; 1535169689Skan } 1536169689Skan /* Parse old-style parameter declarations. ??? Attributes are 1537169689Skan not allowed to start declaration specifiers here because of a 1538169689Skan syntax conflict between a function declaration with attribute 1539169689Skan suffix and a function definition with an attribute prefix on 1540169689Skan first old-style parameter declaration. Following the old 1541169689Skan parser, they are not accepted on subsequent old-style 1542169689Skan parameter declarations either. However, there is no 1543169689Skan ambiguity after the first declaration, nor indeed on the 1544169689Skan first as long as we don't allow postfix attributes after a 1545169689Skan declarator with a nonempty identifier list in a definition; 1546169689Skan and postfix attributes have never been accepted here in 1547169689Skan function definitions either. */ 1548169689Skan while (c_parser_next_token_is_not (parser, CPP_EOF) 1549169689Skan && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) 1550260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 1551260311Spfg c_parser_declaration_or_fndef (parser, false, false, true, false, NULL); 1552169689Skan DECL_SOURCE_LOCATION (current_function_decl) 1553169689Skan = c_parser_peek_token (parser)->location; 1554169689Skan store_parm_decls (); 1555169689Skan fnbody = c_parser_compound_statement (parser); 1556169689Skan if (nested) 1557169689Skan { 1558169689Skan tree decl = current_function_decl; 1559169689Skan add_stmt (fnbody); 1560169689Skan finish_function (); 1561169689Skan pop_function_context (); 1562169689Skan add_stmt (build_stmt (DECL_EXPR, decl)); 1563169689Skan } 1564169689Skan else 1565169689Skan { 1566169689Skan add_stmt (fnbody); 1567169689Skan finish_function (); 1568169689Skan } 1569169689Skan break; 1570169689Skan } 1571169689Skan} 1572169689Skan 1573260311Spfgstatic tree 1574260311Spfgfinish_parse_foreach_header (c_parser *parser, tree foreach_elem_selector) 1575260311Spfg{ 1576260311Spfg tree res; 1577260311Spfg int save_flag_isoc99 = flag_isoc99; 1578260311Spfg gcc_assert (foreach_elem_selector); 1579260311Spfg /* Consume 'in' keyword */ 1580260311Spfg c_parser_consume_token (parser); 1581260311Spfg res = build_tree_list (foreach_elem_selector, c_parser_initializer (parser).value); 1582260311Spfg finish_init (); 1583260311Spfg flag_isoc99 = 1; 1584260311Spfg check_for_loop_decls (); 1585260311Spfg flag_isoc99 = save_flag_isoc99; 1586260311Spfg return res; 1587260311Spfg} 1588260311Spfg/* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */ 1589260311Spfg 1590169689Skan/* Parse an asm-definition (asm() outside a function body). This is a 1591169689Skan GNU extension. 1592169689Skan 1593169689Skan asm-definition: 1594169689Skan simple-asm-expr ; 1595169689Skan*/ 1596169689Skan 1597169689Skanstatic void 1598169689Skanc_parser_asm_definition (c_parser *parser) 1599169689Skan{ 1600169689Skan tree asm_str = c_parser_simple_asm_expr (parser); 1601169689Skan if (asm_str) 1602169689Skan cgraph_add_asm_node (asm_str); 1603169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 1604169689Skan} 1605169689Skan 1606169689Skan/* Parse some declaration specifiers (possibly none) (C90 6.5, C99 1607169689Skan 6.7), adding them to SPECS (which may already include some). 1608169689Skan Storage class specifiers are accepted iff SCSPEC_OK; type 1609169689Skan specifiers are accepted iff TYPESPEC_OK; attributes are accepted at 1610169689Skan the start iff START_ATTR_OK. 1611169689Skan 1612169689Skan declaration-specifiers: 1613169689Skan storage-class-specifier declaration-specifiers[opt] 1614169689Skan type-specifier declaration-specifiers[opt] 1615169689Skan type-qualifier declaration-specifiers[opt] 1616169689Skan function-specifier declaration-specifiers[opt] 1617169689Skan 1618169689Skan Function specifiers (inline) are from C99, and are currently 1619169689Skan handled as storage class specifiers, as is __thread. 1620169689Skan 1621169689Skan C90 6.5.1, C99 6.7.1: 1622169689Skan storage-class-specifier: 1623169689Skan typedef 1624169689Skan extern 1625169689Skan static 1626169689Skan auto 1627169689Skan register 1628169689Skan 1629169689Skan C99 6.7.4: 1630169689Skan function-specifier: 1631169689Skan inline 1632169689Skan 1633169689Skan C90 6.5.2, C99 6.7.2: 1634169689Skan type-specifier: 1635169689Skan void 1636169689Skan char 1637169689Skan short 1638169689Skan int 1639169689Skan long 1640169689Skan float 1641169689Skan double 1642169689Skan signed 1643169689Skan unsigned 1644169689Skan _Bool 1645169689Skan _Complex 1646169689Skan [_Imaginary removed in C99 TC2] 1647169689Skan struct-or-union-specifier 1648169689Skan enum-specifier 1649169689Skan typedef-name 1650169689Skan 1651169689Skan (_Bool and _Complex are new in C99.) 1652169689Skan 1653169689Skan C90 6.5.3, C99 6.7.3: 1654169689Skan 1655169689Skan type-qualifier: 1656169689Skan const 1657169689Skan restrict 1658169689Skan volatile 1659169689Skan 1660169689Skan (restrict is new in C99.) 1661169689Skan 1662169689Skan GNU extensions: 1663169689Skan 1664169689Skan declaration-specifiers: 1665169689Skan attributes declaration-specifiers[opt] 1666169689Skan 1667169689Skan storage-class-specifier: 1668169689Skan __thread 1669169689Skan 1670169689Skan type-specifier: 1671169689Skan typeof-specifier 1672169689Skan _Decimal32 1673169689Skan _Decimal64 1674169689Skan _Decimal128 1675169689Skan 1676169689Skan Objective-C: 1677169689Skan 1678169689Skan type-specifier: 1679169689Skan class-name objc-protocol-refs[opt] 1680169689Skan typedef-name objc-protocol-refs 1681169689Skan objc-protocol-refs 1682169689Skan*/ 1683169689Skan 1684169689Skanstatic void 1685169689Skanc_parser_declspecs (c_parser *parser, struct c_declspecs *specs, 1686169689Skan bool scspec_ok, bool typespec_ok, bool start_attr_ok) 1687169689Skan{ 1688169689Skan bool attrs_ok = start_attr_ok; 1689169689Skan bool seen_type = specs->type_seen_p; 1690169689Skan while (c_parser_next_token_is (parser, CPP_NAME) 1691169689Skan || c_parser_next_token_is (parser, CPP_KEYWORD) 1692169689Skan || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS))) 1693169689Skan { 1694169689Skan struct c_typespec t; 1695169689Skan tree attrs; 1696169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 1697169689Skan { 1698169689Skan tree value = c_parser_peek_token (parser)->value; 1699169689Skan c_id_kind kind = c_parser_peek_token (parser)->id_kind; 1700169689Skan /* This finishes the specifiers unless a type name is OK, it 1701169689Skan is declared as a type name and a type name hasn't yet 1702169689Skan been seen. */ 1703169689Skan if (!typespec_ok || seen_type 1704169689Skan || (kind != C_ID_TYPENAME && kind != C_ID_CLASSNAME)) 1705169689Skan break; 1706169689Skan c_parser_consume_token (parser); 1707169689Skan seen_type = true; 1708169689Skan attrs_ok = true; 1709169689Skan if (kind == C_ID_TYPENAME 1710169689Skan && (!c_dialect_objc () 1711169689Skan || c_parser_next_token_is_not (parser, CPP_LESS))) 1712169689Skan { 1713169689Skan t.kind = ctsk_typedef; 1714169689Skan /* For a typedef name, record the meaning, not the name. 1715169689Skan In case of 'foo foo, bar;'. */ 1716169689Skan t.spec = lookup_name (value); 1717169689Skan } 1718169689Skan else 1719169689Skan { 1720169689Skan tree proto = NULL_TREE; 1721169689Skan gcc_assert (c_dialect_objc ()); 1722169689Skan t.kind = ctsk_objc; 1723169689Skan if (c_parser_next_token_is (parser, CPP_LESS)) 1724169689Skan proto = c_parser_objc_protocol_refs (parser); 1725169689Skan t.spec = objc_get_protocol_qualified_type (value, proto); 1726169689Skan } 1727169689Skan declspecs_add_type (specs, t); 1728169689Skan continue; 1729169689Skan } 1730169689Skan if (c_parser_next_token_is (parser, CPP_LESS)) 1731169689Skan { 1732169689Skan /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" - 1733169689Skan nisse@lysator.liu.se. */ 1734169689Skan tree proto; 1735169689Skan gcc_assert (c_dialect_objc ()); 1736169689Skan if (!typespec_ok || seen_type) 1737169689Skan break; 1738169689Skan proto = c_parser_objc_protocol_refs (parser); 1739169689Skan t.kind = ctsk_objc; 1740169689Skan t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto); 1741169689Skan declspecs_add_type (specs, t); 1742169689Skan continue; 1743169689Skan } 1744169689Skan gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD)); 1745169689Skan switch (c_parser_peek_token (parser)->keyword) 1746169689Skan { 1747169689Skan case RID_STATIC: 1748169689Skan case RID_EXTERN: 1749169689Skan case RID_REGISTER: 1750169689Skan case RID_TYPEDEF: 1751169689Skan case RID_INLINE: 1752169689Skan case RID_AUTO: 1753169689Skan case RID_THREAD: 1754169689Skan if (!scspec_ok) 1755169689Skan goto out; 1756169689Skan attrs_ok = true; 1757169689Skan /* TODO: Distinguish between function specifiers (inline) 1758169689Skan and storage class specifiers, either here or in 1759169689Skan declspecs_add_scspec. */ 1760169689Skan declspecs_add_scspec (specs, c_parser_peek_token (parser)->value); 1761169689Skan c_parser_consume_token (parser); 1762169689Skan break; 1763169689Skan case RID_UNSIGNED: 1764169689Skan case RID_LONG: 1765169689Skan case RID_SHORT: 1766169689Skan case RID_SIGNED: 1767169689Skan case RID_COMPLEX: 1768169689Skan case RID_INT: 1769169689Skan case RID_CHAR: 1770169689Skan case RID_FLOAT: 1771169689Skan case RID_DOUBLE: 1772169689Skan case RID_VOID: 1773169689Skan case RID_DFLOAT32: 1774169689Skan case RID_DFLOAT64: 1775169689Skan case RID_DFLOAT128: 1776169689Skan case RID_BOOL: 1777169689Skan if (!typespec_ok) 1778169689Skan goto out; 1779169689Skan attrs_ok = true; 1780169689Skan seen_type = true; 1781169689Skan OBJC_NEED_RAW_IDENTIFIER (1); 1782169689Skan t.kind = ctsk_resword; 1783169689Skan t.spec = c_parser_peek_token (parser)->value; 1784169689Skan declspecs_add_type (specs, t); 1785169689Skan c_parser_consume_token (parser); 1786169689Skan break; 1787169689Skan case RID_ENUM: 1788169689Skan if (!typespec_ok) 1789169689Skan goto out; 1790169689Skan attrs_ok = true; 1791169689Skan seen_type = true; 1792169689Skan t = c_parser_enum_specifier (parser); 1793169689Skan declspecs_add_type (specs, t); 1794169689Skan break; 1795169689Skan case RID_STRUCT: 1796169689Skan case RID_UNION: 1797169689Skan if (!typespec_ok) 1798169689Skan goto out; 1799169689Skan attrs_ok = true; 1800169689Skan seen_type = true; 1801169689Skan t = c_parser_struct_or_union_specifier (parser); 1802169689Skan declspecs_add_type (specs, t); 1803169689Skan break; 1804169689Skan case RID_TYPEOF: 1805169689Skan /* ??? The old parser rejected typeof after other type 1806169689Skan specifiers, but is a syntax error the best way of 1807169689Skan handling this? */ 1808169689Skan if (!typespec_ok || seen_type) 1809169689Skan goto out; 1810169689Skan attrs_ok = true; 1811169689Skan seen_type = true; 1812169689Skan t = c_parser_typeof_specifier (parser); 1813169689Skan declspecs_add_type (specs, t); 1814169689Skan break; 1815169689Skan case RID_CONST: 1816169689Skan case RID_VOLATILE: 1817169689Skan case RID_RESTRICT: 1818169689Skan attrs_ok = true; 1819169689Skan declspecs_add_qual (specs, c_parser_peek_token (parser)->value); 1820169689Skan c_parser_consume_token (parser); 1821169689Skan break; 1822169689Skan case RID_ATTRIBUTE: 1823169689Skan if (!attrs_ok) 1824169689Skan goto out; 1825169689Skan attrs = c_parser_attributes (parser); 1826169689Skan declspecs_add_attrs (specs, attrs); 1827169689Skan break; 1828169689Skan default: 1829169689Skan goto out; 1830169689Skan } 1831169689Skan } 1832169689Skan out: ; 1833169689Skan} 1834169689Skan 1835169689Skan/* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2). 1836169689Skan 1837169689Skan enum-specifier: 1838169689Skan enum attributes[opt] identifier[opt] { enumerator-list } attributes[opt] 1839169689Skan enum attributes[opt] identifier[opt] { enumerator-list , } attributes[opt] 1840169689Skan enum attributes[opt] identifier 1841169689Skan 1842169689Skan The form with trailing comma is new in C99. The forms with 1843169689Skan attributes are GNU extensions. In GNU C, we accept any expression 1844169689Skan without commas in the syntax (assignment expressions, not just 1845169689Skan conditional expressions); assignment expressions will be diagnosed 1846169689Skan as non-constant. 1847169689Skan 1848169689Skan enumerator-list: 1849169689Skan enumerator 1850169689Skan enumerator-list , enumerator 1851169689Skan 1852169689Skan enumerator: 1853169689Skan enumeration-constant 1854169689Skan enumeration-constant = constant-expression 1855169689Skan*/ 1856169689Skan 1857169689Skanstatic struct c_typespec 1858169689Skanc_parser_enum_specifier (c_parser *parser) 1859169689Skan{ 1860169689Skan struct c_typespec ret; 1861169689Skan tree attrs; 1862169689Skan tree ident = NULL_TREE; 1863169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM)); 1864169689Skan c_parser_consume_token (parser); 1865169689Skan attrs = c_parser_attributes (parser); 1866169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 1867169689Skan { 1868169689Skan ident = c_parser_peek_token (parser)->value; 1869169689Skan c_parser_consume_token (parser); 1870169689Skan } 1871169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 1872169689Skan { 1873169689Skan /* Parse an enum definition. */ 1874169689Skan tree type = start_enum (ident); 1875169689Skan tree postfix_attrs; 1876169689Skan /* We chain the enumerators in reverse order, then put them in 1877169689Skan forward order at the end. */ 1878169689Skan tree values = NULL_TREE; 1879169689Skan c_parser_consume_token (parser); 1880169689Skan while (true) 1881169689Skan { 1882169689Skan tree enum_id; 1883169689Skan tree enum_value; 1884169689Skan tree enum_decl; 1885169689Skan bool seen_comma; 1886169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 1887169689Skan { 1888169689Skan c_parser_error (parser, "expected identifier"); 1889169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 1890169689Skan values = error_mark_node; 1891169689Skan break; 1892169689Skan } 1893169689Skan enum_id = c_parser_peek_token (parser)->value; 1894169689Skan c_parser_consume_token (parser); 1895169689Skan if (c_parser_next_token_is (parser, CPP_EQ)) 1896169689Skan { 1897169689Skan c_parser_consume_token (parser); 1898169689Skan enum_value = c_parser_expr_no_commas (parser, NULL).value; 1899169689Skan } 1900169689Skan else 1901169689Skan enum_value = NULL_TREE; 1902169689Skan enum_decl = build_enumerator (enum_id, enum_value); 1903169689Skan TREE_CHAIN (enum_decl) = values; 1904169689Skan values = enum_decl; 1905169689Skan seen_comma = false; 1906169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 1907169689Skan { 1908169689Skan seen_comma = true; 1909169689Skan c_parser_consume_token (parser); 1910169689Skan } 1911169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 1912169689Skan { 1913169689Skan if (seen_comma && pedantic && !flag_isoc99) 1914169689Skan pedwarn ("comma at end of enumerator list"); 1915169689Skan c_parser_consume_token (parser); 1916169689Skan break; 1917169689Skan } 1918169689Skan if (!seen_comma) 1919169689Skan { 1920169689Skan c_parser_error (parser, "expected %<,%> or %<}%>"); 1921169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 1922169689Skan values = error_mark_node; 1923169689Skan break; 1924169689Skan } 1925169689Skan } 1926169689Skan postfix_attrs = c_parser_attributes (parser); 1927169689Skan ret.spec = finish_enum (type, nreverse (values), 1928169689Skan chainon (attrs, postfix_attrs)); 1929169689Skan ret.kind = ctsk_tagdef; 1930169689Skan return ret; 1931169689Skan } 1932169689Skan else if (!ident) 1933169689Skan { 1934169689Skan c_parser_error (parser, "expected %<{%>"); 1935169689Skan ret.spec = error_mark_node; 1936169689Skan ret.kind = ctsk_tagref; 1937169689Skan return ret; 1938169689Skan } 1939169689Skan ret = parser_xref_tag (ENUMERAL_TYPE, ident); 1940169689Skan /* In ISO C, enumerated types can be referred to only if already 1941169689Skan defined. */ 1942169689Skan if (pedantic && !COMPLETE_TYPE_P (ret.spec)) 1943169689Skan pedwarn ("ISO C forbids forward references to %<enum%> types"); 1944169689Skan return ret; 1945169689Skan} 1946169689Skan 1947169689Skan/* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1). 1948169689Skan 1949169689Skan struct-or-union-specifier: 1950169689Skan struct-or-union attributes[opt] identifier[opt] 1951169689Skan { struct-contents } attributes[opt] 1952169689Skan struct-or-union attributes[opt] identifier 1953169689Skan 1954169689Skan struct-contents: 1955169689Skan struct-declaration-list 1956169689Skan 1957169689Skan struct-declaration-list: 1958169689Skan struct-declaration ; 1959169689Skan struct-declaration-list struct-declaration ; 1960169689Skan 1961169689Skan GNU extensions: 1962169689Skan 1963169689Skan struct-contents: 1964169689Skan empty 1965169689Skan struct-declaration 1966169689Skan struct-declaration-list struct-declaration 1967169689Skan 1968169689Skan struct-declaration-list: 1969169689Skan struct-declaration-list ; 1970169689Skan ; 1971169689Skan 1972169689Skan (Note that in the syntax here, unlike that in ISO C, the semicolons 1973169689Skan are included here rather than in struct-declaration, in order to 1974169689Skan describe the syntax with extra semicolons and missing semicolon at 1975169689Skan end.) 1976169689Skan 1977169689Skan Objective-C: 1978169689Skan 1979169689Skan struct-declaration-list: 1980169689Skan @defs ( class-name ) 1981169689Skan 1982169689Skan (Note this does not include a trailing semicolon, but can be 1983169689Skan followed by further declarations, and gets a pedwarn-if-pedantic 1984169689Skan when followed by a semicolon.) */ 1985169689Skan 1986169689Skanstatic struct c_typespec 1987169689Skanc_parser_struct_or_union_specifier (c_parser *parser) 1988169689Skan{ 1989169689Skan struct c_typespec ret; 1990169689Skan tree attrs; 1991169689Skan tree ident = NULL_TREE; 1992169689Skan enum tree_code code; 1993169689Skan switch (c_parser_peek_token (parser)->keyword) 1994169689Skan { 1995169689Skan case RID_STRUCT: 1996169689Skan code = RECORD_TYPE; 1997169689Skan break; 1998169689Skan case RID_UNION: 1999169689Skan code = UNION_TYPE; 2000169689Skan break; 2001169689Skan default: 2002169689Skan gcc_unreachable (); 2003169689Skan } 2004169689Skan c_parser_consume_token (parser); 2005169689Skan attrs = c_parser_attributes (parser); 2006169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 2007169689Skan { 2008169689Skan ident = c_parser_peek_token (parser)->value; 2009169689Skan c_parser_consume_token (parser); 2010169689Skan } 2011169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 2012169689Skan { 2013169689Skan /* Parse a struct or union definition. Start the scope of the 2014169689Skan tag before parsing components. */ 2015169689Skan tree type = start_struct (code, ident); 2016169689Skan tree postfix_attrs; 2017169689Skan /* We chain the components in reverse order, then put them in 2018169689Skan forward order at the end. Each struct-declaration may 2019169689Skan declare multiple components (comma-separated), so we must use 2020169689Skan chainon to join them, although when parsing each 2021169689Skan struct-declaration we can use TREE_CHAIN directly. 2022169689Skan 2023169689Skan The theory behind all this is that there will be more 2024169689Skan semicolon separated fields than comma separated fields, and 2025169689Skan so we'll be minimizing the number of node traversals required 2026169689Skan by chainon. */ 2027169689Skan tree contents = NULL_TREE; 2028169689Skan c_parser_consume_token (parser); 2029169689Skan /* Handle the Objective-C @defs construct, 2030169689Skan e.g. foo(sizeof(struct{ @defs(ClassName) }));. */ 2031169689Skan if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS)) 2032169689Skan { 2033169689Skan tree name; 2034169689Skan gcc_assert (c_dialect_objc ()); 2035169689Skan c_parser_consume_token (parser); 2036169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 2037169689Skan goto end_at_defs; 2038169689Skan if (c_parser_next_token_is (parser, CPP_NAME) 2039169689Skan && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME) 2040169689Skan { 2041169689Skan name = c_parser_peek_token (parser)->value; 2042169689Skan c_parser_consume_token (parser); 2043169689Skan } 2044169689Skan else 2045169689Skan { 2046169689Skan c_parser_error (parser, "expected class name"); 2047169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 2048169689Skan goto end_at_defs; 2049169689Skan } 2050169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 2051169689Skan "expected %<)%>"); 2052169689Skan contents = nreverse (objc_get_class_ivars (name)); 2053169689Skan } 2054169689Skan end_at_defs: 2055169689Skan /* Parse the struct-declarations and semicolons. Problems with 2056169689Skan semicolons are diagnosed here; empty structures are diagnosed 2057169689Skan elsewhere. */ 2058169689Skan while (true) 2059169689Skan { 2060169689Skan tree decls; 2061169689Skan /* Parse any stray semicolon. */ 2062169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 2063169689Skan { 2064169689Skan if (pedantic) 2065169689Skan pedwarn ("extra semicolon in struct or union specified"); 2066169689Skan c_parser_consume_token (parser); 2067169689Skan continue; 2068169689Skan } 2069169689Skan /* Stop if at the end of the struct or union contents. */ 2070169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 2071169689Skan { 2072169689Skan c_parser_consume_token (parser); 2073169689Skan break; 2074169689Skan } 2075169689Skan /* Accept #pragmas at struct scope. */ 2076169689Skan if (c_parser_next_token_is (parser, CPP_PRAGMA)) 2077169689Skan { 2078169689Skan c_parser_pragma (parser, pragma_external); 2079169689Skan continue; 2080169689Skan } 2081169689Skan /* Parse some comma-separated declarations, but not the 2082169689Skan trailing semicolon if any. */ 2083169689Skan decls = c_parser_struct_declaration (parser); 2084169689Skan contents = chainon (decls, contents); 2085169689Skan /* If no semicolon follows, either we have a parse error or 2086169689Skan are at the end of the struct or union and should 2087169689Skan pedwarn. */ 2088169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 2089169689Skan c_parser_consume_token (parser); 2090169689Skan else 2091169689Skan { 2092169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 2093169689Skan pedwarn ("no semicolon at end of struct or union"); 2094169689Skan else 2095169689Skan { 2096169689Skan c_parser_error (parser, "expected %<;%>"); 2097169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 2098169689Skan break; 2099169689Skan } 2100169689Skan } 2101169689Skan } 2102169689Skan postfix_attrs = c_parser_attributes (parser); 2103169689Skan ret.spec = finish_struct (type, nreverse (contents), 2104169689Skan chainon (attrs, postfix_attrs)); 2105169689Skan ret.kind = ctsk_tagdef; 2106169689Skan return ret; 2107169689Skan } 2108169689Skan else if (!ident) 2109169689Skan { 2110169689Skan c_parser_error (parser, "expected %<{%>"); 2111169689Skan ret.spec = error_mark_node; 2112169689Skan ret.kind = ctsk_tagref; 2113169689Skan return ret; 2114169689Skan } 2115169689Skan ret = parser_xref_tag (code, ident); 2116169689Skan return ret; 2117169689Skan} 2118169689Skan 2119169689Skan/* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1), *without* 2120169689Skan the trailing semicolon. 2121169689Skan 2122169689Skan struct-declaration: 2123169689Skan specifier-qualifier-list struct-declarator-list 2124169689Skan 2125169689Skan specifier-qualifier-list: 2126169689Skan type-specifier specifier-qualifier-list[opt] 2127169689Skan type-qualifier specifier-qualifier-list[opt] 2128169689Skan attributes specifier-qualifier-list[opt] 2129169689Skan 2130169689Skan struct-declarator-list: 2131169689Skan struct-declarator 2132169689Skan struct-declarator-list , attributes[opt] struct-declarator 2133169689Skan 2134169689Skan struct-declarator: 2135169689Skan declarator attributes[opt] 2136169689Skan declarator[opt] : constant-expression attributes[opt] 2137169689Skan 2138169689Skan GNU extensions: 2139169689Skan 2140169689Skan struct-declaration: 2141169689Skan __extension__ struct-declaration 2142169689Skan specifier-qualifier-list 2143169689Skan 2144169689Skan Unlike the ISO C syntax, semicolons are handled elsewhere. The use 2145169689Skan of attributes where shown is a GNU extension. In GNU C, we accept 2146169689Skan any expression without commas in the syntax (assignment 2147169689Skan expressions, not just conditional expressions); assignment 2148169689Skan expressions will be diagnosed as non-constant. */ 2149169689Skan 2150169689Skanstatic tree 2151169689Skanc_parser_struct_declaration (c_parser *parser) 2152169689Skan{ 2153169689Skan struct c_declspecs *specs; 2154169689Skan tree prefix_attrs; 2155169689Skan tree all_prefix_attrs; 2156169689Skan tree decls; 2157169689Skan if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 2158169689Skan { 2159169689Skan int ext; 2160169689Skan tree decl; 2161169689Skan ext = disable_extension_diagnostics (); 2162169689Skan c_parser_consume_token (parser); 2163169689Skan decl = c_parser_struct_declaration (parser); 2164169689Skan restore_extension_diagnostics (ext); 2165169689Skan return decl; 2166169689Skan } 2167169689Skan specs = build_null_declspecs (); 2168169689Skan c_parser_declspecs (parser, specs, false, true, true); 2169169689Skan if (parser->error) 2170169689Skan return NULL_TREE; 2171169689Skan if (!specs->declspecs_seen_p) 2172169689Skan { 2173169689Skan c_parser_error (parser, "expected specifier-qualifier-list"); 2174169689Skan return NULL_TREE; 2175169689Skan } 2176169689Skan finish_declspecs (specs); 2177169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 2178169689Skan { 2179169689Skan tree ret; 2180169689Skan if (!specs->type_seen_p) 2181169689Skan { 2182169689Skan if (pedantic) 2183169689Skan pedwarn ("ISO C forbids member declarations with no members"); 2184169689Skan shadow_tag_warned (specs, pedantic); 2185169689Skan ret = NULL_TREE; 2186169689Skan } 2187169689Skan else 2188169689Skan { 2189169689Skan /* Support for unnamed structs or unions as members of 2190169689Skan structs or unions (which is [a] useful and [b] supports 2191169689Skan MS P-SDK). */ 2192169689Skan ret = grokfield (build_id_declarator (NULL_TREE), specs, NULL_TREE); 2193169689Skan } 2194169689Skan return ret; 2195169689Skan } 2196169689Skan pending_xref_error (); 2197169689Skan prefix_attrs = specs->attrs; 2198169689Skan all_prefix_attrs = prefix_attrs; 2199169689Skan specs->attrs = NULL_TREE; 2200169689Skan decls = NULL_TREE; 2201169689Skan while (true) 2202169689Skan { 2203169689Skan /* Declaring one or more declarators or un-named bit-fields. */ 2204169689Skan struct c_declarator *declarator; 2205169689Skan bool dummy = false; 2206169689Skan if (c_parser_next_token_is (parser, CPP_COLON)) 2207169689Skan declarator = build_id_declarator (NULL_TREE); 2208169689Skan else 2209169689Skan declarator = c_parser_declarator (parser, specs->type_seen_p, 2210169689Skan C_DTR_NORMAL, &dummy); 2211169689Skan if (declarator == NULL) 2212169689Skan { 2213169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 2214169689Skan break; 2215169689Skan } 2216169689Skan if (c_parser_next_token_is (parser, CPP_COLON) 2217169689Skan || c_parser_next_token_is (parser, CPP_COMMA) 2218169689Skan || c_parser_next_token_is (parser, CPP_SEMICOLON) 2219169689Skan || c_parser_next_token_is (parser, CPP_CLOSE_BRACE) 2220169689Skan || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 2221169689Skan { 2222169689Skan tree postfix_attrs = NULL_TREE; 2223169689Skan tree width = NULL_TREE; 2224169689Skan tree d; 2225169689Skan if (c_parser_next_token_is (parser, CPP_COLON)) 2226169689Skan { 2227169689Skan c_parser_consume_token (parser); 2228169689Skan width = c_parser_expr_no_commas (parser, NULL).value; 2229169689Skan } 2230169689Skan if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 2231169689Skan postfix_attrs = c_parser_attributes (parser); 2232169689Skan d = grokfield (declarator, specs, width); 2233169689Skan decl_attributes (&d, chainon (postfix_attrs, 2234169689Skan all_prefix_attrs), 0); 2235169689Skan TREE_CHAIN (d) = decls; 2236169689Skan decls = d; 2237169689Skan if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 2238169689Skan all_prefix_attrs = chainon (c_parser_attributes (parser), 2239169689Skan prefix_attrs); 2240169689Skan else 2241169689Skan all_prefix_attrs = prefix_attrs; 2242169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 2243169689Skan c_parser_consume_token (parser); 2244169689Skan else if (c_parser_next_token_is (parser, CPP_SEMICOLON) 2245169689Skan || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 2246169689Skan { 2247169689Skan /* Semicolon consumed in caller. */ 2248169689Skan break; 2249169689Skan } 2250169689Skan else 2251169689Skan { 2252169689Skan c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>"); 2253169689Skan break; 2254169689Skan } 2255169689Skan } 2256169689Skan else 2257169689Skan { 2258169689Skan c_parser_error (parser, 2259169689Skan "expected %<:%>, %<,%>, %<;%>, %<}%> or " 2260169689Skan "%<__attribute__%>"); 2261169689Skan break; 2262169689Skan } 2263169689Skan } 2264169689Skan return decls; 2265169689Skan} 2266169689Skan 2267169689Skan/* Parse a typeof specifier (a GNU extension). 2268169689Skan 2269169689Skan typeof-specifier: 2270169689Skan typeof ( expression ) 2271169689Skan typeof ( type-name ) 2272169689Skan*/ 2273169689Skan 2274169689Skanstatic struct c_typespec 2275169689Skanc_parser_typeof_specifier (c_parser *parser) 2276169689Skan{ 2277169689Skan struct c_typespec ret; 2278169689Skan ret.kind = ctsk_typeof; 2279169689Skan ret.spec = error_mark_node; 2280169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF)); 2281169689Skan c_parser_consume_token (parser); 2282169689Skan skip_evaluation++; 2283169689Skan in_typeof++; 2284169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 2285169689Skan { 2286169689Skan skip_evaluation--; 2287169689Skan in_typeof--; 2288169689Skan return ret; 2289169689Skan } 2290169689Skan if (c_parser_next_token_starts_typename (parser)) 2291169689Skan { 2292169689Skan struct c_type_name *type = c_parser_type_name (parser); 2293169689Skan skip_evaluation--; 2294169689Skan in_typeof--; 2295169689Skan if (type != NULL) 2296169689Skan { 2297169689Skan ret.spec = groktypename (type); 2298169689Skan pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE)); 2299169689Skan } 2300169689Skan } 2301169689Skan else 2302169689Skan { 2303169689Skan bool was_vm; 2304169689Skan struct c_expr expr = c_parser_expression (parser); 2305169689Skan skip_evaluation--; 2306169689Skan in_typeof--; 2307169689Skan if (TREE_CODE (expr.value) == COMPONENT_REF 2308169689Skan && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) 2309169689Skan error ("%<typeof%> applied to a bit-field"); 2310169689Skan ret.spec = TREE_TYPE (expr.value); 2311169689Skan was_vm = variably_modified_type_p (ret.spec, NULL_TREE); 2312169689Skan /* This should be returned with the type so that when the type 2313169689Skan is evaluated, this can be evaluated. For now, we avoid 2314169689Skan evaluation when the context might. */ 2315169689Skan if (!skip_evaluation && was_vm) 2316169689Skan { 2317169689Skan tree e = expr.value; 2318169689Skan 2319169689Skan /* If the expression is not of a type to which we cannot assign a line 2320169689Skan number, wrap the thing in a no-op NOP_EXPR. */ 2321169689Skan if (DECL_P (e) || CONSTANT_CLASS_P (e)) 2322169689Skan e = build1 (NOP_EXPR, void_type_node, e); 2323169689Skan 2324169689Skan if (EXPR_P (e)) 2325169689Skan SET_EXPR_LOCATION (e, input_location); 2326169689Skan 2327169689Skan add_stmt (e); 2328169689Skan } 2329169689Skan pop_maybe_used (was_vm); 2330169689Skan } 2331169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 2332169689Skan return ret; 2333169689Skan} 2334169689Skan 2335169689Skan/* Parse a declarator, possibly an abstract declarator (C90 6.5.4, 2336169689Skan 6.5.5, C99 6.7.5, 6.7.6). If TYPE_SEEN_P then a typedef name may 2337169689Skan be redeclared; otherwise it may not. KIND indicates which kind of 2338169689Skan declarator is wanted. Returns a valid declarator except in the 2339169689Skan case of a syntax error in which case NULL is returned. *SEEN_ID is 2340169689Skan set to true if an identifier being declared is seen; this is used 2341169689Skan to diagnose bad forms of abstract array declarators and to 2342169689Skan determine whether an identifier list is syntactically permitted. 2343169689Skan 2344169689Skan declarator: 2345169689Skan pointer[opt] direct-declarator 2346169689Skan 2347169689Skan direct-declarator: 2348169689Skan identifier 2349169689Skan ( attributes[opt] declarator ) 2350169689Skan direct-declarator array-declarator 2351169689Skan direct-declarator ( parameter-type-list ) 2352169689Skan direct-declarator ( identifier-list[opt] ) 2353169689Skan 2354169689Skan pointer: 2355169689Skan * type-qualifier-list[opt] 2356169689Skan * type-qualifier-list[opt] pointer 2357169689Skan 2358169689Skan type-qualifier-list: 2359169689Skan type-qualifier 2360169689Skan attributes 2361169689Skan type-qualifier-list type-qualifier 2362169689Skan type-qualifier-list attributes 2363169689Skan 2364169689Skan parameter-type-list: 2365169689Skan parameter-list 2366169689Skan parameter-list , ... 2367169689Skan 2368169689Skan parameter-list: 2369169689Skan parameter-declaration 2370169689Skan parameter-list , parameter-declaration 2371169689Skan 2372169689Skan parameter-declaration: 2373169689Skan declaration-specifiers declarator attributes[opt] 2374169689Skan declaration-specifiers abstract-declarator[opt] attributes[opt] 2375169689Skan 2376169689Skan identifier-list: 2377169689Skan identifier 2378169689Skan identifier-list , identifier 2379169689Skan 2380169689Skan abstract-declarator: 2381169689Skan pointer 2382169689Skan pointer[opt] direct-abstract-declarator 2383169689Skan 2384169689Skan direct-abstract-declarator: 2385169689Skan ( attributes[opt] abstract-declarator ) 2386169689Skan direct-abstract-declarator[opt] array-declarator 2387169689Skan direct-abstract-declarator[opt] ( parameter-type-list[opt] ) 2388169689Skan 2389169689Skan GNU extensions: 2390169689Skan 2391169689Skan direct-declarator: 2392169689Skan direct-declarator ( parameter-forward-declarations 2393169689Skan parameter-type-list[opt] ) 2394169689Skan 2395169689Skan direct-abstract-declarator: 2396169689Skan direct-abstract-declarator[opt] ( parameter-forward-declarations 2397169689Skan parameter-type-list[opt] ) 2398169689Skan 2399169689Skan parameter-forward-declarations: 2400169689Skan parameter-list ; 2401169689Skan parameter-forward-declarations parameter-list ; 2402169689Skan 2403260311Spfg APPLE LOCAL begin blocks 6339747 2404260311Spfg block-declarator: 2405260311Spfg pointer 2406260311Spfg pointer[opt] direct-block-declarator 2407260311Spfg 2408260311Spfg direct-block-declarator: 2409260311Spfg ( attributes[opt] block-declarator ) 2410260311Spfg direct-block-declarator[opt] array-declarator 2411260311Spfg direct-block-declarator[opt] 2412260311Spfg ( parameter-type-list[opt] ) [opt] 2413260311Spfg APPLE LOCAL end blocks 6339747 2414260311Spfg 2415169689Skan The uses of attributes shown above are GNU extensions. 2416169689Skan 2417169689Skan Some forms of array declarator are not included in C99 in the 2418169689Skan syntax for abstract declarators; these are disallowed elsewhere. 2419169689Skan This may be a defect (DR#289). 2420169689Skan 2421169689Skan This function also accepts an omitted abstract declarator as being 2422169689Skan an abstract declarator, although not part of the formal syntax. */ 2423169689Skan 2424169689Skanstatic struct c_declarator * 2425169689Skanc_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, 2426169689Skan bool *seen_id) 2427169689Skan{ 2428169689Skan /* Parse any initial pointer part. */ 2429169689Skan if (c_parser_next_token_is (parser, CPP_MULT)) 2430169689Skan { 2431169689Skan struct c_declspecs *quals_attrs = build_null_declspecs (); 2432169689Skan struct c_declarator *inner; 2433169689Skan c_parser_consume_token (parser); 2434169689Skan c_parser_declspecs (parser, quals_attrs, false, false, true); 2435169689Skan inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); 2436169689Skan if (inner == NULL) 2437169689Skan return NULL; 2438169689Skan else 2439169689Skan return make_pointer_declarator (quals_attrs, inner); 2440169689Skan } 2441260311Spfg /* APPLE LOCAL begin radar 5732232 - blocks (C++ cc) */ 2442260311Spfg else if (flag_blocks && c_parser_next_token_is (parser, CPP_XOR)) { 2443260311Spfg struct c_declspecs *quals_attrs = build_null_declspecs (); 2444260311Spfg struct c_declarator *inner; 2445260311Spfg c_parser_consume_token (parser); 2446260311Spfg c_parser_declspecs (parser, quals_attrs, false, false, true); 2447260311Spfg inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); 2448260311Spfg if (inner == NULL) 2449260311Spfg return NULL; 2450260311Spfg else 2451260311Spfg /* APPLE LOCAL radar 5814025 (C++ cc) */ 2452260311Spfg return make_block_pointer_declarator (quals_attrs, inner); 2453260311Spfg } 2454260311Spfg /* APPLE LOCAL end radar 5732232 - blocks (C++ cc) */ 2455169689Skan /* Now we have a direct declarator, direct abstract declarator or 2456169689Skan nothing (which counts as a direct abstract declarator here). */ 2457169689Skan return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id); 2458169689Skan} 2459169689Skan 2460169689Skan/* Parse a direct declarator or direct abstract declarator; arguments 2461169689Skan as c_parser_declarator. */ 2462169689Skan 2463169689Skanstatic struct c_declarator * 2464169689Skanc_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, 2465169689Skan bool *seen_id) 2466169689Skan{ 2467169689Skan /* The direct declarator must start with an identifier (possibly 2468169689Skan omitted) or a parenthesized declarator (possibly abstract). In 2469169689Skan an ordinary declarator, initial parentheses must start a 2470169689Skan parenthesized declarator. In an abstract declarator or parameter 2471169689Skan declarator, they could start a parenthesized declarator or a 2472169689Skan parameter list. To tell which, the open parenthesis and any 2473169689Skan following attributes must be read. If a declaration specifier 2474169689Skan follows, then it is a parameter list; if the specifier is a 2475169689Skan typedef name, there might be an ambiguity about redeclaring it, 2476169689Skan which is resolved in the direction of treating it as a typedef 2477169689Skan name. If a close parenthesis follows, it is also an empty 2478169689Skan parameter list, as the syntax does not permit empty abstract 2479169689Skan declarators. Otherwise, it is a parenthesized declarator (in 2480169689Skan which case the analysis may be repeated inside it, recursively). 2481169689Skan 2482169689Skan ??? There is an ambiguity in a parameter declaration "int 2483169689Skan (__attribute__((foo)) x)", where x is not a typedef name: it 2484169689Skan could be an abstract declarator for a function, or declare x with 2485169689Skan parentheses. The proper resolution of this ambiguity needs 2486169689Skan documenting. At present we follow an accident of the old 2487169689Skan parser's implementation, whereby the first parameter must have 2488169689Skan some declaration specifiers other than just attributes. Thus as 2489169689Skan a parameter declaration it is treated as a parenthesized 2490169689Skan parameter named x, and as an abstract declarator it is 2491169689Skan rejected. 2492169689Skan 2493169689Skan ??? Also following the old parser, attributes inside an empty 2494169689Skan parameter list are ignored, making it a list not yielding a 2495169689Skan prototype, rather than giving an error or making it have one 2496169689Skan parameter with implicit type int. 2497169689Skan 2498169689Skan ??? Also following the old parser, typedef names may be 2499169689Skan redeclared in declarators, but not Objective-C class names. */ 2500169689Skan 2501260311Spfg /* APPLE LOCAL blocks 6339747 */ 2502260311Spfg if ((kind != C_DTR_ABSTRACT && kind != C_DTR_BLOCK) 2503169689Skan && c_parser_next_token_is (parser, CPP_NAME) 2504169689Skan && ((type_seen_p 2505260311Spfg /* APPLE LOCAL begin radar 4281748 */ 2506260311Spfg && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME 2507260311Spfg || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) 2508260311Spfg /* APPLE LOCAL end radar 4281748 */ 2509169689Skan || c_parser_peek_token (parser)->id_kind == C_ID_ID)) 2510169689Skan { 2511169689Skan struct c_declarator *inner 2512169689Skan = build_id_declarator (c_parser_peek_token (parser)->value); 2513169689Skan *seen_id = true; 2514169689Skan inner->id_loc = c_parser_peek_token (parser)->location; 2515169689Skan c_parser_consume_token (parser); 2516169689Skan return c_parser_direct_declarator_inner (parser, *seen_id, inner); 2517169689Skan } 2518169689Skan 2519169689Skan if (kind != C_DTR_NORMAL 2520169689Skan && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 2521169689Skan { 2522169689Skan struct c_declarator *inner = build_id_declarator (NULL_TREE); 2523169689Skan return c_parser_direct_declarator_inner (parser, *seen_id, inner); 2524169689Skan } 2525169689Skan 2526169689Skan /* Either we are at the end of an abstract declarator, or we have 2527169689Skan parentheses. */ 2528169689Skan 2529169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 2530169689Skan { 2531169689Skan tree attrs; 2532169689Skan struct c_declarator *inner; 2533169689Skan c_parser_consume_token (parser); 2534169689Skan attrs = c_parser_attributes (parser); 2535169689Skan if (kind != C_DTR_NORMAL 2536169689Skan && (c_parser_next_token_starts_declspecs (parser) 2537169689Skan || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) 2538169689Skan { 2539169689Skan struct c_arg_info *args 2540169689Skan = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL, 2541169689Skan attrs); 2542169689Skan if (args == NULL) 2543169689Skan return NULL; 2544169689Skan else 2545169689Skan { 2546169689Skan inner 2547169689Skan = build_function_declarator (args, 2548169689Skan build_id_declarator (NULL_TREE)); 2549169689Skan return c_parser_direct_declarator_inner (parser, *seen_id, 2550169689Skan inner); 2551169689Skan } 2552169689Skan } 2553169689Skan /* A parenthesized declarator. */ 2554169689Skan inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); 2555169689Skan if (inner != NULL && attrs != NULL) 2556169689Skan inner = build_attrs_declarator (attrs, inner); 2557169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 2558169689Skan { 2559169689Skan c_parser_consume_token (parser); 2560169689Skan if (inner == NULL) 2561169689Skan return NULL; 2562169689Skan else 2563169689Skan return c_parser_direct_declarator_inner (parser, *seen_id, inner); 2564169689Skan } 2565169689Skan else 2566169689Skan { 2567169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 2568169689Skan "expected %<)%>"); 2569169689Skan return NULL; 2570169689Skan } 2571169689Skan } 2572169689Skan else 2573169689Skan { 2574169689Skan if (kind == C_DTR_NORMAL) 2575169689Skan { 2576169689Skan c_parser_error (parser, "expected identifier or %<(%>"); 2577169689Skan return NULL; 2578169689Skan } 2579169689Skan else 2580169689Skan return build_id_declarator (NULL_TREE); 2581169689Skan } 2582169689Skan} 2583169689Skan 2584169689Skan/* Parse part of a direct declarator or direct abstract declarator, 2585169689Skan given that some (in INNER) has already been parsed; ID_PRESENT is 2586169689Skan true if an identifier is present, false for an abstract 2587169689Skan declarator. */ 2588169689Skan 2589169689Skanstatic struct c_declarator * 2590169689Skanc_parser_direct_declarator_inner (c_parser *parser, bool id_present, 2591169689Skan struct c_declarator *inner) 2592169689Skan{ 2593169689Skan /* Parse a sequence of array declarators and parameter lists. */ 2594169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 2595169689Skan { 2596169689Skan struct c_declarator *declarator; 2597169689Skan struct c_declspecs *quals_attrs = build_null_declspecs (); 2598169689Skan bool static_seen; 2599169689Skan bool star_seen; 2600169689Skan tree dimen; 2601169689Skan c_parser_consume_token (parser); 2602169689Skan c_parser_declspecs (parser, quals_attrs, false, false, true); 2603169689Skan static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC); 2604169689Skan if (static_seen) 2605169689Skan c_parser_consume_token (parser); 2606169689Skan if (static_seen && !quals_attrs->declspecs_seen_p) 2607169689Skan c_parser_declspecs (parser, quals_attrs, false, false, true); 2608169689Skan if (!quals_attrs->declspecs_seen_p) 2609169689Skan quals_attrs = NULL; 2610169689Skan /* If "static" is present, there must be an array dimension. 2611169689Skan Otherwise, there may be a dimension, "*", or no 2612169689Skan dimension. */ 2613169689Skan if (static_seen) 2614169689Skan { 2615169689Skan star_seen = false; 2616169689Skan dimen = c_parser_expr_no_commas (parser, NULL).value; 2617169689Skan } 2618169689Skan else 2619169689Skan { 2620169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 2621169689Skan { 2622169689Skan dimen = NULL_TREE; 2623169689Skan star_seen = false; 2624169689Skan } 2625169689Skan else if (c_parser_next_token_is (parser, CPP_MULT)) 2626169689Skan { 2627169689Skan if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE) 2628169689Skan { 2629169689Skan dimen = NULL_TREE; 2630169689Skan star_seen = true; 2631169689Skan c_parser_consume_token (parser); 2632169689Skan } 2633169689Skan else 2634169689Skan { 2635169689Skan star_seen = false; 2636169689Skan dimen = c_parser_expr_no_commas (parser, NULL).value; 2637169689Skan } 2638169689Skan } 2639169689Skan else 2640169689Skan { 2641169689Skan star_seen = false; 2642169689Skan dimen = c_parser_expr_no_commas (parser, NULL).value; 2643169689Skan } 2644169689Skan } 2645169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 2646169689Skan c_parser_consume_token (parser); 2647169689Skan else 2648169689Skan { 2649169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 2650169689Skan "expected %<]%>"); 2651169689Skan return NULL; 2652169689Skan } 2653169689Skan declarator = build_array_declarator (dimen, quals_attrs, static_seen, 2654169689Skan star_seen); 2655169689Skan if (declarator == NULL) 2656169689Skan return NULL; 2657169689Skan inner = set_array_declarator_inner (declarator, inner, !id_present); 2658169689Skan return c_parser_direct_declarator_inner (parser, id_present, inner); 2659169689Skan } 2660169689Skan else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 2661169689Skan { 2662169689Skan tree attrs; 2663169689Skan struct c_arg_info *args; 2664169689Skan c_parser_consume_token (parser); 2665169689Skan attrs = c_parser_attributes (parser); 2666169689Skan args = c_parser_parms_declarator (parser, id_present, attrs); 2667169689Skan if (args == NULL) 2668169689Skan return NULL; 2669169689Skan else 2670169689Skan { 2671169689Skan inner = build_function_declarator (args, inner); 2672169689Skan return c_parser_direct_declarator_inner (parser, id_present, inner); 2673169689Skan } 2674169689Skan } 2675169689Skan return inner; 2676169689Skan} 2677169689Skan 2678169689Skan/* Parse a parameter list or identifier list, including the closing 2679169689Skan parenthesis but not the opening one. ATTRS are the attributes at 2680169689Skan the start of the list. ID_LIST_OK is true if an identifier list is 2681169689Skan acceptable; such a list must not have attributes at the start. */ 2682169689Skan 2683169689Skanstatic struct c_arg_info * 2684169689Skanc_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs) 2685169689Skan{ 2686169689Skan push_scope (); 2687169689Skan declare_parm_level (); 2688169689Skan /* If the list starts with an identifier, it is an identifier list. 2689169689Skan Otherwise, it is either a prototype list or an empty list. */ 2690169689Skan if (id_list_ok 2691169689Skan && !attrs 2692169689Skan && c_parser_next_token_is (parser, CPP_NAME) 2693169689Skan && c_parser_peek_token (parser)->id_kind == C_ID_ID) 2694169689Skan { 2695169689Skan tree list = NULL_TREE, *nextp = &list; 2696169689Skan while (c_parser_next_token_is (parser, CPP_NAME) 2697169689Skan && c_parser_peek_token (parser)->id_kind == C_ID_ID) 2698169689Skan { 2699169689Skan *nextp = build_tree_list (NULL_TREE, 2700169689Skan c_parser_peek_token (parser)->value); 2701169689Skan nextp = & TREE_CHAIN (*nextp); 2702169689Skan c_parser_consume_token (parser); 2703169689Skan if (c_parser_next_token_is_not (parser, CPP_COMMA)) 2704169689Skan break; 2705169689Skan c_parser_consume_token (parser); 2706169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 2707169689Skan { 2708169689Skan c_parser_error (parser, "expected identifier"); 2709169689Skan break; 2710169689Skan } 2711169689Skan } 2712169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 2713169689Skan { 2714169689Skan struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info); 2715169689Skan ret->parms = 0; 2716169689Skan ret->tags = 0; 2717169689Skan ret->types = list; 2718169689Skan ret->others = 0; 2719169689Skan ret->pending_sizes = 0; 2720169689Skan ret->had_vla_unspec = 0; 2721169689Skan c_parser_consume_token (parser); 2722169689Skan pop_scope (); 2723169689Skan return ret; 2724169689Skan } 2725169689Skan else 2726169689Skan { 2727169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 2728169689Skan "expected %<)%>"); 2729169689Skan pop_scope (); 2730169689Skan return NULL; 2731169689Skan } 2732169689Skan } 2733169689Skan else 2734169689Skan { 2735169689Skan struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs); 2736169689Skan pop_scope (); 2737169689Skan return ret; 2738169689Skan } 2739169689Skan} 2740169689Skan 2741169689Skan/* Parse a parameter list (possibly empty), including the closing 2742169689Skan parenthesis but not the opening one. ATTRS are the attributes at 2743169689Skan the start of the list. */ 2744169689Skan 2745169689Skanstatic struct c_arg_info * 2746169689Skanc_parser_parms_list_declarator (c_parser *parser, tree attrs) 2747169689Skan{ 2748169689Skan bool good_parm = false; 2749169689Skan /* ??? Following the old parser, forward parameter declarations may 2750169689Skan use abstract declarators, and if no real parameter declarations 2751169689Skan follow the forward declarations then this is not diagnosed. Also 2752169689Skan note as above that attributes are ignored as the only contents of 2753169689Skan the parentheses, or as the only contents after forward 2754169689Skan declarations. */ 2755169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 2756169689Skan { 2757169689Skan struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info); 2758169689Skan ret->parms = 0; 2759169689Skan ret->tags = 0; 2760169689Skan ret->types = 0; 2761169689Skan ret->others = 0; 2762169689Skan ret->pending_sizes = 0; 2763169689Skan ret->had_vla_unspec = 0; 2764169689Skan c_parser_consume_token (parser); 2765169689Skan return ret; 2766169689Skan } 2767169689Skan if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 2768169689Skan { 2769169689Skan struct c_arg_info *ret = XOBNEW (&parser_obstack, struct c_arg_info); 2770169689Skan ret->parms = 0; 2771169689Skan ret->tags = 0; 2772169689Skan ret->others = 0; 2773169689Skan ret->pending_sizes = 0; 2774169689Skan ret->had_vla_unspec = 0; 2775169689Skan /* Suppress -Wold-style-definition for this case. */ 2776169689Skan ret->types = error_mark_node; 2777169689Skan error ("ISO C requires a named argument before %<...%>"); 2778169689Skan c_parser_consume_token (parser); 2779169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 2780169689Skan { 2781169689Skan c_parser_consume_token (parser); 2782169689Skan return ret; 2783169689Skan } 2784169689Skan else 2785169689Skan { 2786169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 2787169689Skan "expected %<)%>"); 2788169689Skan return NULL; 2789169689Skan } 2790169689Skan } 2791169689Skan /* Nonempty list of parameters, either terminated with semicolon 2792169689Skan (forward declarations; recurse) or with close parenthesis (normal 2793169689Skan function) or with ", ... )" (variadic function). */ 2794169689Skan while (true) 2795169689Skan { 2796169689Skan /* Parse a parameter. */ 2797169689Skan struct c_parm *parm = c_parser_parameter_declaration (parser, attrs); 2798169689Skan attrs = NULL_TREE; 2799169689Skan if (parm != NULL) 2800169689Skan { 2801169689Skan good_parm = true; 2802169689Skan push_parm_decl (parm); 2803169689Skan } 2804169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 2805169689Skan { 2806169689Skan tree new_attrs; 2807169689Skan c_parser_consume_token (parser); 2808169689Skan mark_forward_parm_decls (); 2809169689Skan new_attrs = c_parser_attributes (parser); 2810169689Skan return c_parser_parms_list_declarator (parser, new_attrs); 2811169689Skan } 2812169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 2813169689Skan { 2814169689Skan c_parser_consume_token (parser); 2815169689Skan if (good_parm) 2816169689Skan return get_parm_info (false); 2817169689Skan else 2818169689Skan { 2819169689Skan struct c_arg_info *ret 2820169689Skan = XOBNEW (&parser_obstack, struct c_arg_info); 2821169689Skan ret->parms = 0; 2822169689Skan ret->tags = 0; 2823169689Skan ret->types = 0; 2824169689Skan ret->others = 0; 2825169689Skan ret->pending_sizes = 0; 2826169689Skan ret->had_vla_unspec = 0; 2827169689Skan return ret; 2828169689Skan } 2829169689Skan } 2830169689Skan if (!c_parser_require (parser, CPP_COMMA, 2831169689Skan "expected %<;%>, %<,%> or %<)%>")) 2832169689Skan { 2833169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 2834169689Skan return NULL; 2835169689Skan } 2836169689Skan if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 2837169689Skan { 2838169689Skan c_parser_consume_token (parser); 2839169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 2840169689Skan { 2841169689Skan c_parser_consume_token (parser); 2842169689Skan if (good_parm) 2843169689Skan return get_parm_info (true); 2844169689Skan else 2845169689Skan { 2846169689Skan struct c_arg_info *ret 2847169689Skan = XOBNEW (&parser_obstack, struct c_arg_info); 2848169689Skan ret->parms = 0; 2849169689Skan ret->tags = 0; 2850169689Skan ret->types = 0; 2851169689Skan ret->others = 0; 2852169689Skan ret->pending_sizes = 0; 2853169689Skan ret->had_vla_unspec = 0; 2854169689Skan return ret; 2855169689Skan } 2856169689Skan } 2857169689Skan else 2858169689Skan { 2859169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 2860169689Skan "expected %<)%>"); 2861169689Skan return NULL; 2862169689Skan } 2863169689Skan } 2864169689Skan } 2865169689Skan} 2866169689Skan 2867169689Skan/* Parse a parameter declaration. ATTRS are the attributes at the 2868169689Skan start of the declaration if it is the first parameter. */ 2869169689Skan 2870169689Skanstatic struct c_parm * 2871169689Skanc_parser_parameter_declaration (c_parser *parser, tree attrs) 2872169689Skan{ 2873169689Skan struct c_declspecs *specs; 2874169689Skan struct c_declarator *declarator; 2875169689Skan tree prefix_attrs; 2876169689Skan tree postfix_attrs = NULL_TREE; 2877169689Skan bool dummy = false; 2878169689Skan if (!c_parser_next_token_starts_declspecs (parser)) 2879169689Skan { 2880169689Skan /* ??? In some Objective-C cases '...' isn't applicable so there 2881169689Skan should be a different message. */ 2882169689Skan c_parser_error (parser, 2883169689Skan "expected declaration specifiers or %<...%>"); 2884169689Skan c_parser_skip_to_end_of_parameter (parser); 2885169689Skan return NULL; 2886169689Skan } 2887169689Skan specs = build_null_declspecs (); 2888169689Skan if (attrs) 2889169689Skan { 2890169689Skan declspecs_add_attrs (specs, attrs); 2891169689Skan attrs = NULL_TREE; 2892169689Skan } 2893169689Skan c_parser_declspecs (parser, specs, true, true, true); 2894169689Skan finish_declspecs (specs); 2895169689Skan pending_xref_error (); 2896169689Skan prefix_attrs = specs->attrs; 2897169689Skan specs->attrs = NULL_TREE; 2898169689Skan declarator = c_parser_declarator (parser, specs->type_seen_p, 2899169689Skan C_DTR_PARM, &dummy); 2900169689Skan if (declarator == NULL) 2901169689Skan { 2902169689Skan c_parser_skip_until_found (parser, CPP_COMMA, NULL); 2903169689Skan return NULL; 2904169689Skan } 2905169689Skan if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 2906169689Skan postfix_attrs = c_parser_attributes (parser); 2907169689Skan return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs), 2908169689Skan declarator); 2909169689Skan} 2910169689Skan 2911169689Skan/* Parse a string literal in an asm expression. It should not be 2912169689Skan translated, and wide string literals are an error although 2913169689Skan permitted by the syntax. This is a GNU extension. 2914169689Skan 2915169689Skan asm-string-literal: 2916169689Skan string-literal 2917169689Skan 2918169689Skan ??? At present, following the old parser, the caller needs to have 2919169689Skan set c_lex_string_translate to 0. It would be better to follow the 2920169689Skan C++ parser rather than using the c_lex_string_translate kludge. */ 2921169689Skan 2922169689Skanstatic tree 2923169689Skanc_parser_asm_string_literal (c_parser *parser) 2924169689Skan{ 2925169689Skan tree str; 2926169689Skan if (c_parser_next_token_is (parser, CPP_STRING)) 2927169689Skan { 2928169689Skan str = c_parser_peek_token (parser)->value; 2929169689Skan c_parser_consume_token (parser); 2930169689Skan } 2931169689Skan else if (c_parser_next_token_is (parser, CPP_WSTRING)) 2932169689Skan { 2933169689Skan error ("wide string literal in %<asm%>"); 2934169689Skan str = build_string (1, ""); 2935169689Skan c_parser_consume_token (parser); 2936169689Skan } 2937169689Skan else 2938169689Skan { 2939169689Skan c_parser_error (parser, "expected string literal"); 2940169689Skan str = NULL_TREE; 2941169689Skan } 2942169689Skan return str; 2943169689Skan} 2944169689Skan 2945169689Skan/* Parse a simple asm expression. This is used in restricted 2946169689Skan contexts, where a full expression with inputs and outputs does not 2947169689Skan make sense. This is a GNU extension. 2948169689Skan 2949169689Skan simple-asm-expr: 2950169689Skan asm ( asm-string-literal ) 2951169689Skan*/ 2952169689Skan 2953169689Skanstatic tree 2954169689Skanc_parser_simple_asm_expr (c_parser *parser) 2955169689Skan{ 2956169689Skan tree str; 2957169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM)); 2958169689Skan /* ??? Follow the C++ parser rather than using the 2959169689Skan c_lex_string_translate kludge. */ 2960169689Skan c_lex_string_translate = 0; 2961169689Skan c_parser_consume_token (parser); 2962169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 2963169689Skan { 2964169689Skan c_lex_string_translate = 1; 2965169689Skan return NULL_TREE; 2966169689Skan } 2967169689Skan str = c_parser_asm_string_literal (parser); 2968169689Skan c_lex_string_translate = 1; 2969169689Skan if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 2970169689Skan { 2971169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 2972169689Skan return NULL_TREE; 2973169689Skan } 2974169689Skan return str; 2975169689Skan} 2976169689Skan 2977169689Skan/* Parse (possibly empty) attributes. This is a GNU extension. 2978169689Skan 2979169689Skan attributes: 2980169689Skan empty 2981169689Skan attributes attribute 2982169689Skan 2983169689Skan attribute: 2984169689Skan __attribute__ ( ( attribute-list ) ) 2985169689Skan 2986169689Skan attribute-list: 2987169689Skan attrib 2988169689Skan attribute_list , attrib 2989169689Skan 2990169689Skan attrib: 2991169689Skan empty 2992169689Skan any-word 2993169689Skan any-word ( identifier ) 2994169689Skan any-word ( identifier , nonempty-expr-list ) 2995169689Skan any-word ( expr-list ) 2996169689Skan 2997169689Skan where the "identifier" must not be declared as a type, and 2998169689Skan "any-word" may be any identifier (including one declared as a 2999169689Skan type), a reserved word storage class specifier, type specifier or 3000169689Skan type qualifier. ??? This still leaves out most reserved keywords 3001169689Skan (following the old parser), shouldn't we include them, and why not 3002169689Skan allow identifiers declared as types to start the arguments? */ 3003169689Skan 3004169689Skanstatic tree 3005169689Skanc_parser_attributes (c_parser *parser) 3006169689Skan{ 3007169689Skan tree attrs = NULL_TREE; 3008169689Skan while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 3009169689Skan { 3010169689Skan /* ??? Follow the C++ parser rather than using the 3011169689Skan c_lex_string_translate kludge. */ 3012169689Skan c_lex_string_translate = 0; 3013169689Skan c_parser_consume_token (parser); 3014169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 3015169689Skan { 3016169689Skan c_lex_string_translate = 1; 3017169689Skan return attrs; 3018169689Skan } 3019169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 3020169689Skan { 3021169689Skan c_lex_string_translate = 1; 3022169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 3023169689Skan return attrs; 3024169689Skan } 3025169689Skan /* Parse the attribute list. */ 3026169689Skan while (c_parser_next_token_is (parser, CPP_COMMA) 3027169689Skan || c_parser_next_token_is (parser, CPP_NAME) 3028169689Skan || c_parser_next_token_is (parser, CPP_KEYWORD)) 3029169689Skan { 3030169689Skan tree attr, attr_name, attr_args; 3031169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 3032169689Skan { 3033169689Skan c_parser_consume_token (parser); 3034169689Skan continue; 3035169689Skan } 3036169689Skan if (c_parser_next_token_is (parser, CPP_KEYWORD)) 3037169689Skan { 3038169689Skan /* ??? See comment above about what keywords are 3039169689Skan accepted here. */ 3040169689Skan bool ok; 3041169689Skan switch (c_parser_peek_token (parser)->keyword) 3042169689Skan { 3043169689Skan case RID_STATIC: 3044169689Skan case RID_UNSIGNED: 3045169689Skan case RID_LONG: 3046169689Skan case RID_CONST: 3047169689Skan case RID_EXTERN: 3048169689Skan case RID_REGISTER: 3049169689Skan case RID_TYPEDEF: 3050169689Skan case RID_SHORT: 3051169689Skan case RID_INLINE: 3052169689Skan case RID_VOLATILE: 3053169689Skan case RID_SIGNED: 3054169689Skan case RID_AUTO: 3055169689Skan case RID_RESTRICT: 3056169689Skan case RID_COMPLEX: 3057169689Skan case RID_THREAD: 3058169689Skan case RID_INT: 3059169689Skan case RID_CHAR: 3060169689Skan case RID_FLOAT: 3061169689Skan case RID_DOUBLE: 3062169689Skan case RID_VOID: 3063169689Skan case RID_DFLOAT32: 3064169689Skan case RID_DFLOAT64: 3065169689Skan case RID_DFLOAT128: 3066169689Skan case RID_BOOL: 3067169689Skan ok = true; 3068169689Skan break; 3069169689Skan default: 3070169689Skan ok = false; 3071169689Skan break; 3072169689Skan } 3073169689Skan if (!ok) 3074169689Skan break; 3075169689Skan } 3076169689Skan attr_name = c_parser_peek_token (parser)->value; 3077169689Skan c_parser_consume_token (parser); 3078169689Skan if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) 3079169689Skan { 3080169689Skan attr = build_tree_list (attr_name, NULL_TREE); 3081169689Skan attrs = chainon (attrs, attr); 3082169689Skan continue; 3083169689Skan } 3084169689Skan c_parser_consume_token (parser); 3085169689Skan /* Parse the attribute contents. If they start with an 3086169689Skan identifier which is followed by a comma or close 3087169689Skan parenthesis, then the arguments start with that 3088169689Skan identifier; otherwise they are an expression list. */ 3089169689Skan if (c_parser_next_token_is (parser, CPP_NAME) 3090169689Skan && c_parser_peek_token (parser)->id_kind == C_ID_ID 3091169689Skan && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 3092169689Skan || (c_parser_peek_2nd_token (parser)->type 3093169689Skan == CPP_CLOSE_PAREN))) 3094169689Skan { 3095169689Skan tree arg1 = c_parser_peek_token (parser)->value; 3096169689Skan c_parser_consume_token (parser); 3097169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3098169689Skan attr_args = build_tree_list (NULL_TREE, arg1); 3099169689Skan else 3100169689Skan { 3101169689Skan c_parser_consume_token (parser); 3102169689Skan attr_args = tree_cons (NULL_TREE, arg1, 3103169689Skan c_parser_expr_list (parser, false)); 3104169689Skan } 3105169689Skan } 3106169689Skan else 3107169689Skan { 3108169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3109169689Skan attr_args = NULL_TREE; 3110169689Skan else 3111169689Skan attr_args = c_parser_expr_list (parser, false); 3112169689Skan } 3113169689Skan attr = build_tree_list (attr_name, attr_args); 3114169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3115169689Skan c_parser_consume_token (parser); 3116169689Skan else 3117169689Skan { 3118169689Skan c_lex_string_translate = 1; 3119169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 3120169689Skan "expected %<)%>"); 3121169689Skan return attrs; 3122169689Skan } 3123169689Skan attrs = chainon (attrs, attr); 3124169689Skan } 3125169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3126169689Skan c_parser_consume_token (parser); 3127169689Skan else 3128169689Skan { 3129169689Skan c_lex_string_translate = 1; 3130169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 3131169689Skan "expected %<)%>"); 3132169689Skan return attrs; 3133169689Skan } 3134169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3135169689Skan c_parser_consume_token (parser); 3136169689Skan else 3137169689Skan { 3138169689Skan c_lex_string_translate = 1; 3139169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 3140169689Skan "expected %<)%>"); 3141169689Skan return attrs; 3142169689Skan } 3143169689Skan c_lex_string_translate = 1; 3144169689Skan } 3145169689Skan return attrs; 3146169689Skan} 3147169689Skan 3148169689Skan/* Parse a type name (C90 6.5.5, C99 6.7.6). 3149169689Skan 3150169689Skan type-name: 3151169689Skan specifier-qualifier-list abstract-declarator[opt] 3152169689Skan*/ 3153169689Skan 3154169689Skanstatic struct c_type_name * 3155169689Skanc_parser_type_name (c_parser *parser) 3156169689Skan{ 3157169689Skan struct c_declspecs *specs = build_null_declspecs (); 3158169689Skan struct c_declarator *declarator; 3159169689Skan struct c_type_name *ret; 3160169689Skan bool dummy = false; 3161169689Skan c_parser_declspecs (parser, specs, false, true, true); 3162169689Skan if (!specs->declspecs_seen_p) 3163169689Skan { 3164169689Skan c_parser_error (parser, "expected specifier-qualifier-list"); 3165169689Skan return NULL; 3166169689Skan } 3167169689Skan pending_xref_error (); 3168169689Skan finish_declspecs (specs); 3169169689Skan declarator = c_parser_declarator (parser, specs->type_seen_p, 3170169689Skan C_DTR_ABSTRACT, &dummy); 3171169689Skan if (declarator == NULL) 3172169689Skan return NULL; 3173169689Skan ret = XOBNEW (&parser_obstack, struct c_type_name); 3174169689Skan ret->specs = specs; 3175169689Skan ret->declarator = declarator; 3176169689Skan return ret; 3177169689Skan} 3178169689Skan 3179169689Skan/* Parse an initializer (C90 6.5.7, C99 6.7.8). 3180169689Skan 3181169689Skan initializer: 3182169689Skan assignment-expression 3183169689Skan { initializer-list } 3184169689Skan { initializer-list , } 3185169689Skan 3186169689Skan initializer-list: 3187169689Skan designation[opt] initializer 3188169689Skan initializer-list , designation[opt] initializer 3189169689Skan 3190169689Skan designation: 3191169689Skan designator-list = 3192169689Skan 3193169689Skan designator-list: 3194169689Skan designator 3195169689Skan designator-list designator 3196169689Skan 3197169689Skan designator: 3198169689Skan array-designator 3199169689Skan . identifier 3200169689Skan 3201169689Skan array-designator: 3202169689Skan [ constant-expression ] 3203169689Skan 3204169689Skan GNU extensions: 3205169689Skan 3206169689Skan initializer: 3207169689Skan { } 3208169689Skan 3209169689Skan designation: 3210169689Skan array-designator 3211169689Skan identifier : 3212169689Skan 3213169689Skan array-designator: 3214169689Skan [ constant-expression ... constant-expression ] 3215169689Skan 3216169689Skan Any expression without commas is accepted in the syntax for the 3217169689Skan constant-expressions, with non-constant expressions rejected later. 3218169689Skan 3219169689Skan This function is only used for top-level initializers; for nested 3220169689Skan ones, see c_parser_initval. */ 3221169689Skan 3222169689Skanstatic struct c_expr 3223169689Skanc_parser_initializer (c_parser *parser) 3224169689Skan{ 3225169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 3226169689Skan return c_parser_braced_init (parser, NULL_TREE, false); 3227169689Skan else 3228169689Skan { 3229169689Skan struct c_expr ret; 3230169689Skan ret = c_parser_expr_no_commas (parser, NULL); 3231169689Skan if (TREE_CODE (ret.value) != STRING_CST 3232169689Skan && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR) 3233169689Skan ret = default_function_array_conversion (ret); 3234169689Skan return ret; 3235169689Skan } 3236169689Skan} 3237169689Skan 3238169689Skan/* Parse a braced initializer list. TYPE is the type specified for a 3239169689Skan compound literal, and NULL_TREE for other initializers and for 3240169689Skan nested braced lists. NESTED_P is true for nested braced lists, 3241169689Skan false for the list of a compound literal or the list that is the 3242169689Skan top-level initializer in a declaration. */ 3243169689Skan 3244169689Skanstatic struct c_expr 3245169689Skanc_parser_braced_init (c_parser *parser, tree type, bool nested_p) 3246169689Skan{ 3247169689Skan gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); 3248169689Skan c_parser_consume_token (parser); 3249169689Skan if (nested_p) 3250169689Skan push_init_level (0); 3251169689Skan else 3252169689Skan really_start_incremental_init (type); 3253169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3254169689Skan { 3255169689Skan if (pedantic) 3256169689Skan pedwarn ("ISO C forbids empty initializer braces"); 3257169689Skan } 3258169689Skan else 3259169689Skan { 3260169689Skan /* Parse a non-empty initializer list, possibly with a trailing 3261169689Skan comma. */ 3262169689Skan while (true) 3263169689Skan { 3264169689Skan c_parser_initelt (parser); 3265169689Skan if (parser->error) 3266169689Skan break; 3267169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 3268169689Skan c_parser_consume_token (parser); 3269169689Skan else 3270169689Skan break; 3271169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3272169689Skan break; 3273169689Skan } 3274169689Skan } 3275169689Skan if (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) 3276169689Skan { 3277169689Skan struct c_expr ret; 3278169689Skan ret.value = error_mark_node; 3279169689Skan ret.original_code = ERROR_MARK; 3280169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>"); 3281169689Skan return ret; 3282169689Skan } 3283169689Skan c_parser_consume_token (parser); 3284169689Skan return pop_init_level (0); 3285169689Skan} 3286169689Skan 3287169689Skan/* Parse a nested initializer, including designators. */ 3288169689Skan 3289169689Skanstatic void 3290169689Skanc_parser_initelt (c_parser *parser) 3291169689Skan{ 3292169689Skan /* Parse any designator or designator list. A single array 3293169689Skan designator may have the subsequent "=" omitted in GNU C, but a 3294169689Skan longer list or a structure member designator may not. */ 3295169689Skan if (c_parser_next_token_is (parser, CPP_NAME) 3296169689Skan && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 3297169689Skan { 3298169689Skan /* Old-style structure member designator. */ 3299169689Skan set_init_label (c_parser_peek_token (parser)->value); 3300169689Skan if (pedantic) 3301169689Skan pedwarn ("obsolete use of designated initializer with %<:%>"); 3302169689Skan c_parser_consume_token (parser); 3303169689Skan c_parser_consume_token (parser); 3304169689Skan } 3305169689Skan else 3306169689Skan { 3307169689Skan /* des_seen is 0 if there have been no designators, 1 if there 3308169689Skan has been a single array designator and 2 otherwise. */ 3309169689Skan int des_seen = 0; 3310169689Skan while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE) 3311169689Skan || c_parser_next_token_is (parser, CPP_DOT)) 3312169689Skan { 3313169689Skan int des_prev = des_seen; 3314169689Skan if (des_seen < 2) 3315169689Skan des_seen++; 3316169689Skan if (c_parser_next_token_is (parser, CPP_DOT)) 3317169689Skan { 3318169689Skan des_seen = 2; 3319169689Skan c_parser_consume_token (parser); 3320169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 3321169689Skan { 3322169689Skan set_init_label (c_parser_peek_token (parser)->value); 3323169689Skan c_parser_consume_token (parser); 3324169689Skan } 3325169689Skan else 3326169689Skan { 3327169689Skan struct c_expr init; 3328169689Skan init.value = error_mark_node; 3329169689Skan init.original_code = ERROR_MARK; 3330169689Skan c_parser_error (parser, "expected identifier"); 3331169689Skan c_parser_skip_until_found (parser, CPP_COMMA, NULL); 3332169689Skan process_init_element (init); 3333169689Skan return; 3334169689Skan } 3335169689Skan } 3336169689Skan else 3337169689Skan { 3338169689Skan tree first, second; 3339169689Skan /* ??? Following the old parser, [ objc-receiver 3340169689Skan objc-message-args ] is accepted as an initializer, 3341169689Skan being distinguished from a designator by what follows 3342169689Skan the first assignment expression inside the square 3343169689Skan brackets, but after a first array designator a 3344169689Skan subsequent square bracket is for Objective-C taken to 3345169689Skan start an expression, using the obsolete form of 3346169689Skan designated initializer without '=', rather than 3347169689Skan possibly being a second level of designation: in LALR 3348169689Skan terms, the '[' is shifted rather than reducing 3349169689Skan designator to designator-list. */ 3350169689Skan if (des_prev == 1 && c_dialect_objc ()) 3351169689Skan { 3352169689Skan des_seen = des_prev; 3353169689Skan break; 3354169689Skan } 3355169689Skan if (des_prev == 0 && c_dialect_objc ()) 3356169689Skan { 3357169689Skan /* This might be an array designator or an 3358169689Skan Objective-C message expression. If the former, 3359169689Skan continue parsing here; if the latter, parse the 3360169689Skan remainder of the initializer given the starting 3361169689Skan primary-expression. ??? It might make sense to 3362169689Skan distinguish when des_prev == 1 as well; see 3363169689Skan previous comment. */ 3364169689Skan tree rec, args; 3365169689Skan struct c_expr mexpr; 3366169689Skan c_parser_consume_token (parser); 3367169689Skan if (c_parser_peek_token (parser)->type == CPP_NAME 3368169689Skan && ((c_parser_peek_token (parser)->id_kind 3369169689Skan == C_ID_TYPENAME) 3370169689Skan || (c_parser_peek_token (parser)->id_kind 3371169689Skan == C_ID_CLASSNAME))) 3372169689Skan { 3373169689Skan /* Type name receiver. */ 3374169689Skan tree id = c_parser_peek_token (parser)->value; 3375169689Skan c_parser_consume_token (parser); 3376169689Skan rec = objc_get_class_reference (id); 3377169689Skan goto parse_message_args; 3378169689Skan } 3379169689Skan first = c_parser_expr_no_commas (parser, NULL).value; 3380169689Skan if (c_parser_next_token_is (parser, CPP_ELLIPSIS) 3381169689Skan || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 3382169689Skan goto array_desig_after_first; 3383169689Skan /* Expression receiver. So far only one part 3384169689Skan without commas has been parsed; there might be 3385169689Skan more of the expression. */ 3386169689Skan rec = first; 3387169689Skan while (c_parser_next_token_is (parser, CPP_COMMA)) 3388169689Skan { 3389169689Skan struct c_expr next; 3390169689Skan c_parser_consume_token (parser); 3391169689Skan next = c_parser_expr_no_commas (parser, NULL); 3392169689Skan next = default_function_array_conversion (next); 3393169689Skan rec = build_compound_expr (rec, next.value); 3394169689Skan } 3395169689Skan parse_message_args: 3396169689Skan /* Now parse the objc-message-args. */ 3397169689Skan args = c_parser_objc_message_args (parser); 3398169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 3399169689Skan "expected %<]%>"); 3400169689Skan mexpr.value 3401169689Skan = objc_build_message_expr (build_tree_list (rec, args)); 3402169689Skan mexpr.original_code = ERROR_MARK; 3403169689Skan /* Now parse and process the remainder of the 3404169689Skan initializer, starting with this message 3405169689Skan expression as a primary-expression. */ 3406169689Skan c_parser_initval (parser, &mexpr); 3407169689Skan return; 3408169689Skan } 3409169689Skan c_parser_consume_token (parser); 3410169689Skan first = c_parser_expr_no_commas (parser, NULL).value; 3411169689Skan array_desig_after_first: 3412169689Skan if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 3413169689Skan { 3414169689Skan c_parser_consume_token (parser); 3415169689Skan second = c_parser_expr_no_commas (parser, NULL).value; 3416169689Skan } 3417169689Skan else 3418169689Skan second = NULL_TREE; 3419169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 3420169689Skan { 3421169689Skan c_parser_consume_token (parser); 3422169689Skan set_init_index (first, second); 3423169689Skan if (pedantic && second) 3424169689Skan pedwarn ("ISO C forbids specifying range of " 3425169689Skan "elements to initialize"); 3426169689Skan } 3427169689Skan else 3428169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 3429169689Skan "expected %<]%>"); 3430169689Skan } 3431169689Skan } 3432169689Skan if (des_seen >= 1) 3433169689Skan { 3434169689Skan if (c_parser_next_token_is (parser, CPP_EQ)) 3435169689Skan { 3436169689Skan if (pedantic && !flag_isoc99) 3437169689Skan pedwarn ("ISO C90 forbids specifying subobject to initialize"); 3438169689Skan c_parser_consume_token (parser); 3439169689Skan } 3440169689Skan else 3441169689Skan { 3442169689Skan if (des_seen == 1) 3443169689Skan { 3444169689Skan if (pedantic) 3445169689Skan pedwarn ("obsolete use of designated initializer " 3446169689Skan "without %<=%>"); 3447169689Skan } 3448169689Skan else 3449169689Skan { 3450169689Skan struct c_expr init; 3451169689Skan init.value = error_mark_node; 3452169689Skan init.original_code = ERROR_MARK; 3453169689Skan c_parser_error (parser, "expected %<=%>"); 3454169689Skan c_parser_skip_until_found (parser, CPP_COMMA, NULL); 3455169689Skan process_init_element (init); 3456169689Skan return; 3457169689Skan } 3458169689Skan } 3459169689Skan } 3460169689Skan } 3461169689Skan c_parser_initval (parser, NULL); 3462169689Skan} 3463169689Skan 3464169689Skan/* Parse a nested initializer; as c_parser_initializer but parses 3465169689Skan initializers within braced lists, after any designators have been 3466169689Skan applied. If AFTER is not NULL then it is an Objective-C message 3467169689Skan expression which is the primary-expression starting the 3468169689Skan initializer. */ 3469169689Skan 3470169689Skanstatic void 3471169689Skanc_parser_initval (c_parser *parser, struct c_expr *after) 3472169689Skan{ 3473169689Skan struct c_expr init; 3474169689Skan gcc_assert (!after || c_dialect_objc ()); 3475169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after) 3476169689Skan init = c_parser_braced_init (parser, NULL_TREE, true); 3477169689Skan else 3478169689Skan { 3479169689Skan init = c_parser_expr_no_commas (parser, after); 3480169689Skan if (init.value != NULL_TREE 3481169689Skan && TREE_CODE (init.value) != STRING_CST 3482169689Skan && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR) 3483169689Skan init = default_function_array_conversion (init); 3484169689Skan } 3485169689Skan process_init_element (init); 3486169689Skan} 3487169689Skan 3488169689Skan/* Parse a compound statement (possibly a function body) (C90 6.6.2, 3489169689Skan C99 6.8.2). 3490169689Skan 3491169689Skan compound-statement: 3492169689Skan { block-item-list[opt] } 3493169689Skan { label-declarations block-item-list } 3494169689Skan 3495169689Skan block-item-list: 3496169689Skan block-item 3497169689Skan block-item-list block-item 3498169689Skan 3499169689Skan block-item: 3500169689Skan nested-declaration 3501169689Skan statement 3502169689Skan 3503169689Skan nested-declaration: 3504169689Skan declaration 3505169689Skan 3506169689Skan GNU extensions: 3507169689Skan 3508169689Skan compound-statement: 3509169689Skan { label-declarations block-item-list } 3510169689Skan 3511169689Skan nested-declaration: 3512169689Skan __extension__ nested-declaration 3513169689Skan nested-function-definition 3514169689Skan 3515169689Skan label-declarations: 3516169689Skan label-declaration 3517169689Skan label-declarations label-declaration 3518169689Skan 3519169689Skan label-declaration: 3520169689Skan __label__ identifier-list ; 3521169689Skan 3522169689Skan Allowing the mixing of declarations and code is new in C99. The 3523169689Skan GNU syntax also permits (not shown above) labels at the end of 3524169689Skan compound statements, which yield an error. We don't allow labels 3525169689Skan on declarations; this might seem like a natural extension, but 3526169689Skan there would be a conflict between attributes on the label and 3527169689Skan prefix attributes on the declaration. ??? The syntax follows the 3528169689Skan old parser in requiring something after label declarations. 3529169689Skan Although they are erroneous if the labels declared aren't defined, 3530169689Skan is it useful for the syntax to be this way? 3531169689Skan 3532169689Skan OpenMP: 3533169689Skan 3534169689Skan block-item: 3535169689Skan openmp-directive 3536169689Skan 3537169689Skan openmp-directive: 3538169689Skan barrier-directive 3539169689Skan flush-directive */ 3540169689Skan 3541169689Skanstatic tree 3542169689Skanc_parser_compound_statement (c_parser *parser) 3543169689Skan{ 3544169689Skan tree stmt; 3545169689Skan if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 3546169689Skan return error_mark_node; 3547169689Skan stmt = c_begin_compound_stmt (true); 3548169689Skan c_parser_compound_statement_nostart (parser); 3549169689Skan return c_end_compound_stmt (stmt, true); 3550169689Skan} 3551169689Skan 3552169689Skan/* Parse a compound statement except for the opening brace. This is 3553169689Skan used for parsing both compound statements and statement expressions 3554169689Skan (which follow different paths to handling the opening). */ 3555169689Skan 3556169689Skanstatic void 3557169689Skanc_parser_compound_statement_nostart (c_parser *parser) 3558169689Skan{ 3559169689Skan bool last_stmt = false; 3560169689Skan bool last_label = false; 3561260311Spfg /* APPLE LOCAL radar 5732232 - blocks (not in C++) */ 3562260311Spfg bool first_stmt = true; 3563169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3564169689Skan { 3565169689Skan c_parser_consume_token (parser); 3566169689Skan return; 3567169689Skan } 3568169689Skan if (c_parser_next_token_is_keyword (parser, RID_LABEL)) 3569169689Skan { 3570169689Skan /* Read zero or more forward-declarations for labels that nested 3571169689Skan functions can jump to. */ 3572169689Skan while (c_parser_next_token_is_keyword (parser, RID_LABEL)) 3573260311Spfg { 3574260311Spfg c_parser_consume_token (parser); 3575260311Spfg /* Any identifiers, including those declared as type names, 3576260311Spfg are OK here. */ 3577260311Spfg while (true) 3578169689Skan { 3579260311Spfg tree label; 3580260311Spfg if (c_parser_next_token_is_not (parser, CPP_NAME)) 3581169689Skan { 3582260311Spfg c_parser_error (parser, "expected identifier"); 3583260311Spfg break; 3584169689Skan } 3585260311Spfg label 3586169689Skan = declare_label (c_parser_peek_token (parser)->value); 3587260311Spfg C_DECLARED_LABEL_FLAG (label) = 1; 3588260311Spfg add_stmt (build_stmt (DECL_EXPR, label)); 3589169689Skan c_parser_consume_token (parser); 3590260311Spfg if (c_parser_next_token_is (parser, CPP_COMMA)) 3591260311Spfg c_parser_consume_token (parser); 3592260311Spfg else 3593260311Spfg break; 3594169689Skan } 3595260311Spfg c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 3596260311Spfg } 3597169689Skan /* ??? Locating this diagnostic on the token after the 3598169689Skan declarations end follows the old parser, but it might be 3599169689Skan better to locate it where the declarations start instead. */ 3600169689Skan if (pedantic) 3601169689Skan pedwarn ("ISO C forbids label declarations"); 3602169689Skan } 3603169689Skan /* We must now have at least one statement, label or declaration. */ 3604169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3605169689Skan { 3606169689Skan c_parser_error (parser, "expected declaration or statement"); 3607169689Skan c_parser_consume_token (parser); 3608169689Skan return; 3609169689Skan } 3610169689Skan while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) 3611169689Skan { 3612169689Skan location_t loc = c_parser_peek_token (parser)->location; 3613169689Skan if (c_parser_next_token_is_keyword (parser, RID_CASE) 3614260311Spfg || c_parser_next_token_is_keyword (parser, RID_DEFAULT) 3615260311Spfg || (c_parser_next_token_is (parser, CPP_NAME) 3616260311Spfg && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) 3617260311Spfg { 3618260311Spfg last_label = true; 3619260311Spfg last_stmt = false; 3620260311Spfg c_parser_label (parser); 3621260311Spfg } 3622169689Skan else if (!last_label 3623260311Spfg && c_parser_next_token_starts_declspecs (parser)) 3624260311Spfg { 3625260311Spfg last_label = false; 3626260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 3627260311Spfg c_parser_declaration_or_fndef (parser, true, true, true, true, NULL); 3628260311Spfg if (last_stmt 3629260311Spfg && ((pedantic && !flag_isoc99) 3630260311Spfg || warn_declaration_after_statement)) 3631260311Spfg pedwarn_c90 ("%HISO C90 forbids mixed declarations and code", 3632260311Spfg &loc); 3633260311Spfg last_stmt = false; 3634260311Spfg } 3635169689Skan else if (!last_label 3636260311Spfg && c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 3637260311Spfg { 3638260311Spfg /* __extension__ can start a declaration, but is also an 3639260311Spfg unary operator that can start an expression. Consume all 3640260311Spfg but the last of a possible series of __extension__ to 3641260311Spfg determine which. */ 3642260311Spfg while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD 3643260311Spfg && (c_parser_peek_2nd_token (parser)->keyword 3644260311Spfg == RID_EXTENSION)) 3645260311Spfg c_parser_consume_token (parser); 3646260311Spfg if (c_token_starts_declspecs (c_parser_peek_2nd_token (parser))) 3647169689Skan { 3648260311Spfg int ext; 3649260311Spfg ext = disable_extension_diagnostics (); 3650260311Spfg c_parser_consume_token (parser); 3651260311Spfg last_label = false; 3652260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 3653260311Spfg c_parser_declaration_or_fndef (parser, true, true, true, true, NULL); 3654260311Spfg /* Following the old parser, __extension__ does not 3655169689Skan disable this diagnostic. */ 3656260311Spfg restore_extension_diagnostics (ext); 3657260311Spfg if (last_stmt 3658260311Spfg && ((pedantic && !flag_isoc99) 3659260311Spfg || warn_declaration_after_statement)) 3660260311Spfg pedwarn_c90 ("%HISO C90 forbids mixed declarations and code", 3661260311Spfg &loc); 3662260311Spfg last_stmt = false; 3663169689Skan } 3664260311Spfg else 3665260311Spfg goto statement; 3666260311Spfg } 3667169689Skan else if (c_parser_next_token_is (parser, CPP_PRAGMA)) 3668260311Spfg { 3669260311Spfg /* External pragmas, and some omp pragmas, are not associated 3670260311Spfg with regular c code, and so are not to be considered statements 3671260311Spfg syntactically. This ensures that the user doesn't put them 3672260311Spfg places that would turn into syntax errors if the directive 3673260311Spfg were ignored. */ 3674260311Spfg if (c_parser_pragma (parser, pragma_compound)) 3675260311Spfg last_label = false, last_stmt = true; 3676260311Spfg } 3677169689Skan else if (c_parser_next_token_is (parser, CPP_EOF)) 3678260311Spfg { 3679260311Spfg c_parser_error (parser, "expected declaration or statement"); 3680260311Spfg return; 3681260311Spfg } 3682169689Skan else 3683260311Spfg { 3684260311Spfg statement: 3685260311Spfg last_label = false; 3686260311Spfg last_stmt = true; 3687260311Spfg c_parser_statement_after_labels (parser); 3688260311Spfg } 3689260311Spfg 3690169689Skan parser->error = false; 3691260311Spfg /* APPLE LOCAL radar 5732232 - blocks (not in C++) */ 3692260311Spfg first_stmt = false; 3693169689Skan } 3694169689Skan if (last_label) 3695169689Skan error ("label at end of compound statement"); 3696169689Skan c_parser_consume_token (parser); 3697169689Skan} 3698169689Skan 3699169689Skan/* Parse a label (C90 6.6.1, C99 6.8.1). 3700169689Skan 3701169689Skan label: 3702169689Skan identifier : attributes[opt] 3703169689Skan case constant-expression : 3704169689Skan default : 3705169689Skan 3706169689Skan GNU extensions: 3707169689Skan 3708169689Skan label: 3709169689Skan case constant-expression ... constant-expression : 3710169689Skan 3711169689Skan The use of attributes on labels is a GNU extension. The syntax in 3712169689Skan GNU C accepts any expressions without commas, non-constant 3713169689Skan expressions being rejected later. */ 3714169689Skan 3715169689Skanstatic void 3716169689Skanc_parser_label (c_parser *parser) 3717169689Skan{ 3718169689Skan location_t loc1 = c_parser_peek_token (parser)->location; 3719169689Skan tree label = NULL_TREE; 3720169689Skan if (c_parser_next_token_is_keyword (parser, RID_CASE)) 3721169689Skan { 3722169689Skan tree exp1, exp2; 3723169689Skan c_parser_consume_token (parser); 3724169689Skan exp1 = c_parser_expr_no_commas (parser, NULL).value; 3725169689Skan if (c_parser_next_token_is (parser, CPP_COLON)) 3726169689Skan { 3727169689Skan c_parser_consume_token (parser); 3728169689Skan label = do_case (exp1, NULL_TREE); 3729169689Skan } 3730169689Skan else if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 3731169689Skan { 3732169689Skan c_parser_consume_token (parser); 3733169689Skan exp2 = c_parser_expr_no_commas (parser, NULL).value; 3734169689Skan if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 3735169689Skan label = do_case (exp1, exp2); 3736169689Skan } 3737169689Skan else 3738169689Skan c_parser_error (parser, "expected %<:%> or %<...%>"); 3739169689Skan } 3740169689Skan else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 3741169689Skan { 3742169689Skan c_parser_consume_token (parser); 3743169689Skan if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 3744169689Skan label = do_case (NULL_TREE, NULL_TREE); 3745169689Skan } 3746169689Skan else 3747169689Skan { 3748169689Skan tree name = c_parser_peek_token (parser)->value; 3749169689Skan tree tlab; 3750169689Skan location_t loc2; 3751169689Skan tree attrs; 3752169689Skan gcc_assert (c_parser_next_token_is (parser, CPP_NAME)); 3753169689Skan c_parser_consume_token (parser); 3754169689Skan gcc_assert (c_parser_next_token_is (parser, CPP_COLON)); 3755169689Skan loc2 = c_parser_peek_token (parser)->location; 3756169689Skan c_parser_consume_token (parser); 3757169689Skan attrs = c_parser_attributes (parser); 3758169689Skan tlab = define_label (loc2, name); 3759169689Skan if (tlab) 3760169689Skan { 3761169689Skan decl_attributes (&tlab, attrs, 0); 3762169689Skan label = add_stmt (build_stmt (LABEL_EXPR, tlab)); 3763169689Skan } 3764169689Skan } 3765169689Skan if (label) 3766169689Skan SET_EXPR_LOCATION (label, loc1); 3767169689Skan} 3768169689Skan 3769169689Skan/* Parse a statement (C90 6.6, C99 6.8). 3770169689Skan 3771169689Skan statement: 3772169689Skan labeled-statement 3773169689Skan compound-statement 3774169689Skan expression-statement 3775169689Skan selection-statement 3776169689Skan iteration-statement 3777169689Skan jump-statement 3778169689Skan 3779169689Skan labeled-statement: 3780169689Skan label statement 3781169689Skan 3782169689Skan expression-statement: 3783169689Skan expression[opt] ; 3784169689Skan 3785169689Skan selection-statement: 3786169689Skan if-statement 3787169689Skan switch-statement 3788169689Skan 3789169689Skan iteration-statement: 3790169689Skan while-statement 3791169689Skan do-statement 3792169689Skan for-statement 3793169689Skan 3794169689Skan jump-statement: 3795169689Skan goto identifier ; 3796169689Skan continue ; 3797169689Skan break ; 3798169689Skan return expression[opt] ; 3799169689Skan 3800169689Skan GNU extensions: 3801169689Skan 3802169689Skan statement: 3803169689Skan asm-statement 3804169689Skan 3805169689Skan jump-statement: 3806169689Skan goto * expression ; 3807169689Skan 3808169689Skan Objective-C: 3809169689Skan 3810169689Skan statement: 3811169689Skan objc-throw-statement 3812169689Skan objc-try-catch-statement 3813169689Skan objc-synchronized-statement 3814169689Skan 3815169689Skan objc-throw-statement: 3816169689Skan @throw expression ; 3817169689Skan @throw ; 3818169689Skan 3819169689Skan OpenMP: 3820169689Skan 3821169689Skan statement: 3822169689Skan openmp-construct 3823169689Skan 3824169689Skan openmp-construct: 3825169689Skan parallel-construct 3826169689Skan for-construct 3827169689Skan sections-construct 3828169689Skan single-construct 3829169689Skan parallel-for-construct 3830169689Skan parallel-sections-construct 3831169689Skan master-construct 3832169689Skan critical-construct 3833169689Skan atomic-construct 3834169689Skan ordered-construct 3835169689Skan 3836169689Skan parallel-construct: 3837169689Skan parallel-directive structured-block 3838169689Skan 3839169689Skan for-construct: 3840169689Skan for-directive iteration-statement 3841169689Skan 3842169689Skan sections-construct: 3843169689Skan sections-directive section-scope 3844169689Skan 3845169689Skan single-construct: 3846169689Skan single-directive structured-block 3847169689Skan 3848169689Skan parallel-for-construct: 3849169689Skan parallel-for-directive iteration-statement 3850169689Skan 3851169689Skan parallel-sections-construct: 3852169689Skan parallel-sections-directive section-scope 3853169689Skan 3854169689Skan master-construct: 3855169689Skan master-directive structured-block 3856169689Skan 3857169689Skan critical-construct: 3858169689Skan critical-directive structured-block 3859169689Skan 3860169689Skan atomic-construct: 3861169689Skan atomic-directive expression-statement 3862169689Skan 3863169689Skan ordered-construct: 3864169689Skan ordered-directive structured-block */ 3865169689Skan 3866169689Skanstatic void 3867169689Skanc_parser_statement (c_parser *parser) 3868169689Skan{ 3869169689Skan while (c_parser_next_token_is_keyword (parser, RID_CASE) 3870169689Skan || c_parser_next_token_is_keyword (parser, RID_DEFAULT) 3871169689Skan || (c_parser_next_token_is (parser, CPP_NAME) 3872169689Skan && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) 3873169689Skan c_parser_label (parser); 3874169689Skan c_parser_statement_after_labels (parser); 3875169689Skan} 3876169689Skan 3877169689Skan/* Parse a statement, other than a labeled statement. */ 3878169689Skan 3879169689Skanstatic void 3880169689Skanc_parser_statement_after_labels (c_parser *parser) 3881169689Skan{ 3882169689Skan location_t loc = c_parser_peek_token (parser)->location; 3883169689Skan tree stmt = NULL_TREE; 3884169689Skan switch (c_parser_peek_token (parser)->type) 3885169689Skan { 3886169689Skan case CPP_OPEN_BRACE: 3887169689Skan add_stmt (c_parser_compound_statement (parser)); 3888169689Skan break; 3889169689Skan case CPP_KEYWORD: 3890169689Skan switch (c_parser_peek_token (parser)->keyword) 3891169689Skan { 3892169689Skan case RID_IF: 3893169689Skan c_parser_if_statement (parser); 3894169689Skan break; 3895169689Skan case RID_SWITCH: 3896169689Skan c_parser_switch_statement (parser); 3897169689Skan break; 3898169689Skan case RID_WHILE: 3899169689Skan c_parser_while_statement (parser); 3900169689Skan break; 3901169689Skan case RID_DO: 3902169689Skan c_parser_do_statement (parser); 3903169689Skan break; 3904169689Skan case RID_FOR: 3905169689Skan c_parser_for_statement (parser); 3906169689Skan break; 3907169689Skan case RID_GOTO: 3908260311Spfg /* APPLE LOCAL begin radar 5732232 - blocks (C++ cb) */ 3909260311Spfg if (cur_block) 3910260311Spfg error ("goto not allowed in block literal"); 3911260311Spfg /* APPLE LOCAL end radar 5732232 - blocks (C++ cb) */ 3912169689Skan c_parser_consume_token (parser); 3913169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 3914169689Skan { 3915169689Skan stmt = c_finish_goto_label (c_parser_peek_token (parser)->value); 3916169689Skan c_parser_consume_token (parser); 3917169689Skan } 3918169689Skan else if (c_parser_next_token_is (parser, CPP_MULT)) 3919169689Skan { 3920169689Skan c_parser_consume_token (parser); 3921169689Skan stmt = c_finish_goto_ptr (c_parser_expression (parser).value); 3922169689Skan } 3923169689Skan else 3924169689Skan c_parser_error (parser, "expected identifier or %<*%>"); 3925169689Skan goto expect_semicolon; 3926169689Skan case RID_CONTINUE: 3927169689Skan c_parser_consume_token (parser); 3928169689Skan stmt = c_finish_bc_stmt (&c_cont_label, false); 3929169689Skan goto expect_semicolon; 3930169689Skan case RID_BREAK: 3931169689Skan c_parser_consume_token (parser); 3932169689Skan stmt = c_finish_bc_stmt (&c_break_label, true); 3933169689Skan goto expect_semicolon; 3934169689Skan case RID_RETURN: 3935169689Skan c_parser_consume_token (parser); 3936169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 3937169689Skan { 3938169689Skan stmt = c_finish_return (NULL_TREE); 3939169689Skan c_parser_consume_token (parser); 3940169689Skan } 3941169689Skan else 3942169689Skan { 3943169689Skan stmt = c_finish_return (c_parser_expression_conv (parser).value); 3944169689Skan goto expect_semicolon; 3945169689Skan } 3946169689Skan break; 3947169689Skan case RID_ASM: 3948169689Skan stmt = c_parser_asm_statement (parser); 3949169689Skan break; 3950169689Skan case RID_AT_THROW: 3951169689Skan gcc_assert (c_dialect_objc ()); 3952169689Skan c_parser_consume_token (parser); 3953169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 3954169689Skan { 3955169689Skan stmt = objc_build_throw_stmt (NULL_TREE); 3956169689Skan c_parser_consume_token (parser); 3957169689Skan } 3958169689Skan else 3959169689Skan { 3960169689Skan stmt 3961169689Skan = objc_build_throw_stmt (c_parser_expression (parser).value); 3962169689Skan goto expect_semicolon; 3963169689Skan } 3964169689Skan break; 3965169689Skan case RID_AT_TRY: 3966169689Skan gcc_assert (c_dialect_objc ()); 3967169689Skan c_parser_objc_try_catch_statement (parser); 3968169689Skan break; 3969169689Skan case RID_AT_SYNCHRONIZED: 3970169689Skan gcc_assert (c_dialect_objc ()); 3971169689Skan c_parser_objc_synchronized_statement (parser); 3972169689Skan break; 3973169689Skan default: 3974169689Skan goto expr_stmt; 3975169689Skan } 3976169689Skan break; 3977169689Skan case CPP_SEMICOLON: 3978169689Skan c_parser_consume_token (parser); 3979169689Skan break; 3980169689Skan case CPP_CLOSE_PAREN: 3981169689Skan case CPP_CLOSE_SQUARE: 3982169689Skan /* Avoid infinite loop in error recovery: 3983169689Skan c_parser_skip_until_found stops at a closing nesting 3984169689Skan delimiter without consuming it, but here we need to consume 3985169689Skan it to proceed further. */ 3986169689Skan c_parser_error (parser, "expected statement"); 3987169689Skan c_parser_consume_token (parser); 3988169689Skan break; 3989169689Skan case CPP_PRAGMA: 3990169689Skan c_parser_pragma (parser, pragma_stmt); 3991169689Skan break; 3992169689Skan default: 3993169689Skan expr_stmt: 3994169689Skan stmt = c_finish_expr_stmt (c_parser_expression_conv (parser).value); 3995169689Skan expect_semicolon: 3996169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 3997169689Skan break; 3998169689Skan } 3999169689Skan /* Two cases cannot and do not have line numbers associated: If stmt 4000169689Skan is degenerate, such as "2;", then stmt is an INTEGER_CST, which 4001169689Skan cannot hold line numbers. But that's OK because the statement 4002169689Skan will either be changed to a MODIFY_EXPR during gimplification of 4003169689Skan the statement expr, or discarded. If stmt was compound, but 4004169689Skan without new variables, we will have skipped the creation of a 4005169689Skan BIND and will have a bare STATEMENT_LIST. But that's OK because 4006169689Skan (recursively) all of the component statements should already have 4007169689Skan line numbers assigned. ??? Can we discard no-op statements 4008169689Skan earlier? */ 4009260311Spfg /* APPLE LOCAL begin Radar 6144634 */ 4010260311Spfg /* Normal expr stmts, including modify exprs, get the location where 4011260311Spfg the statement began, i.e. 'loc'. Assignments of Blocks to Block 4012260311Spfg pointer variables get the location of the end of the Block definition, 4013260311Spfg i.e. 'input_location', which should already be set by this point. */ 4014169689Skan if (stmt && EXPR_P (stmt)) 4015260311Spfg { 4016260311Spfg if (TREE_CODE (stmt) == MODIFY_EXPR 4017260311Spfg && TREE_CODE (TREE_TYPE (TREE_OPERAND (stmt, 0))) == BLOCK_POINTER_TYPE) 4018260311Spfg SET_EXPR_LOCATION (stmt, input_location); 4019260311Spfg else 4020260311Spfg SET_EXPR_LOCATION (stmt, loc); 4021260311Spfg } 4022260311Spfg /* APPLE LOCAL end Radar 6144634 */ 4023169689Skan} 4024169689Skan 4025169689Skan/* Parse a parenthesized condition from an if, do or while statement. 4026169689Skan 4027169689Skan condition: 4028169689Skan ( expression ) 4029169689Skan*/ 4030169689Skanstatic tree 4031169689Skanc_parser_paren_condition (c_parser *parser) 4032169689Skan{ 4033169689Skan location_t loc; 4034169689Skan tree cond; 4035169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4036169689Skan return error_mark_node; 4037169689Skan loc = c_parser_peek_token (parser)->location; 4038169689Skan cond = c_objc_common_truthvalue_conversion 4039169689Skan (c_parser_expression_conv (parser).value); 4040169689Skan if (EXPR_P (cond)) 4041169689Skan SET_EXPR_LOCATION (cond, loc); 4042169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 4043169689Skan return cond; 4044169689Skan} 4045169689Skan 4046169689Skan/* Parse a statement which is a block in C99. */ 4047169689Skan 4048169689Skanstatic tree 4049169689Skanc_parser_c99_block_statement (c_parser *parser) 4050169689Skan{ 4051169689Skan tree block = c_begin_compound_stmt (flag_isoc99); 4052169689Skan c_parser_statement (parser); 4053169689Skan return c_end_compound_stmt (block, flag_isoc99); 4054169689Skan} 4055169689Skan 4056169689Skan/* Parse the body of an if statement or the else half thereof. This 4057169689Skan is just parsing a statement but (a) it is a block in C99, (b) we 4058169689Skan track whether the body is an if statement for the sake of 4059169689Skan -Wparentheses warnings, (c) we handle an empty body specially for 4060169689Skan the sake of -Wextra warnings. */ 4061169689Skan 4062169689Skanstatic tree 4063169689Skanc_parser_if_body (c_parser *parser, bool *if_p) 4064169689Skan{ 4065169689Skan tree block = c_begin_compound_stmt (flag_isoc99); 4066169689Skan while (c_parser_next_token_is_keyword (parser, RID_CASE) 4067169689Skan || c_parser_next_token_is_keyword (parser, RID_DEFAULT) 4068169689Skan || (c_parser_next_token_is (parser, CPP_NAME) 4069169689Skan && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) 4070169689Skan c_parser_label (parser); 4071169689Skan *if_p = c_parser_next_token_is_keyword (parser, RID_IF); 4072169689Skan if (extra_warnings && c_parser_next_token_is (parser, CPP_SEMICOLON)) 4073169689Skan add_stmt (build_empty_stmt ()); 4074169689Skan c_parser_statement_after_labels (parser); 4075169689Skan return c_end_compound_stmt (block, flag_isoc99); 4076169689Skan} 4077169689Skan 4078169689Skan/* Parse an if statement (C90 6.6.4, C99 6.8.4). 4079169689Skan 4080169689Skan if-statement: 4081169689Skan if ( expression ) statement 4082169689Skan if ( expression ) statement else statement 4083169689Skan*/ 4084169689Skan 4085169689Skanstatic void 4086169689Skanc_parser_if_statement (c_parser *parser) 4087169689Skan{ 4088169689Skan tree block; 4089169689Skan location_t loc; 4090169689Skan tree cond; 4091169689Skan bool first_if = false, second_if = false; 4092169689Skan tree first_body, second_body; 4093169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF)); 4094169689Skan c_parser_consume_token (parser); 4095169689Skan block = c_begin_compound_stmt (flag_isoc99); 4096169689Skan loc = c_parser_peek_token (parser)->location; 4097169689Skan cond = c_parser_paren_condition (parser); 4098169689Skan first_body = c_parser_if_body (parser, &first_if); 4099169689Skan if (c_parser_next_token_is_keyword (parser, RID_ELSE)) 4100169689Skan { 4101169689Skan c_parser_consume_token (parser); 4102169689Skan second_body = c_parser_if_body (parser, &second_if); 4103169689Skan } 4104169689Skan else 4105169689Skan second_body = NULL_TREE; 4106169689Skan c_finish_if_stmt (loc, cond, first_body, second_body, first_if); 4107169689Skan add_stmt (c_end_compound_stmt (block, flag_isoc99)); 4108169689Skan} 4109169689Skan 4110169689Skan/* Parse a switch statement (C90 6.6.4, C99 6.8.4). 4111169689Skan 4112169689Skan switch-statement: 4113169689Skan switch (expression) statement 4114169689Skan*/ 4115169689Skan 4116169689Skanstatic void 4117169689Skanc_parser_switch_statement (c_parser *parser) 4118169689Skan{ 4119169689Skan tree block, expr, body, save_break; 4120169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH)); 4121169689Skan c_parser_consume_token (parser); 4122169689Skan block = c_begin_compound_stmt (flag_isoc99); 4123169689Skan if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4124169689Skan { 4125169689Skan expr = c_parser_expression (parser).value; 4126169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 4127169689Skan } 4128169689Skan else 4129169689Skan expr = error_mark_node; 4130169689Skan c_start_case (expr); 4131169689Skan save_break = c_break_label; 4132169689Skan c_break_label = NULL_TREE; 4133169689Skan body = c_parser_c99_block_statement (parser); 4134169689Skan c_finish_case (body); 4135169689Skan if (c_break_label) 4136169689Skan add_stmt (build1 (LABEL_EXPR, void_type_node, c_break_label)); 4137169689Skan c_break_label = save_break; 4138169689Skan add_stmt (c_end_compound_stmt (block, flag_isoc99)); 4139169689Skan} 4140169689Skan 4141169689Skan/* Parse a while statement (C90 6.6.5, C99 6.8.5). 4142169689Skan 4143169689Skan while-statement: 4144260014Spfg APPLE LOCAL begin for-fsf-4_4 3274130 5295549 4145260014Spfg while attributes (expression) statement 4146260014Spfg 4147260014Spfg The use of attributes is a GNU extension. 4148260014Spfg APPLE LOCAL end for-fsf-4_4 3274130 5295549 4149169689Skan*/ 4150169689Skan 4151169689Skanstatic void 4152169689Skanc_parser_while_statement (c_parser *parser) 4153169689Skan{ 4154260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4155260014Spfg tree block, cond, body, save_break, save_cont, attrs; 4156260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4157169689Skan location_t loc; 4158169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE)); 4159169689Skan c_parser_consume_token (parser); 4160260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4161260014Spfg attrs = c_parser_attributes (parser); 4162260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4163169689Skan block = c_begin_compound_stmt (flag_isoc99); 4164169689Skan loc = c_parser_peek_token (parser)->location; 4165169689Skan cond = c_parser_paren_condition (parser); 4166169689Skan save_break = c_break_label; 4167169689Skan c_break_label = NULL_TREE; 4168169689Skan save_cont = c_cont_label; 4169169689Skan c_cont_label = NULL_TREE; 4170169689Skan body = c_parser_c99_block_statement (parser); 4171260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4172260014Spfg c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, attrs, 4173260014Spfg true); 4174260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4175169689Skan add_stmt (c_end_compound_stmt (block, flag_isoc99)); 4176169689Skan c_break_label = save_break; 4177169689Skan c_cont_label = save_cont; 4178169689Skan} 4179169689Skan 4180169689Skan/* Parse a do statement (C90 6.6.5, C99 6.8.5). 4181169689Skan 4182169689Skan do-statement: 4183260014Spfg APPLE LOCAL begin for-fsf-4_4 3274130 5295549 4184260014Spfg do attributes statement while ( expression ) ; 4185260014Spfg 4186260014Spfg The use of attributes is a GNU extension. 4187260014Spfg APPLE LOCAL end for-fsf-4_4 3274130 5295549 4188169689Skan*/ 4189169689Skan 4190169689Skanstatic void 4191169689Skanc_parser_do_statement (c_parser *parser) 4192169689Skan{ 4193260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4194260014Spfg tree block, cond, body, save_break, save_cont, new_break, new_cont, attrs; 4195260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4196169689Skan location_t loc; 4197169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO)); 4198169689Skan c_parser_consume_token (parser); 4199260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4200260014Spfg attrs = c_parser_attributes (parser); 4201260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4202169689Skan block = c_begin_compound_stmt (flag_isoc99); 4203169689Skan loc = c_parser_peek_token (parser)->location; 4204169689Skan save_break = c_break_label; 4205169689Skan c_break_label = NULL_TREE; 4206169689Skan save_cont = c_cont_label; 4207169689Skan c_cont_label = NULL_TREE; 4208169689Skan body = c_parser_c99_block_statement (parser); 4209169689Skan c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>"); 4210169689Skan new_break = c_break_label; 4211169689Skan c_break_label = save_break; 4212169689Skan new_cont = c_cont_label; 4213169689Skan c_cont_label = save_cont; 4214169689Skan cond = c_parser_paren_condition (parser); 4215169689Skan if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 4216169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 4217260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4218260014Spfg c_finish_loop (loc, cond, NULL, body, new_break, new_cont, attrs, false); 4219260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4220169689Skan add_stmt (c_end_compound_stmt (block, flag_isoc99)); 4221169689Skan} 4222169689Skan 4223169689Skan/* Parse a for statement (C90 6.6.5, C99 6.8.5). 4224169689Skan 4225169689Skan for-statement: 4226260014Spfg APPLE LOCAL begin for-fsf-4_4 3274130 5295549 4227260014Spfg for attributes ( expression[opt] ; expression[opt] ; expression[opt] ) \ 4228260014Spfg statement 4229260014Spfg for attributes ( nested-declaration expression[opt] ; expression[opt] ) \ 4230260014Spfg statement 4231169689Skan 4232169689Skan The form with a declaration is new in C99. 4233169689Skan 4234260014Spfg The use of attributes is a GNU extension. 4235260014Spfg 4236260014Spfg APPLE LOCAL end for-fsf-4_4 3274130 5295549 4237169689Skan ??? In accordance with the old parser, the declaration may be a 4238169689Skan nested function, which is then rejected in check_for_loop_decls, 4239169689Skan but does it make any sense for this to be included in the grammar? 4240169689Skan Note in particular that the nested function does not include a 4241169689Skan trailing ';', whereas the "declaration" production includes one. 4242169689Skan Also, can we reject bad declarations earlier and cheaper than 4243169689Skan check_for_loop_decls? */ 4244169689Skan 4245169689Skanstatic void 4246169689Skanc_parser_for_statement (c_parser *parser) 4247169689Skan{ 4248260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4249260014Spfg tree block, cond, incr, save_break, save_cont, body, attrs; 4250260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4251169689Skan location_t loc; 4252260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 4253260311Spfg bool foreach_p = false; 4254169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR)); 4255169689Skan loc = c_parser_peek_token (parser)->location; 4256169689Skan c_parser_consume_token (parser); 4257260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4258260014Spfg attrs = c_parser_attributes (parser); 4259260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4260169689Skan block = c_begin_compound_stmt (flag_isoc99); 4261169689Skan if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4262169689Skan { 4263169689Skan /* Parse the initialization declaration or expression. */ 4264169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 4265169689Skan { 4266169689Skan c_parser_consume_token (parser); 4267169689Skan c_finish_expr_stmt (NULL_TREE); 4268169689Skan } 4269169689Skan else if (c_parser_next_token_starts_declspecs (parser)) 4270169689Skan { 4271260311Spfg /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */ 4272260311Spfg cond = NULL_TREE; 4273260311Spfg c_parser_declaration_or_fndef (parser, true, true, true, true, &cond); 4274260311Spfg /* APPLE LOCAL radar 5925639 */ 4275260311Spfg if (c_parser_next_token_is_keyword (parser, RID_IN) && cond) 4276260311Spfg { 4277260311Spfg cond = finish_parse_foreach_header (parser, cond); 4278260311Spfg foreach_p = true; 4279260311Spfg } 4280260311Spfg else 4281260311Spfg check_for_loop_decls (); 4282260311Spfg /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */ 4283169689Skan } 4284169689Skan else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 4285169689Skan { 4286169689Skan /* __extension__ can start a declaration, but is also an 4287169689Skan unary operator that can start an expression. Consume all 4288169689Skan but the last of a possible series of __extension__ to 4289169689Skan determine which. */ 4290169689Skan while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD 4291169689Skan && (c_parser_peek_2nd_token (parser)->keyword 4292169689Skan == RID_EXTENSION)) 4293169689Skan c_parser_consume_token (parser); 4294169689Skan if (c_token_starts_declspecs (c_parser_peek_2nd_token (parser))) 4295169689Skan { 4296169689Skan int ext; 4297169689Skan ext = disable_extension_diagnostics (); 4298169689Skan c_parser_consume_token (parser); 4299260311Spfg /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */ 4300260311Spfg cond = NULL_TREE; 4301260311Spfg c_parser_declaration_or_fndef (parser, true, true, true, true, &cond); 4302169689Skan restore_extension_diagnostics (ext); 4303260311Spfg /* APPLE LOCAL radar 5925639 */ 4304260311Spfg if (c_parser_next_token_is_keyword (parser, RID_IN) && cond) 4305260311Spfg { 4306260311Spfg cond = finish_parse_foreach_header (parser, cond); 4307260311Spfg foreach_p = true; 4308260311Spfg } 4309260311Spfg else 4310260311Spfg check_for_loop_decls (); 4311260311Spfg /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */ 4312169689Skan } 4313169689Skan else 4314169689Skan goto init_expr; 4315169689Skan } 4316169689Skan else 4317169689Skan { 4318169689Skan init_expr: 4319260311Spfg /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */ 4320260311Spfg cond = c_parser_expression (parser).value; 4321260311Spfg if (c_parser_next_token_is_keyword (parser, RID_IN)) 4322260311Spfg { 4323260311Spfg c_parser_consume_token (parser); /* IN */ 4324260311Spfg cond = build_tree_list (cond, c_parser_initializer (parser).value); 4325260311Spfg foreach_p = true; 4326260311Spfg } 4327260311Spfg else 4328260311Spfg { 4329260311Spfg c_finish_expr_stmt (cond); 4330260311Spfg c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 4331260311Spfg } 4332169689Skan } 4333260311Spfg objc_foreach_context = 0; 4334260311Spfg /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */ 4335169689Skan /* Parse the loop condition. */ 4336169689Skan loc = c_parser_peek_token (parser)->location; 4337169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 4338169689Skan { 4339169689Skan c_parser_consume_token (parser); 4340169689Skan cond = NULL_TREE; 4341169689Skan } 4342260311Spfg /* APPLE LOCAL begin radar 4708210 (for_objc_collection in 4.2) */ 4343260311Spfg else if (foreach_p) 4344260311Spfg ; 4345260311Spfg /* APPLE LOCAL end radar 4708210 (for_objc_collection in 4.2) */ 4346169689Skan else 4347169689Skan { 4348169689Skan tree ocond = c_parser_expression_conv (parser).value; 4349169689Skan cond = c_objc_common_truthvalue_conversion (ocond); 4350169689Skan if (EXPR_P (cond)) 4351169689Skan SET_EXPR_LOCATION (cond, loc); 4352169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 4353169689Skan } 4354169689Skan /* Parse the increment expression. */ 4355169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4356169689Skan incr = c_process_expr_stmt (NULL_TREE); 4357169689Skan else 4358169689Skan incr = c_process_expr_stmt (c_parser_expression (parser).value); 4359169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 4360169689Skan } 4361169689Skan else 4362169689Skan { 4363169689Skan cond = error_mark_node; 4364169689Skan incr = error_mark_node; 4365169689Skan } 4366169689Skan save_break = c_break_label; 4367169689Skan c_break_label = NULL_TREE; 4368169689Skan save_cont = c_cont_label; 4369169689Skan c_cont_label = NULL_TREE; 4370169689Skan body = c_parser_c99_block_statement (parser); 4371260014Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 4372260014Spfg c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, attrs, 4373260014Spfg true); 4374260014Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 4375169689Skan add_stmt (c_end_compound_stmt (block, flag_isoc99)); 4376169689Skan c_break_label = save_break; 4377169689Skan c_cont_label = save_cont; 4378169689Skan} 4379169689Skan 4380169689Skan/* Parse an asm statement, a GNU extension. This is a full-blown asm 4381169689Skan statement with inputs, outputs, clobbers, and volatile tag 4382169689Skan allowed. 4383169689Skan 4384169689Skan asm-statement: 4385169689Skan asm type-qualifier[opt] ( asm-argument ) ; 4386169689Skan 4387169689Skan asm-argument: 4388169689Skan asm-string-literal 4389169689Skan asm-string-literal : asm-operands[opt] 4390169689Skan asm-string-literal : asm-operands[opt] : asm-operands[opt] 4391169689Skan asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers 4392169689Skan 4393169689Skan Qualifiers other than volatile are accepted in the syntax but 4394169689Skan warned for. */ 4395169689Skan 4396169689Skanstatic tree 4397169689Skanc_parser_asm_statement (c_parser *parser) 4398169689Skan{ 4399169689Skan tree quals, str, outputs, inputs, clobbers, ret; 4400169689Skan bool simple; 4401169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM)); 4402169689Skan c_parser_consume_token (parser); 4403169689Skan if (c_parser_next_token_is_keyword (parser, RID_VOLATILE)) 4404169689Skan { 4405169689Skan quals = c_parser_peek_token (parser)->value; 4406169689Skan c_parser_consume_token (parser); 4407169689Skan } 4408169689Skan else if (c_parser_next_token_is_keyword (parser, RID_CONST) 4409169689Skan || c_parser_next_token_is_keyword (parser, RID_RESTRICT)) 4410169689Skan { 4411169689Skan warning (0, "%E qualifier ignored on asm", 4412169689Skan c_parser_peek_token (parser)->value); 4413169689Skan quals = NULL_TREE; 4414169689Skan c_parser_consume_token (parser); 4415169689Skan } 4416169689Skan else 4417169689Skan quals = NULL_TREE; 4418169689Skan /* ??? Follow the C++ parser rather than using the 4419169689Skan c_lex_string_translate kludge. */ 4420169689Skan c_lex_string_translate = 0; 4421169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4422169689Skan { 4423169689Skan c_lex_string_translate = 1; 4424169689Skan return NULL_TREE; 4425169689Skan } 4426169689Skan str = c_parser_asm_string_literal (parser); 4427169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4428169689Skan { 4429169689Skan simple = true; 4430169689Skan outputs = NULL_TREE; 4431169689Skan inputs = NULL_TREE; 4432169689Skan clobbers = NULL_TREE; 4433169689Skan goto done_asm; 4434169689Skan } 4435169689Skan if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>")) 4436169689Skan { 4437169689Skan c_lex_string_translate = 1; 4438169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4439169689Skan return NULL_TREE; 4440169689Skan } 4441169689Skan simple = false; 4442169689Skan /* Parse outputs. */ 4443169689Skan if (c_parser_next_token_is (parser, CPP_COLON) 4444169689Skan || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4445169689Skan outputs = NULL_TREE; 4446169689Skan else 4447169689Skan outputs = c_parser_asm_operands (parser, false); 4448169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4449169689Skan { 4450169689Skan inputs = NULL_TREE; 4451169689Skan clobbers = NULL_TREE; 4452169689Skan goto done_asm; 4453169689Skan } 4454169689Skan if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>")) 4455169689Skan { 4456169689Skan c_lex_string_translate = 1; 4457169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4458169689Skan return NULL_TREE; 4459169689Skan } 4460169689Skan /* Parse inputs. */ 4461169689Skan if (c_parser_next_token_is (parser, CPP_COLON) 4462169689Skan || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4463169689Skan inputs = NULL_TREE; 4464169689Skan else 4465169689Skan inputs = c_parser_asm_operands (parser, true); 4466169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4467169689Skan { 4468169689Skan clobbers = NULL_TREE; 4469169689Skan goto done_asm; 4470169689Skan } 4471169689Skan if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>")) 4472169689Skan { 4473169689Skan c_lex_string_translate = 1; 4474169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4475169689Skan return NULL_TREE; 4476169689Skan } 4477169689Skan /* Parse clobbers. */ 4478169689Skan clobbers = c_parser_asm_clobbers (parser); 4479169689Skan done_asm: 4480169689Skan c_lex_string_translate = 1; 4481169689Skan if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 4482169689Skan { 4483169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4484169689Skan return NULL_TREE; 4485169689Skan } 4486169689Skan if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 4487169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 4488169689Skan ret = build_asm_stmt (quals, build_asm_expr (str, outputs, inputs, 4489169689Skan clobbers, simple)); 4490169689Skan return ret; 4491169689Skan} 4492169689Skan 4493169689Skan/* Parse asm operands, a GNU extension. If CONVERT_P (for inputs but 4494169689Skan not outputs), apply the default conversion of functions and arrays 4495169689Skan to pointers. 4496169689Skan 4497169689Skan asm-operands: 4498169689Skan asm-operand 4499169689Skan asm-operands , asm-operand 4500169689Skan 4501169689Skan asm-operand: 4502169689Skan asm-string-literal ( expression ) 4503169689Skan [ identifier ] asm-string-literal ( expression ) 4504169689Skan*/ 4505169689Skan 4506169689Skanstatic tree 4507169689Skanc_parser_asm_operands (c_parser *parser, bool convert_p) 4508169689Skan{ 4509169689Skan tree list = NULL_TREE; 4510169689Skan while (true) 4511169689Skan { 4512169689Skan tree name, str; 4513169689Skan struct c_expr expr; 4514169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 4515169689Skan { 4516169689Skan c_parser_consume_token (parser); 4517169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 4518169689Skan { 4519169689Skan tree id = c_parser_peek_token (parser)->value; 4520169689Skan c_parser_consume_token (parser); 4521169689Skan name = build_string (IDENTIFIER_LENGTH (id), 4522169689Skan IDENTIFIER_POINTER (id)); 4523169689Skan } 4524169689Skan else 4525169689Skan { 4526169689Skan c_parser_error (parser, "expected identifier"); 4527169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); 4528169689Skan return NULL_TREE; 4529169689Skan } 4530169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 4531169689Skan "expected %<]%>"); 4532169689Skan } 4533169689Skan else 4534169689Skan name = NULL_TREE; 4535169689Skan str = c_parser_asm_string_literal (parser); 4536169689Skan if (str == NULL_TREE) 4537169689Skan return NULL_TREE; 4538169689Skan c_lex_string_translate = 1; 4539169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4540169689Skan { 4541169689Skan c_lex_string_translate = 0; 4542169689Skan return NULL_TREE; 4543169689Skan } 4544169689Skan expr = c_parser_expression (parser); 4545169689Skan if (convert_p) 4546169689Skan expr = default_function_array_conversion (expr); 4547169689Skan c_lex_string_translate = 0; 4548169689Skan if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 4549169689Skan { 4550169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4551169689Skan return NULL_TREE; 4552169689Skan } 4553169689Skan list = chainon (list, build_tree_list (build_tree_list (name, str), 4554169689Skan expr.value)); 4555169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 4556169689Skan c_parser_consume_token (parser); 4557169689Skan else 4558169689Skan break; 4559169689Skan } 4560169689Skan return list; 4561169689Skan} 4562169689Skan 4563169689Skan/* Parse asm clobbers, a GNU extension. 4564169689Skan 4565169689Skan asm-clobbers: 4566169689Skan asm-string-literal 4567169689Skan asm-clobbers , asm-string-literal 4568169689Skan*/ 4569169689Skan 4570169689Skanstatic tree 4571169689Skanc_parser_asm_clobbers (c_parser *parser) 4572169689Skan{ 4573169689Skan tree list = NULL_TREE; 4574169689Skan while (true) 4575169689Skan { 4576169689Skan tree str = c_parser_asm_string_literal (parser); 4577169689Skan if (str) 4578169689Skan list = tree_cons (NULL_TREE, str, list); 4579169689Skan else 4580169689Skan return NULL_TREE; 4581169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 4582169689Skan c_parser_consume_token (parser); 4583169689Skan else 4584169689Skan break; 4585169689Skan } 4586169689Skan return list; 4587169689Skan} 4588169689Skan 4589169689Skan/* Parse an expression other than a compound expression; that is, an 4590169689Skan assignment expression (C90 6.3.16, C99 6.5.16). If AFTER is not 4591169689Skan NULL then it is an Objective-C message expression which is the 4592169689Skan primary-expression starting the expression as an initializer. 4593169689Skan 4594169689Skan assignment-expression: 4595169689Skan conditional-expression 4596169689Skan unary-expression assignment-operator assignment-expression 4597169689Skan 4598169689Skan assignment-operator: one of 4599169689Skan = *= /= %= += -= <<= >>= &= ^= |= 4600169689Skan 4601169689Skan In GNU C we accept any conditional expression on the LHS and 4602169689Skan diagnose the invalid lvalue rather than producing a syntax 4603169689Skan error. */ 4604169689Skan 4605169689Skanstatic struct c_expr 4606169689Skanc_parser_expr_no_commas (c_parser *parser, struct c_expr *after) 4607169689Skan{ 4608169689Skan struct c_expr lhs, rhs, ret; 4609169689Skan enum tree_code code; 4610169689Skan gcc_assert (!after || c_dialect_objc ()); 4611169689Skan lhs = c_parser_conditional_expression (parser, after); 4612169689Skan switch (c_parser_peek_token (parser)->type) 4613169689Skan { 4614169689Skan case CPP_EQ: 4615169689Skan code = NOP_EXPR; 4616169689Skan break; 4617169689Skan case CPP_MULT_EQ: 4618169689Skan code = MULT_EXPR; 4619169689Skan break; 4620169689Skan case CPP_DIV_EQ: 4621169689Skan code = TRUNC_DIV_EXPR; 4622169689Skan break; 4623169689Skan case CPP_MOD_EQ: 4624169689Skan code = TRUNC_MOD_EXPR; 4625169689Skan break; 4626169689Skan case CPP_PLUS_EQ: 4627169689Skan code = PLUS_EXPR; 4628169689Skan break; 4629169689Skan case CPP_MINUS_EQ: 4630169689Skan code = MINUS_EXPR; 4631169689Skan break; 4632169689Skan case CPP_LSHIFT_EQ: 4633169689Skan code = LSHIFT_EXPR; 4634169689Skan break; 4635169689Skan case CPP_RSHIFT_EQ: 4636169689Skan code = RSHIFT_EXPR; 4637169689Skan break; 4638169689Skan case CPP_AND_EQ: 4639169689Skan code = BIT_AND_EXPR; 4640169689Skan break; 4641169689Skan case CPP_XOR_EQ: 4642169689Skan code = BIT_XOR_EXPR; 4643169689Skan break; 4644169689Skan case CPP_OR_EQ: 4645169689Skan code = BIT_IOR_EXPR; 4646169689Skan break; 4647169689Skan default: 4648169689Skan return lhs; 4649169689Skan } 4650169689Skan c_parser_consume_token (parser); 4651169689Skan rhs = c_parser_expr_no_commas (parser, NULL); 4652169689Skan rhs = default_function_array_conversion (rhs); 4653169689Skan ret.value = build_modify_expr (lhs.value, code, rhs.value); 4654169689Skan if (code == NOP_EXPR) 4655169689Skan ret.original_code = MODIFY_EXPR; 4656169689Skan else 4657169689Skan { 4658169689Skan TREE_NO_WARNING (ret.value) = 1; 4659169689Skan ret.original_code = ERROR_MARK; 4660169689Skan } 4661169689Skan return ret; 4662169689Skan} 4663169689Skan 4664169689Skan/* Parse a conditional expression (C90 6.3.15, C99 6.5.15). If AFTER 4665169689Skan is not NULL then it is an Objective-C message expression which is 4666169689Skan the primary-expression starting the expression as an initializer. 4667169689Skan 4668169689Skan conditional-expression: 4669169689Skan logical-OR-expression 4670169689Skan logical-OR-expression ? expression : conditional-expression 4671169689Skan 4672169689Skan GNU extensions: 4673169689Skan 4674169689Skan conditional-expression: 4675169689Skan logical-OR-expression ? : conditional-expression 4676169689Skan*/ 4677169689Skan 4678169689Skanstatic struct c_expr 4679169689Skanc_parser_conditional_expression (c_parser *parser, struct c_expr *after) 4680169689Skan{ 4681169689Skan struct c_expr cond, exp1, exp2, ret; 4682169689Skan gcc_assert (!after || c_dialect_objc ()); 4683169689Skan cond = c_parser_binary_expression (parser, after); 4684169689Skan if (c_parser_next_token_is_not (parser, CPP_QUERY)) 4685169689Skan return cond; 4686169689Skan cond = default_function_array_conversion (cond); 4687169689Skan c_parser_consume_token (parser); 4688169689Skan if (c_parser_next_token_is (parser, CPP_COLON)) 4689169689Skan { 4690169689Skan if (pedantic) 4691169689Skan pedwarn ("ISO C forbids omitting the middle term of a ?: expression"); 4692169689Skan /* Make sure first operand is calculated only once. */ 4693169689Skan exp1.value = save_expr (default_conversion (cond.value)); 4694169689Skan cond.value = c_objc_common_truthvalue_conversion (exp1.value); 4695169689Skan skip_evaluation += cond.value == truthvalue_true_node; 4696169689Skan } 4697169689Skan else 4698169689Skan { 4699169689Skan cond.value 4700169689Skan = c_objc_common_truthvalue_conversion 4701169689Skan (default_conversion (cond.value)); 4702169689Skan skip_evaluation += cond.value == truthvalue_false_node; 4703169689Skan exp1 = c_parser_expression_conv (parser); 4704169689Skan skip_evaluation += ((cond.value == truthvalue_true_node) 4705169689Skan - (cond.value == truthvalue_false_node)); 4706169689Skan } 4707169689Skan if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 4708169689Skan { 4709169689Skan skip_evaluation -= cond.value == truthvalue_true_node; 4710169689Skan ret.value = error_mark_node; 4711169689Skan ret.original_code = ERROR_MARK; 4712169689Skan return ret; 4713169689Skan } 4714169689Skan exp2 = c_parser_conditional_expression (parser, NULL); 4715169689Skan exp2 = default_function_array_conversion (exp2); 4716169689Skan skip_evaluation -= cond.value == truthvalue_true_node; 4717169689Skan ret.value = build_conditional_expr (cond.value, exp1.value, exp2.value); 4718169689Skan ret.original_code = ERROR_MARK; 4719169689Skan return ret; 4720169689Skan} 4721169689Skan 4722169689Skan/* Parse a binary expression; that is, a logical-OR-expression (C90 4723169689Skan 6.3.5-6.3.14, C99 6.5.5-6.5.14). If AFTER is not NULL then it is 4724169689Skan an Objective-C message expression which is the primary-expression 4725169689Skan starting the expression as an initializer. 4726169689Skan 4727169689Skan multiplicative-expression: 4728169689Skan cast-expression 4729169689Skan multiplicative-expression * cast-expression 4730169689Skan multiplicative-expression / cast-expression 4731169689Skan multiplicative-expression % cast-expression 4732169689Skan 4733169689Skan additive-expression: 4734169689Skan multiplicative-expression 4735169689Skan additive-expression + multiplicative-expression 4736169689Skan additive-expression - multiplicative-expression 4737169689Skan 4738169689Skan shift-expression: 4739169689Skan additive-expression 4740169689Skan shift-expression << additive-expression 4741169689Skan shift-expression >> additive-expression 4742169689Skan 4743169689Skan relational-expression: 4744169689Skan shift-expression 4745169689Skan relational-expression < shift-expression 4746169689Skan relational-expression > shift-expression 4747169689Skan relational-expression <= shift-expression 4748169689Skan relational-expression >= shift-expression 4749169689Skan 4750169689Skan equality-expression: 4751169689Skan relational-expression 4752169689Skan equality-expression == relational-expression 4753169689Skan equality-expression != relational-expression 4754169689Skan 4755169689Skan AND-expression: 4756169689Skan equality-expression 4757169689Skan AND-expression & equality-expression 4758169689Skan 4759169689Skan exclusive-OR-expression: 4760169689Skan AND-expression 4761169689Skan exclusive-OR-expression ^ AND-expression 4762169689Skan 4763169689Skan inclusive-OR-expression: 4764169689Skan exclusive-OR-expression 4765169689Skan inclusive-OR-expression | exclusive-OR-expression 4766169689Skan 4767169689Skan logical-AND-expression: 4768169689Skan inclusive-OR-expression 4769169689Skan logical-AND-expression && inclusive-OR-expression 4770169689Skan 4771169689Skan logical-OR-expression: 4772169689Skan logical-AND-expression 4773169689Skan logical-OR-expression || logical-AND-expression 4774169689Skan*/ 4775169689Skan 4776169689Skanstatic struct c_expr 4777169689Skanc_parser_binary_expression (c_parser *parser, struct c_expr *after) 4778169689Skan{ 4779169689Skan /* A binary expression is parsed using operator-precedence parsing, 4780169689Skan with the operands being cast expressions. All the binary 4781169689Skan operators are left-associative. Thus a binary expression is of 4782169689Skan form: 4783169689Skan 4784169689Skan E0 op1 E1 op2 E2 ... 4785169689Skan 4786169689Skan which we represent on a stack. On the stack, the precedence 4787169689Skan levels are strictly increasing. When a new operator is 4788169689Skan encountered of higher precedence than that at the top of the 4789169689Skan stack, it is pushed; its LHS is the top expression, and its RHS 4790169689Skan is everything parsed until it is popped. When a new operator is 4791169689Skan encountered with precedence less than or equal to that at the top 4792169689Skan of the stack, triples E[i-1] op[i] E[i] are popped and replaced 4793169689Skan by the result of the operation until the operator at the top of 4794169689Skan the stack has lower precedence than the new operator or there is 4795169689Skan only one element on the stack; then the top expression is the LHS 4796169689Skan of the new operator. In the case of logical AND and OR 4797169689Skan expressions, we also need to adjust skip_evaluation as 4798169689Skan appropriate when the operators are pushed and popped. */ 4799169689Skan 4800169689Skan /* The precedence levels, where 0 is a dummy lowest level used for 4801169689Skan the bottom of the stack. */ 4802169689Skan enum prec { 4803169689Skan PREC_NONE, 4804169689Skan PREC_LOGOR, 4805169689Skan PREC_LOGAND, 4806169689Skan PREC_BITOR, 4807169689Skan PREC_BITXOR, 4808169689Skan PREC_BITAND, 4809169689Skan PREC_EQ, 4810169689Skan PREC_REL, 4811169689Skan PREC_SHIFT, 4812169689Skan PREC_ADD, 4813169689Skan PREC_MULT, 4814169689Skan NUM_PRECS 4815169689Skan }; 4816169689Skan struct { 4817169689Skan /* The expression at this stack level. */ 4818169689Skan struct c_expr expr; 4819169689Skan /* The precedence of the operator on its left, PREC_NONE at the 4820169689Skan bottom of the stack. */ 4821169689Skan enum prec prec; 4822169689Skan /* The operation on its left. */ 4823169689Skan enum tree_code op; 4824169689Skan } stack[NUM_PRECS]; 4825169689Skan int sp; 4826169689Skan#define POP \ 4827169689Skan do { \ 4828169689Skan switch (stack[sp].op) \ 4829169689Skan { \ 4830169689Skan case TRUTH_ANDIF_EXPR: \ 4831169689Skan skip_evaluation -= stack[sp - 1].expr.value == truthvalue_false_node; \ 4832169689Skan break; \ 4833169689Skan case TRUTH_ORIF_EXPR: \ 4834169689Skan skip_evaluation -= stack[sp - 1].expr.value == truthvalue_true_node; \ 4835169689Skan break; \ 4836169689Skan default: \ 4837169689Skan break; \ 4838169689Skan } \ 4839169689Skan stack[sp - 1].expr \ 4840169689Skan = default_function_array_conversion (stack[sp - 1].expr); \ 4841169689Skan stack[sp].expr \ 4842169689Skan = default_function_array_conversion (stack[sp].expr); \ 4843169689Skan stack[sp - 1].expr = parser_build_binary_op (stack[sp].op, \ 4844169689Skan stack[sp - 1].expr, \ 4845169689Skan stack[sp].expr); \ 4846169689Skan sp--; \ 4847169689Skan } while (0) 4848169689Skan gcc_assert (!after || c_dialect_objc ()); 4849169689Skan stack[0].expr = c_parser_cast_expression (parser, after); 4850260311Spfg /* APPLE LOCAL begin radar 4426814 */ 4851260311Spfg if (c_dialect_objc() && flag_objc_gc) 4852260311Spfg /* APPLE LOCAL radar 5276085 */ 4853260311Spfg stack[0].expr.value = objc_build_weak_reference_tree (stack[0].expr.value); 4854260311Spfg /* APPLE LOCAL end radar 4426814 */ 4855169689Skan stack[0].prec = PREC_NONE; 4856169689Skan sp = 0; 4857169689Skan while (true) 4858169689Skan { 4859169689Skan enum prec oprec; 4860169689Skan enum tree_code ocode; 4861169689Skan if (parser->error) 4862169689Skan goto out; 4863169689Skan switch (c_parser_peek_token (parser)->type) 4864169689Skan { 4865169689Skan case CPP_MULT: 4866169689Skan oprec = PREC_MULT; 4867169689Skan ocode = MULT_EXPR; 4868169689Skan break; 4869169689Skan case CPP_DIV: 4870169689Skan oprec = PREC_MULT; 4871169689Skan ocode = TRUNC_DIV_EXPR; 4872169689Skan break; 4873169689Skan case CPP_MOD: 4874169689Skan oprec = PREC_MULT; 4875169689Skan ocode = TRUNC_MOD_EXPR; 4876169689Skan break; 4877169689Skan case CPP_PLUS: 4878169689Skan oprec = PREC_ADD; 4879169689Skan ocode = PLUS_EXPR; 4880169689Skan break; 4881169689Skan case CPP_MINUS: 4882169689Skan oprec = PREC_ADD; 4883169689Skan ocode = MINUS_EXPR; 4884169689Skan break; 4885169689Skan case CPP_LSHIFT: 4886169689Skan oprec = PREC_SHIFT; 4887169689Skan ocode = LSHIFT_EXPR; 4888169689Skan break; 4889169689Skan case CPP_RSHIFT: 4890169689Skan oprec = PREC_SHIFT; 4891169689Skan ocode = RSHIFT_EXPR; 4892169689Skan break; 4893169689Skan case CPP_LESS: 4894169689Skan oprec = PREC_REL; 4895169689Skan ocode = LT_EXPR; 4896169689Skan break; 4897169689Skan case CPP_GREATER: 4898169689Skan oprec = PREC_REL; 4899169689Skan ocode = GT_EXPR; 4900169689Skan break; 4901169689Skan case CPP_LESS_EQ: 4902169689Skan oprec = PREC_REL; 4903169689Skan ocode = LE_EXPR; 4904169689Skan break; 4905169689Skan case CPP_GREATER_EQ: 4906169689Skan oprec = PREC_REL; 4907169689Skan ocode = GE_EXPR; 4908169689Skan break; 4909169689Skan case CPP_EQ_EQ: 4910169689Skan oprec = PREC_EQ; 4911169689Skan ocode = EQ_EXPR; 4912169689Skan break; 4913169689Skan case CPP_NOT_EQ: 4914169689Skan oprec = PREC_EQ; 4915169689Skan ocode = NE_EXPR; 4916169689Skan break; 4917169689Skan case CPP_AND: 4918169689Skan oprec = PREC_BITAND; 4919169689Skan ocode = BIT_AND_EXPR; 4920169689Skan break; 4921169689Skan case CPP_XOR: 4922169689Skan oprec = PREC_BITXOR; 4923169689Skan ocode = BIT_XOR_EXPR; 4924169689Skan break; 4925169689Skan case CPP_OR: 4926169689Skan oprec = PREC_BITOR; 4927169689Skan ocode = BIT_IOR_EXPR; 4928169689Skan break; 4929169689Skan case CPP_AND_AND: 4930169689Skan oprec = PREC_LOGAND; 4931169689Skan ocode = TRUTH_ANDIF_EXPR; 4932169689Skan break; 4933169689Skan case CPP_OR_OR: 4934169689Skan oprec = PREC_LOGOR; 4935169689Skan ocode = TRUTH_ORIF_EXPR; 4936169689Skan break; 4937169689Skan default: 4938169689Skan /* Not a binary operator, so end of the binary 4939169689Skan expression. */ 4940169689Skan goto out; 4941169689Skan } 4942169689Skan c_parser_consume_token (parser); 4943169689Skan while (oprec <= stack[sp].prec) 4944169689Skan POP; 4945169689Skan switch (ocode) 4946169689Skan { 4947169689Skan case TRUTH_ANDIF_EXPR: 4948169689Skan stack[sp].expr 4949169689Skan = default_function_array_conversion (stack[sp].expr); 4950169689Skan stack[sp].expr.value = c_objc_common_truthvalue_conversion 4951169689Skan (default_conversion (stack[sp].expr.value)); 4952169689Skan skip_evaluation += stack[sp].expr.value == truthvalue_false_node; 4953169689Skan break; 4954169689Skan case TRUTH_ORIF_EXPR: 4955169689Skan stack[sp].expr 4956169689Skan = default_function_array_conversion (stack[sp].expr); 4957169689Skan stack[sp].expr.value = c_objc_common_truthvalue_conversion 4958169689Skan (default_conversion (stack[sp].expr.value)); 4959169689Skan skip_evaluation += stack[sp].expr.value == truthvalue_true_node; 4960169689Skan break; 4961169689Skan default: 4962169689Skan break; 4963169689Skan } 4964169689Skan sp++; 4965169689Skan stack[sp].expr = c_parser_cast_expression (parser, NULL); 4966260311Spfg /* APPLE LOCAL begin radar 4426814 */ 4967260311Spfg if (c_dialect_objc() && flag_objc_gc) 4968260311Spfg /* APPLE LOCAL radar 5276085 */ 4969260311Spfg stack[sp].expr.value = objc_build_weak_reference_tree (stack[sp].expr.value); 4970260311Spfg /* APPLE LOCAL end radar 4426814 */ 4971169689Skan stack[sp].prec = oprec; 4972169689Skan stack[sp].op = ocode; 4973169689Skan } 4974169689Skan out: 4975169689Skan while (sp > 0) 4976169689Skan POP; 4977169689Skan return stack[0].expr; 4978169689Skan#undef POP 4979169689Skan} 4980169689Skan 4981169689Skan/* Parse a cast expression (C90 6.3.4, C99 6.5.4). If AFTER is not 4982169689Skan NULL then it is an Objective-C message expression which is the 4983169689Skan primary-expression starting the expression as an initializer. 4984169689Skan 4985169689Skan cast-expression: 4986169689Skan unary-expression 4987169689Skan ( type-name ) unary-expression 4988169689Skan*/ 4989169689Skan 4990169689Skanstatic struct c_expr 4991169689Skanc_parser_cast_expression (c_parser *parser, struct c_expr *after) 4992169689Skan{ 4993169689Skan gcc_assert (!after || c_dialect_objc ()); 4994169689Skan if (after) 4995169689Skan return c_parser_postfix_expression_after_primary (parser, *after); 4996169689Skan /* If the expression begins with a parenthesized type name, it may 4997169689Skan be either a cast or a compound literal; we need to see whether 4998169689Skan the next character is '{' to tell the difference. If not, it is 4999169689Skan an unary expression. */ 5000169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 5001169689Skan && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 5002169689Skan { 5003169689Skan struct c_type_name *type_name; 5004169689Skan struct c_expr ret; 5005169689Skan struct c_expr expr; 5006169689Skan c_parser_consume_token (parser); 5007169689Skan type_name = c_parser_type_name (parser); 5008169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 5009169689Skan if (type_name == NULL) 5010169689Skan { 5011169689Skan ret.value = error_mark_node; 5012169689Skan ret.original_code = ERROR_MARK; 5013169689Skan return ret; 5014169689Skan } 5015169689Skan 5016169689Skan /* Save casted types in the function's used types hash table. */ 5017169689Skan used_types_insert (type_name->specs->type); 5018169689Skan 5019169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 5020169689Skan return c_parser_postfix_expression_after_paren_type (parser, 5021169689Skan type_name); 5022169689Skan expr = c_parser_cast_expression (parser, NULL); 5023169689Skan expr = default_function_array_conversion (expr); 5024169689Skan ret.value = c_cast_expr (type_name, expr.value); 5025169689Skan ret.original_code = ERROR_MARK; 5026169689Skan return ret; 5027169689Skan } 5028169689Skan else 5029169689Skan return c_parser_unary_expression (parser); 5030169689Skan} 5031169689Skan 5032169689Skan/* Parse an unary expression (C90 6.3.3, C99 6.5.3). 5033169689Skan 5034169689Skan unary-expression: 5035169689Skan postfix-expression 5036169689Skan ++ unary-expression 5037169689Skan -- unary-expression 5038169689Skan unary-operator cast-expression 5039169689Skan sizeof unary-expression 5040169689Skan sizeof ( type-name ) 5041169689Skan 5042169689Skan unary-operator: one of 5043169689Skan & * + - ~ ! 5044169689Skan 5045169689Skan GNU extensions: 5046169689Skan 5047169689Skan unary-expression: 5048169689Skan __alignof__ unary-expression 5049169689Skan __alignof__ ( type-name ) 5050169689Skan && identifier 5051169689Skan 5052169689Skan unary-operator: one of 5053169689Skan __extension__ __real__ __imag__ 5054169689Skan 5055169689Skan In addition, the GNU syntax treats ++ and -- as unary operators, so 5056169689Skan they may be applied to cast expressions with errors for non-lvalues 5057169689Skan given later. */ 5058169689Skan 5059169689Skanstatic struct c_expr 5060169689Skanc_parser_unary_expression (c_parser *parser) 5061169689Skan{ 5062169689Skan int ext; 5063169689Skan struct c_expr ret, op; 5064169689Skan switch (c_parser_peek_token (parser)->type) 5065169689Skan { 5066169689Skan case CPP_PLUS_PLUS: 5067169689Skan c_parser_consume_token (parser); 5068169689Skan op = c_parser_cast_expression (parser, NULL); 5069169689Skan op = default_function_array_conversion (op); 5070169689Skan return parser_build_unary_op (PREINCREMENT_EXPR, op); 5071169689Skan case CPP_MINUS_MINUS: 5072169689Skan c_parser_consume_token (parser); 5073169689Skan op = c_parser_cast_expression (parser, NULL); 5074169689Skan op = default_function_array_conversion (op); 5075169689Skan return parser_build_unary_op (PREDECREMENT_EXPR, op); 5076169689Skan case CPP_AND: 5077169689Skan c_parser_consume_token (parser); 5078169689Skan return parser_build_unary_op (ADDR_EXPR, 5079169689Skan c_parser_cast_expression (parser, NULL)); 5080169689Skan case CPP_MULT: 5081169689Skan c_parser_consume_token (parser); 5082169689Skan op = c_parser_cast_expression (parser, NULL); 5083169689Skan op = default_function_array_conversion (op); 5084169689Skan ret.value = build_indirect_ref (op.value, "unary *"); 5085169689Skan ret.original_code = ERROR_MARK; 5086169689Skan return ret; 5087169689Skan case CPP_PLUS: 5088169689Skan c_parser_consume_token (parser); 5089169689Skan if (!c_dialect_objc () && !in_system_header) 5090169689Skan warning (OPT_Wtraditional, 5091169689Skan "traditional C rejects the unary plus operator"); 5092169689Skan op = c_parser_cast_expression (parser, NULL); 5093169689Skan op = default_function_array_conversion (op); 5094169689Skan return parser_build_unary_op (CONVERT_EXPR, op); 5095169689Skan case CPP_MINUS: 5096169689Skan c_parser_consume_token (parser); 5097169689Skan op = c_parser_cast_expression (parser, NULL); 5098169689Skan op = default_function_array_conversion (op); 5099169689Skan return parser_build_unary_op (NEGATE_EXPR, op); 5100169689Skan case CPP_COMPL: 5101169689Skan c_parser_consume_token (parser); 5102169689Skan op = c_parser_cast_expression (parser, NULL); 5103169689Skan op = default_function_array_conversion (op); 5104169689Skan return parser_build_unary_op (BIT_NOT_EXPR, op); 5105169689Skan case CPP_NOT: 5106169689Skan c_parser_consume_token (parser); 5107169689Skan op = c_parser_cast_expression (parser, NULL); 5108169689Skan op = default_function_array_conversion (op); 5109169689Skan return parser_build_unary_op (TRUTH_NOT_EXPR, op); 5110169689Skan case CPP_AND_AND: 5111169689Skan /* Refer to the address of a label as a pointer. */ 5112169689Skan c_parser_consume_token (parser); 5113169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 5114169689Skan { 5115169689Skan ret.value = finish_label_address_expr 5116169689Skan (c_parser_peek_token (parser)->value); 5117169689Skan c_parser_consume_token (parser); 5118169689Skan } 5119169689Skan else 5120169689Skan { 5121169689Skan c_parser_error (parser, "expected identifier"); 5122169689Skan ret.value = error_mark_node; 5123169689Skan } 5124169689Skan ret.original_code = ERROR_MARK; 5125169689Skan return ret; 5126169689Skan case CPP_KEYWORD: 5127169689Skan switch (c_parser_peek_token (parser)->keyword) 5128169689Skan { 5129169689Skan case RID_SIZEOF: 5130169689Skan return c_parser_sizeof_expression (parser); 5131169689Skan case RID_ALIGNOF: 5132169689Skan return c_parser_alignof_expression (parser); 5133169689Skan case RID_EXTENSION: 5134169689Skan c_parser_consume_token (parser); 5135169689Skan ext = disable_extension_diagnostics (); 5136169689Skan ret = c_parser_cast_expression (parser, NULL); 5137169689Skan restore_extension_diagnostics (ext); 5138169689Skan return ret; 5139169689Skan case RID_REALPART: 5140169689Skan c_parser_consume_token (parser); 5141169689Skan op = c_parser_cast_expression (parser, NULL); 5142169689Skan op = default_function_array_conversion (op); 5143169689Skan return parser_build_unary_op (REALPART_EXPR, op); 5144169689Skan case RID_IMAGPART: 5145169689Skan c_parser_consume_token (parser); 5146169689Skan op = c_parser_cast_expression (parser, NULL); 5147169689Skan op = default_function_array_conversion (op); 5148169689Skan return parser_build_unary_op (IMAGPART_EXPR, op); 5149169689Skan default: 5150169689Skan return c_parser_postfix_expression (parser); 5151169689Skan } 5152169689Skan default: 5153169689Skan return c_parser_postfix_expression (parser); 5154169689Skan } 5155169689Skan} 5156169689Skan 5157169689Skan/* Parse a sizeof expression. */ 5158169689Skan 5159169689Skanstatic struct c_expr 5160169689Skanc_parser_sizeof_expression (c_parser *parser) 5161169689Skan{ 5162169689Skan struct c_expr expr; 5163169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF)); 5164169689Skan c_parser_consume_token (parser); 5165169689Skan skip_evaluation++; 5166169689Skan in_sizeof++; 5167169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 5168169689Skan && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 5169169689Skan { 5170169689Skan /* Either sizeof ( type-name ) or sizeof unary-expression 5171169689Skan starting with a compound literal. */ 5172169689Skan struct c_type_name *type_name; 5173169689Skan c_parser_consume_token (parser); 5174169689Skan type_name = c_parser_type_name (parser); 5175169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 5176169689Skan if (type_name == NULL) 5177169689Skan { 5178169689Skan struct c_expr ret; 5179169689Skan skip_evaluation--; 5180169689Skan in_sizeof--; 5181169689Skan ret.value = error_mark_node; 5182169689Skan ret.original_code = ERROR_MARK; 5183169689Skan return ret; 5184169689Skan } 5185169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 5186169689Skan { 5187169689Skan expr = c_parser_postfix_expression_after_paren_type (parser, 5188169689Skan type_name); 5189169689Skan goto sizeof_expr; 5190169689Skan } 5191169689Skan /* sizeof ( type-name ). */ 5192169689Skan skip_evaluation--; 5193169689Skan in_sizeof--; 5194169689Skan if (type_name->declarator->kind == cdk_array 5195169689Skan && type_name->declarator->u.array.vla_unspec_p) 5196169689Skan { 5197169689Skan /* C99 6.7.5.2p4 */ 5198169689Skan error ("%<[*]%> not allowed in other than a declaration"); 5199169689Skan } 5200169689Skan return c_expr_sizeof_type (type_name); 5201169689Skan } 5202169689Skan else 5203169689Skan { 5204169689Skan expr = c_parser_unary_expression (parser); 5205169689Skan sizeof_expr: 5206169689Skan skip_evaluation--; 5207169689Skan in_sizeof--; 5208169689Skan if (TREE_CODE (expr.value) == COMPONENT_REF 5209169689Skan && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) 5210169689Skan error ("%<sizeof%> applied to a bit-field"); 5211169689Skan return c_expr_sizeof_expr (expr); 5212169689Skan } 5213169689Skan} 5214169689Skan 5215169689Skan/* Parse an alignof expression. */ 5216169689Skan 5217169689Skanstatic struct c_expr 5218169689Skanc_parser_alignof_expression (c_parser *parser) 5219169689Skan{ 5220169689Skan struct c_expr expr; 5221169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF)); 5222169689Skan c_parser_consume_token (parser); 5223169689Skan skip_evaluation++; 5224169689Skan in_alignof++; 5225169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 5226169689Skan && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 5227169689Skan { 5228169689Skan /* Either __alignof__ ( type-name ) or __alignof__ 5229169689Skan unary-expression starting with a compound literal. */ 5230169689Skan struct c_type_name *type_name; 5231169689Skan struct c_expr ret; 5232169689Skan c_parser_consume_token (parser); 5233169689Skan type_name = c_parser_type_name (parser); 5234169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 5235169689Skan if (type_name == NULL) 5236169689Skan { 5237169689Skan struct c_expr ret; 5238169689Skan skip_evaluation--; 5239169689Skan in_alignof--; 5240169689Skan ret.value = error_mark_node; 5241169689Skan ret.original_code = ERROR_MARK; 5242169689Skan return ret; 5243169689Skan } 5244169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 5245169689Skan { 5246169689Skan expr = c_parser_postfix_expression_after_paren_type (parser, 5247169689Skan type_name); 5248169689Skan goto alignof_expr; 5249169689Skan } 5250169689Skan /* alignof ( type-name ). */ 5251169689Skan skip_evaluation--; 5252169689Skan in_alignof--; 5253169689Skan ret.value = c_alignof (groktypename (type_name)); 5254169689Skan ret.original_code = ERROR_MARK; 5255169689Skan return ret; 5256169689Skan } 5257169689Skan else 5258169689Skan { 5259169689Skan struct c_expr ret; 5260169689Skan expr = c_parser_unary_expression (parser); 5261169689Skan alignof_expr: 5262169689Skan skip_evaluation--; 5263169689Skan in_alignof--; 5264169689Skan ret.value = c_alignof_expr (expr.value); 5265169689Skan ret.original_code = ERROR_MARK; 5266169689Skan return ret; 5267169689Skan } 5268169689Skan} 5269169689Skan 5270169689Skan/* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2). 5271169689Skan 5272169689Skan postfix-expression: 5273169689Skan primary-expression 5274169689Skan postfix-expression [ expression ] 5275169689Skan postfix-expression ( argument-expression-list[opt] ) 5276169689Skan postfix-expression . identifier 5277169689Skan postfix-expression -> identifier 5278169689Skan postfix-expression ++ 5279169689Skan postfix-expression -- 5280169689Skan ( type-name ) { initializer-list } 5281169689Skan ( type-name ) { initializer-list , } 5282169689Skan 5283169689Skan argument-expression-list: 5284169689Skan argument-expression 5285169689Skan argument-expression-list , argument-expression 5286169689Skan 5287169689Skan primary-expression: 5288169689Skan identifier 5289169689Skan constant 5290169689Skan string-literal 5291169689Skan ( expression ) 5292169689Skan 5293169689Skan GNU extensions: 5294169689Skan 5295169689Skan primary-expression: 5296169689Skan __func__ 5297169689Skan (treated as a keyword in GNU C) 5298169689Skan __FUNCTION__ 5299169689Skan __PRETTY_FUNCTION__ 5300169689Skan ( compound-statement ) 5301169689Skan __builtin_va_arg ( assignment-expression , type-name ) 5302169689Skan __builtin_offsetof ( type-name , offsetof-member-designator ) 5303169689Skan __builtin_choose_expr ( assignment-expression , 5304169689Skan assignment-expression , 5305169689Skan assignment-expression ) 5306169689Skan __builtin_types_compatible_p ( type-name , type-name ) 5307260311Spfg APPLE LOCAL blocks (C++ cf) 5308260311Spfg block-literal-expr 5309169689Skan 5310169689Skan offsetof-member-designator: 5311169689Skan identifier 5312169689Skan offsetof-member-designator . identifier 5313169689Skan offsetof-member-designator [ expression ] 5314169689Skan 5315169689Skan Objective-C: 5316169689Skan 5317169689Skan primary-expression: 5318169689Skan [ objc-receiver objc-message-args ] 5319169689Skan @selector ( objc-selector-arg ) 5320169689Skan @protocol ( identifier ) 5321169689Skan @encode ( type-name ) 5322169689Skan objc-string-literal 5323169689Skan*/ 5324169689Skan 5325169689Skanstatic struct c_expr 5326169689Skanc_parser_postfix_expression (c_parser *parser) 5327169689Skan{ 5328169689Skan struct c_expr expr, e1, e2, e3; 5329169689Skan struct c_type_name *t1, *t2; 5330169689Skan switch (c_parser_peek_token (parser)->type) 5331169689Skan { 5332169689Skan case CPP_NUMBER: 5333169689Skan case CPP_CHAR: 5334169689Skan case CPP_WCHAR: 5335169689Skan expr.value = c_parser_peek_token (parser)->value; 5336169689Skan expr.original_code = ERROR_MARK; 5337169689Skan c_parser_consume_token (parser); 5338169689Skan break; 5339169689Skan case CPP_STRING: 5340169689Skan case CPP_WSTRING: 5341169689Skan expr.value = c_parser_peek_token (parser)->value; 5342169689Skan expr.original_code = STRING_CST; 5343169689Skan c_parser_consume_token (parser); 5344169689Skan break; 5345169689Skan case CPP_OBJC_STRING: 5346169689Skan gcc_assert (c_dialect_objc ()); 5347169689Skan expr.value 5348169689Skan = objc_build_string_object (c_parser_peek_token (parser)->value); 5349169689Skan expr.original_code = ERROR_MARK; 5350169689Skan c_parser_consume_token (parser); 5351169689Skan break; 5352169689Skan case CPP_NAME: 5353260311Spfg /* APPLE LOCAL begin radar 5277239 */ 5354260311Spfg if (c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME 5355260311Spfg && c_parser_peek_2nd_token (parser)->type == CPP_DOT) 5356260311Spfg { 5357260311Spfg /* CLASS.class_method expression. */ 5358260311Spfg tree receiver, component; 5359260311Spfg receiver = c_parser_objc_receiver (parser); 5360260311Spfg /* consume '.' operator */ 5361260311Spfg c_parser_consume_token (parser); 5362260311Spfg component = c_parser_objc_message_args (parser); 5363260311Spfg expr.value = objc_build_property_reference_expr (receiver, component); 5364260311Spfg expr.original_code = ERROR_MARK; 5365260311Spfg break; 5366260311Spfg } 5367260311Spfg /* APPLE LOCAL end radar 5277239 */ 5368169689Skan if (c_parser_peek_token (parser)->id_kind != C_ID_ID) 5369169689Skan { 5370169689Skan c_parser_error (parser, "expected expression"); 5371169689Skan expr.value = error_mark_node; 5372169689Skan expr.original_code = ERROR_MARK; 5373169689Skan break; 5374169689Skan } 5375169689Skan { 5376169689Skan tree id = c_parser_peek_token (parser)->value; 5377169689Skan location_t loc = c_parser_peek_token (parser)->location; 5378169689Skan c_parser_consume_token (parser); 5379169689Skan expr.value = build_external_ref (id, 5380169689Skan (c_parser_peek_token (parser)->type 5381169689Skan == CPP_OPEN_PAREN), loc); 5382260311Spfg /* APPLE LOCAL begin radar 5732232 - blocks (C++ cd) */ 5383260311Spfg /* If a variabled declared as referenced variable, using |...| syntax, 5384260311Spfg is used in the block, it has to be derefrenced because this 5385260311Spfg variable holds address of the outside variable referenced in. */ 5386260311Spfg 5387260311Spfg /* APPLE LOCAL begin radar 5932809 - copyable byref blocks (C++ cd) */ 5388260311Spfg if (TREE_CODE (expr.value) == VAR_DECL) 5389260311Spfg { 5390260311Spfg if (BLOCK_DECL_BYREF (expr.value)) 5391260311Spfg { 5392260311Spfg tree orig_decl = expr.value; 5393260311Spfg expr.value = build_indirect_ref (expr.value, "unary *"); 5394260311Spfg if (COPYABLE_BYREF_LOCAL_VAR (orig_decl)) { 5395260311Spfg /* What we have is an expression which is of type 5396260311Spfg struct __Block_byref_X. Must get to the value of the variable 5397260311Spfg embedded in this structure. It is at: 5398260311Spfg __Block_byref_X.__forwarding->x */ 5399260311Spfg expr.value = build_byref_local_var_access (expr.value, 5400260311Spfg DECL_NAME (orig_decl)); 5401260311Spfg } 5402260311Spfg } 5403260311Spfg else if (COPYABLE_BYREF_LOCAL_VAR (expr.value)) 5404260311Spfg expr.value = build_byref_local_var_access (expr.value, 5405260311Spfg DECL_NAME (expr.value)); 5406260311Spfg } 5407260311Spfg /* APPLE LOCAL end radar 5932809 - copyable byref blocks */ 5408260311Spfg 5409260311Spfg /* APPLE LOCAL end radar 5732232 - blocks (C++ cd) */ 5410169689Skan expr.original_code = ERROR_MARK; 5411169689Skan } 5412169689Skan break; 5413169689Skan case CPP_OPEN_PAREN: 5414169689Skan /* A parenthesized expression, statement expression or compound 5415169689Skan literal. */ 5416169689Skan if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE) 5417169689Skan { 5418169689Skan /* A statement expression. */ 5419169689Skan tree stmt; 5420169689Skan c_parser_consume_token (parser); 5421169689Skan c_parser_consume_token (parser); 5422169689Skan if (cur_stmt_list == NULL) 5423169689Skan { 5424169689Skan error ("braced-group within expression allowed " 5425169689Skan "only inside a function"); 5426169689Skan parser->error = true; 5427169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 5428169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 5429169689Skan expr.value = error_mark_node; 5430169689Skan expr.original_code = ERROR_MARK; 5431169689Skan break; 5432169689Skan } 5433169689Skan stmt = c_begin_stmt_expr (); 5434169689Skan c_parser_compound_statement_nostart (parser); 5435169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5436169689Skan "expected %<)%>"); 5437169689Skan if (pedantic) 5438169689Skan pedwarn ("ISO C forbids braced-groups within expressions"); 5439169689Skan expr.value = c_finish_stmt_expr (stmt); 5440169689Skan expr.original_code = ERROR_MARK; 5441169689Skan } 5442169689Skan else if (c_token_starts_typename (c_parser_peek_2nd_token (parser))) 5443169689Skan { 5444169689Skan /* A compound literal. ??? Can we actually get here rather 5445169689Skan than going directly to 5446169689Skan c_parser_postfix_expression_after_paren_type from 5447169689Skan elsewhere? */ 5448169689Skan struct c_type_name *type_name; 5449169689Skan c_parser_consume_token (parser); 5450169689Skan type_name = c_parser_type_name (parser); 5451169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5452169689Skan "expected %<)%>"); 5453169689Skan if (type_name == NULL) 5454169689Skan { 5455169689Skan expr.value = error_mark_node; 5456169689Skan expr.original_code = ERROR_MARK; 5457169689Skan } 5458169689Skan else 5459169689Skan expr = c_parser_postfix_expression_after_paren_type (parser, 5460169689Skan type_name); 5461169689Skan } 5462169689Skan else 5463169689Skan { 5464169689Skan /* A parenthesized expression. */ 5465169689Skan c_parser_consume_token (parser); 5466169689Skan expr = c_parser_expression (parser); 5467169689Skan if (TREE_CODE (expr.value) == MODIFY_EXPR) 5468169689Skan TREE_NO_WARNING (expr.value) = 1; 5469169689Skan expr.original_code = ERROR_MARK; 5470169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5471169689Skan "expected %<)%>"); 5472169689Skan } 5473169689Skan break; 5474169689Skan case CPP_KEYWORD: 5475169689Skan switch (c_parser_peek_token (parser)->keyword) 5476169689Skan { 5477169689Skan case RID_FUNCTION_NAME: 5478169689Skan case RID_PRETTY_FUNCTION_NAME: 5479169689Skan case RID_C99_FUNCTION_NAME: 5480169689Skan expr.value = fname_decl (c_parser_peek_token (parser)->keyword, 5481169689Skan c_parser_peek_token (parser)->value); 5482169689Skan expr.original_code = ERROR_MARK; 5483169689Skan c_parser_consume_token (parser); 5484169689Skan break; 5485169689Skan case RID_VA_ARG: 5486169689Skan c_parser_consume_token (parser); 5487169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 5488169689Skan { 5489169689Skan expr.value = error_mark_node; 5490169689Skan expr.original_code = ERROR_MARK; 5491169689Skan break; 5492169689Skan } 5493169689Skan e1 = c_parser_expr_no_commas (parser, NULL); 5494169689Skan if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 5495169689Skan { 5496169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 5497169689Skan expr.value = error_mark_node; 5498169689Skan expr.original_code = ERROR_MARK; 5499169689Skan break; 5500169689Skan } 5501169689Skan t1 = c_parser_type_name (parser); 5502169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5503169689Skan "expected %<)%>"); 5504169689Skan if (t1 == NULL) 5505169689Skan { 5506169689Skan expr.value = error_mark_node; 5507169689Skan expr.original_code = ERROR_MARK; 5508169689Skan } 5509169689Skan else 5510169689Skan { 5511169689Skan expr.value = build_va_arg (e1.value, groktypename (t1)); 5512169689Skan expr.original_code = ERROR_MARK; 5513169689Skan } 5514169689Skan break; 5515169689Skan case RID_OFFSETOF: 5516169689Skan c_parser_consume_token (parser); 5517169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 5518169689Skan { 5519169689Skan expr.value = error_mark_node; 5520169689Skan expr.original_code = ERROR_MARK; 5521169689Skan break; 5522169689Skan } 5523169689Skan t1 = c_parser_type_name (parser); 5524169689Skan if (t1 == NULL) 5525169689Skan { 5526169689Skan expr.value = error_mark_node; 5527169689Skan expr.original_code = ERROR_MARK; 5528169689Skan break; 5529169689Skan } 5530169689Skan if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 5531169689Skan { 5532169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 5533169689Skan expr.value = error_mark_node; 5534169689Skan expr.original_code = ERROR_MARK; 5535169689Skan break; 5536169689Skan } 5537169689Skan { 5538169689Skan tree type = groktypename (t1); 5539169689Skan tree offsetof_ref; 5540169689Skan if (type == error_mark_node) 5541169689Skan offsetof_ref = error_mark_node; 5542169689Skan else 5543169689Skan offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node); 5544169689Skan /* Parse the second argument to __builtin_offsetof. We 5545169689Skan must have one identifier, and beyond that we want to 5546169689Skan accept sub structure and sub array references. */ 5547169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 5548169689Skan { 5549169689Skan offsetof_ref = build_component_ref 5550169689Skan (offsetof_ref, c_parser_peek_token (parser)->value); 5551169689Skan c_parser_consume_token (parser); 5552169689Skan while (c_parser_next_token_is (parser, CPP_DOT) 5553169689Skan || c_parser_next_token_is (parser, 5554169689Skan CPP_OPEN_SQUARE)) 5555169689Skan { 5556169689Skan if (c_parser_next_token_is (parser, CPP_DOT)) 5557169689Skan { 5558169689Skan c_parser_consume_token (parser); 5559169689Skan if (c_parser_next_token_is_not (parser, 5560169689Skan CPP_NAME)) 5561169689Skan { 5562169689Skan c_parser_error (parser, "expected identifier"); 5563169689Skan break; 5564169689Skan } 5565169689Skan offsetof_ref = build_component_ref 5566169689Skan (offsetof_ref, 5567169689Skan c_parser_peek_token (parser)->value); 5568169689Skan c_parser_consume_token (parser); 5569169689Skan } 5570169689Skan else 5571169689Skan { 5572169689Skan tree idx; 5573169689Skan c_parser_consume_token (parser); 5574169689Skan idx = c_parser_expression (parser).value; 5575169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 5576169689Skan "expected %<]%>"); 5577169689Skan offsetof_ref = build_array_ref (offsetof_ref, idx); 5578169689Skan } 5579169689Skan } 5580169689Skan } 5581169689Skan else 5582169689Skan c_parser_error (parser, "expected identifier"); 5583169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5584169689Skan "expected %<)%>"); 5585169689Skan expr.value = fold_offsetof (offsetof_ref, NULL_TREE); 5586169689Skan expr.original_code = ERROR_MARK; 5587169689Skan } 5588169689Skan break; 5589169689Skan case RID_CHOOSE_EXPR: 5590169689Skan c_parser_consume_token (parser); 5591169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 5592169689Skan { 5593169689Skan expr.value = error_mark_node; 5594169689Skan expr.original_code = ERROR_MARK; 5595169689Skan break; 5596169689Skan } 5597169689Skan e1 = c_parser_expr_no_commas (parser, NULL); 5598169689Skan if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 5599169689Skan { 5600169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 5601169689Skan expr.value = error_mark_node; 5602169689Skan expr.original_code = ERROR_MARK; 5603169689Skan break; 5604169689Skan } 5605169689Skan e2 = c_parser_expr_no_commas (parser, NULL); 5606169689Skan if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 5607169689Skan { 5608169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 5609169689Skan expr.value = error_mark_node; 5610169689Skan expr.original_code = ERROR_MARK; 5611169689Skan break; 5612169689Skan } 5613169689Skan e3 = c_parser_expr_no_commas (parser, NULL); 5614169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5615169689Skan "expected %<)%>"); 5616169689Skan { 5617169689Skan tree c; 5618169689Skan 5619169689Skan c = fold (e1.value); 5620169689Skan if (TREE_CODE (c) != INTEGER_CST) 5621169689Skan error ("first argument to %<__builtin_choose_expr%> not" 5622169689Skan " a constant"); 5623169689Skan expr = integer_zerop (c) ? e3 : e2; 5624169689Skan } 5625169689Skan break; 5626169689Skan case RID_TYPES_COMPATIBLE_P: 5627169689Skan c_parser_consume_token (parser); 5628169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 5629169689Skan { 5630169689Skan expr.value = error_mark_node; 5631169689Skan expr.original_code = ERROR_MARK; 5632169689Skan break; 5633169689Skan } 5634169689Skan t1 = c_parser_type_name (parser); 5635169689Skan if (t1 == NULL) 5636169689Skan { 5637169689Skan expr.value = error_mark_node; 5638169689Skan expr.original_code = ERROR_MARK; 5639169689Skan break; 5640169689Skan } 5641169689Skan if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 5642169689Skan { 5643169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 5644169689Skan expr.value = error_mark_node; 5645169689Skan expr.original_code = ERROR_MARK; 5646169689Skan break; 5647169689Skan } 5648169689Skan t2 = c_parser_type_name (parser); 5649169689Skan if (t2 == NULL) 5650169689Skan { 5651169689Skan expr.value = error_mark_node; 5652169689Skan expr.original_code = ERROR_MARK; 5653169689Skan break; 5654169689Skan } 5655169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5656169689Skan "expected %<)%>"); 5657169689Skan { 5658169689Skan tree e1, e2; 5659169689Skan 5660169689Skan e1 = TYPE_MAIN_VARIANT (groktypename (t1)); 5661169689Skan e2 = TYPE_MAIN_VARIANT (groktypename (t2)); 5662169689Skan 5663169689Skan expr.value = comptypes (e1, e2) 5664169689Skan ? build_int_cst (NULL_TREE, 1) 5665169689Skan : build_int_cst (NULL_TREE, 0); 5666169689Skan expr.original_code = ERROR_MARK; 5667169689Skan } 5668169689Skan break; 5669169689Skan case RID_AT_SELECTOR: 5670169689Skan gcc_assert (c_dialect_objc ()); 5671169689Skan c_parser_consume_token (parser); 5672169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 5673169689Skan { 5674169689Skan expr.value = error_mark_node; 5675169689Skan expr.original_code = ERROR_MARK; 5676169689Skan break; 5677169689Skan } 5678169689Skan { 5679169689Skan tree sel = c_parser_objc_selector_arg (parser); 5680169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5681169689Skan "expected %<)%>"); 5682169689Skan expr.value = objc_build_selector_expr (sel); 5683169689Skan expr.original_code = ERROR_MARK; 5684169689Skan } 5685169689Skan break; 5686169689Skan case RID_AT_PROTOCOL: 5687169689Skan gcc_assert (c_dialect_objc ()); 5688169689Skan c_parser_consume_token (parser); 5689169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 5690169689Skan { 5691169689Skan expr.value = error_mark_node; 5692169689Skan expr.original_code = ERROR_MARK; 5693169689Skan break; 5694169689Skan } 5695169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 5696169689Skan { 5697169689Skan c_parser_error (parser, "expected identifier"); 5698169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 5699169689Skan expr.value = error_mark_node; 5700169689Skan expr.original_code = ERROR_MARK; 5701169689Skan break; 5702169689Skan } 5703169689Skan { 5704169689Skan tree id = c_parser_peek_token (parser)->value; 5705169689Skan c_parser_consume_token (parser); 5706169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5707169689Skan "expected %<)%>"); 5708169689Skan expr.value = objc_build_protocol_expr (id); 5709169689Skan expr.original_code = ERROR_MARK; 5710169689Skan } 5711169689Skan break; 5712169689Skan case RID_AT_ENCODE: 5713169689Skan /* Extension to support C-structures in the archiver. */ 5714169689Skan gcc_assert (c_dialect_objc ()); 5715169689Skan c_parser_consume_token (parser); 5716169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 5717169689Skan { 5718169689Skan expr.value = error_mark_node; 5719169689Skan expr.original_code = ERROR_MARK; 5720169689Skan break; 5721169689Skan } 5722169689Skan t1 = c_parser_type_name (parser); 5723169689Skan if (t1 == NULL) 5724169689Skan { 5725169689Skan expr.value = error_mark_node; 5726169689Skan expr.original_code = ERROR_MARK; 5727169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 5728169689Skan break; 5729169689Skan } 5730169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5731169689Skan "expected %<)%>"); 5732169689Skan { 5733169689Skan tree type = groktypename (t1); 5734169689Skan expr.value = objc_build_encode_expr (type); 5735169689Skan expr.original_code = ERROR_MARK; 5736169689Skan } 5737169689Skan break; 5738169689Skan default: 5739169689Skan c_parser_error (parser, "expected expression"); 5740169689Skan expr.value = error_mark_node; 5741169689Skan expr.original_code = ERROR_MARK; 5742169689Skan break; 5743169689Skan } 5744169689Skan break; 5745260311Spfg /* APPLE LOCAL begin radar 5732232 - blocks (C++ cf) */ 5746260311Spfg case CPP_XOR: 5747260311Spfg if (flag_blocks) { 5748260311Spfg expr.value = c_parser_block_literal_expr (parser); 5749260311Spfg expr.original_code = ERROR_MARK; 5750260311Spfg break; 5751260311Spfg } 5752260311Spfg c_parser_error (parser, "expected expression"); 5753260311Spfg expr.value = error_mark_node; 5754260311Spfg expr.original_code = ERROR_MARK; 5755260311Spfg break; 5756260311Spfg /* APPLE LOCAL end radar 5732232 - blocks (C++ cf) */ 5757169689Skan case CPP_OPEN_SQUARE: 5758169689Skan if (c_dialect_objc ()) 5759169689Skan { 5760169689Skan tree receiver, args; 5761169689Skan c_parser_consume_token (parser); 5762169689Skan receiver = c_parser_objc_receiver (parser); 5763169689Skan args = c_parser_objc_message_args (parser); 5764169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 5765169689Skan "expected %<]%>"); 5766169689Skan expr.value = objc_build_message_expr (build_tree_list (receiver, 5767169689Skan args)); 5768169689Skan expr.original_code = ERROR_MARK; 5769169689Skan break; 5770169689Skan } 5771169689Skan /* Else fall through to report error. */ 5772169689Skan default: 5773169689Skan c_parser_error (parser, "expected expression"); 5774169689Skan expr.value = error_mark_node; 5775169689Skan expr.original_code = ERROR_MARK; 5776169689Skan break; 5777169689Skan } 5778169689Skan return c_parser_postfix_expression_after_primary (parser, expr); 5779169689Skan} 5780169689Skan 5781169689Skan/* Parse a postfix expression after a parenthesized type name: the 5782169689Skan brace-enclosed initializer of a compound literal, possibly followed 5783169689Skan by some postfix operators. This is separate because it is not 5784169689Skan possible to tell until after the type name whether a cast 5785169689Skan expression has a cast or a compound literal, or whether the operand 5786169689Skan of sizeof is a parenthesized type name or starts with a compound 5787169689Skan literal. */ 5788169689Skan 5789169689Skanstatic struct c_expr 5790169689Skanc_parser_postfix_expression_after_paren_type (c_parser *parser, 5791169689Skan struct c_type_name *type_name) 5792169689Skan{ 5793169689Skan tree type; 5794169689Skan struct c_expr init; 5795169689Skan struct c_expr expr; 5796169689Skan start_init (NULL_TREE, NULL, 0); 5797169689Skan type = groktypename (type_name); 5798169689Skan if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type)) 5799169689Skan { 5800169689Skan error ("compound literal has variable size"); 5801169689Skan type = error_mark_node; 5802169689Skan } 5803169689Skan init = c_parser_braced_init (parser, type, false); 5804169689Skan finish_init (); 5805169689Skan maybe_warn_string_init (type, init); 5806169689Skan 5807169689Skan if (pedantic && !flag_isoc99) 5808169689Skan pedwarn ("ISO C90 forbids compound literals"); 5809169689Skan expr.value = build_compound_literal (type, init.value); 5810169689Skan expr.original_code = ERROR_MARK; 5811169689Skan return c_parser_postfix_expression_after_primary (parser, expr); 5812169689Skan} 5813169689Skan 5814169689Skan/* Parse a postfix expression after the initial primary or compound 5815169689Skan literal; that is, parse a series of postfix operators. */ 5816169689Skan 5817169689Skanstatic struct c_expr 5818169689Skanc_parser_postfix_expression_after_primary (c_parser *parser, 5819169689Skan struct c_expr expr) 5820169689Skan{ 5821169689Skan tree ident, idx, exprlist; 5822169689Skan while (true) 5823169689Skan { 5824169689Skan switch (c_parser_peek_token (parser)->type) 5825169689Skan { 5826169689Skan case CPP_OPEN_SQUARE: 5827169689Skan /* Array reference. */ 5828169689Skan c_parser_consume_token (parser); 5829169689Skan idx = c_parser_expression (parser).value; 5830169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 5831169689Skan "expected %<]%>"); 5832169689Skan expr.value = build_array_ref (expr.value, idx); 5833169689Skan expr.original_code = ERROR_MARK; 5834169689Skan break; 5835169689Skan case CPP_OPEN_PAREN: 5836169689Skan /* Function call. */ 5837169689Skan c_parser_consume_token (parser); 5838169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 5839169689Skan exprlist = NULL_TREE; 5840169689Skan else 5841169689Skan exprlist = c_parser_expr_list (parser, true); 5842169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 5843169689Skan "expected %<)%>"); 5844169689Skan expr.value = build_function_call (expr.value, exprlist); 5845169689Skan expr.original_code = ERROR_MARK; 5846169689Skan break; 5847169689Skan case CPP_DOT: 5848169689Skan /* Structure element reference. */ 5849169689Skan c_parser_consume_token (parser); 5850169689Skan expr = default_function_array_conversion (expr); 5851169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 5852169689Skan ident = c_parser_peek_token (parser)->value; 5853169689Skan else 5854169689Skan { 5855169689Skan c_parser_error (parser, "expected identifier"); 5856169689Skan expr.value = error_mark_node; 5857169689Skan expr.original_code = ERROR_MARK; 5858169689Skan return expr; 5859169689Skan } 5860169689Skan c_parser_consume_token (parser); 5861169689Skan expr.value = build_component_ref (expr.value, ident); 5862169689Skan expr.original_code = ERROR_MARK; 5863169689Skan break; 5864169689Skan case CPP_DEREF: 5865169689Skan /* Structure element reference. */ 5866169689Skan c_parser_consume_token (parser); 5867169689Skan expr = default_function_array_conversion (expr); 5868169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 5869169689Skan ident = c_parser_peek_token (parser)->value; 5870169689Skan else 5871169689Skan { 5872169689Skan c_parser_error (parser, "expected identifier"); 5873169689Skan expr.value = error_mark_node; 5874169689Skan expr.original_code = ERROR_MARK; 5875169689Skan return expr; 5876169689Skan } 5877169689Skan c_parser_consume_token (parser); 5878169689Skan expr.value = build_component_ref (build_indirect_ref (expr.value, 5879169689Skan "->"), ident); 5880169689Skan expr.original_code = ERROR_MARK; 5881169689Skan break; 5882169689Skan case CPP_PLUS_PLUS: 5883169689Skan /* Postincrement. */ 5884169689Skan c_parser_consume_token (parser); 5885169689Skan expr = default_function_array_conversion (expr); 5886169689Skan expr.value = build_unary_op (POSTINCREMENT_EXPR, expr.value, 0); 5887169689Skan expr.original_code = ERROR_MARK; 5888169689Skan break; 5889169689Skan case CPP_MINUS_MINUS: 5890169689Skan /* Postdecrement. */ 5891169689Skan c_parser_consume_token (parser); 5892169689Skan expr = default_function_array_conversion (expr); 5893169689Skan expr.value = build_unary_op (POSTDECREMENT_EXPR, expr.value, 0); 5894169689Skan expr.original_code = ERROR_MARK; 5895169689Skan break; 5896169689Skan default: 5897169689Skan return expr; 5898169689Skan } 5899169689Skan } 5900169689Skan} 5901169689Skan 5902169689Skan/* Parse an expression (C90 6.3.17, C99 6.5.17). 5903169689Skan 5904169689Skan expression: 5905169689Skan assignment-expression 5906169689Skan expression , assignment-expression 5907169689Skan*/ 5908169689Skan 5909169689Skanstatic struct c_expr 5910169689Skanc_parser_expression (c_parser *parser) 5911169689Skan{ 5912169689Skan struct c_expr expr; 5913169689Skan expr = c_parser_expr_no_commas (parser, NULL); 5914169689Skan while (c_parser_next_token_is (parser, CPP_COMMA)) 5915169689Skan { 5916169689Skan struct c_expr next; 5917169689Skan c_parser_consume_token (parser); 5918169689Skan next = c_parser_expr_no_commas (parser, NULL); 5919169689Skan next = default_function_array_conversion (next); 5920169689Skan expr.value = build_compound_expr (expr.value, next.value); 5921169689Skan expr.original_code = COMPOUND_EXPR; 5922169689Skan } 5923169689Skan return expr; 5924169689Skan} 5925169689Skan 5926169689Skan/* Parse an expression and convert functions or arrays to 5927169689Skan pointers. */ 5928169689Skan 5929169689Skanstatic struct c_expr 5930169689Skanc_parser_expression_conv (c_parser *parser) 5931169689Skan{ 5932169689Skan struct c_expr expr; 5933169689Skan expr = c_parser_expression (parser); 5934169689Skan expr = default_function_array_conversion (expr); 5935169689Skan return expr; 5936169689Skan} 5937169689Skan 5938169689Skan/* Parse a non-empty list of expressions. If CONVERT_P, convert 5939169689Skan functions and arrays to pointers. 5940169689Skan 5941169689Skan nonempty-expr-list: 5942169689Skan assignment-expression 5943169689Skan nonempty-expr-list , assignment-expression 5944169689Skan*/ 5945169689Skan 5946169689Skanstatic tree 5947169689Skanc_parser_expr_list (c_parser *parser, bool convert_p) 5948169689Skan{ 5949169689Skan struct c_expr expr; 5950169689Skan tree ret, cur; 5951169689Skan expr = c_parser_expr_no_commas (parser, NULL); 5952169689Skan if (convert_p) 5953169689Skan expr = default_function_array_conversion (expr); 5954169689Skan ret = cur = build_tree_list (NULL_TREE, expr.value); 5955169689Skan while (c_parser_next_token_is (parser, CPP_COMMA)) 5956169689Skan { 5957169689Skan c_parser_consume_token (parser); 5958169689Skan expr = c_parser_expr_no_commas (parser, NULL); 5959169689Skan if (convert_p) 5960169689Skan expr = default_function_array_conversion (expr); 5961169689Skan cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value); 5962169689Skan } 5963169689Skan return ret; 5964169689Skan} 5965169689Skan 5966169689Skan 5967169689Skan/* Parse Objective-C-specific constructs. */ 5968169689Skan 5969169689Skan/* Parse an objc-class-definition. 5970169689Skan 5971169689Skan objc-class-definition: 5972169689Skan @interface identifier objc-superclass[opt] objc-protocol-refs[opt] 5973169689Skan objc-class-instance-variables[opt] objc-methodprotolist @end 5974169689Skan @implementation identifier objc-superclass[opt] 5975169689Skan objc-class-instance-variables[opt] 5976169689Skan @interface identifier ( identifier ) objc-protocol-refs[opt] 5977169689Skan objc-methodprotolist @end 5978169689Skan @implementation identifier ( identifier ) 5979169689Skan 5980169689Skan objc-superclass: 5981169689Skan : identifier 5982169689Skan 5983169689Skan "@interface identifier (" must start "@interface identifier ( 5984169689Skan identifier ) ...": objc-methodprotolist in the first production may 5985169689Skan not start with a parenthesized identifier as a declarator of a data 5986169689Skan definition with no declaration specifiers if the objc-superclass, 5987169689Skan objc-protocol-refs and objc-class-instance-variables are omitted. */ 5988169689Skan 5989169689Skanstatic void 5990260311Spfg/* APPLE LOCAL radar 4548636 - class attributes. */ 5991260311Spfgc_parser_objc_class_definition (c_parser *parser, tree prefix_attrs) 5992169689Skan{ 5993169689Skan bool iface_p; 5994169689Skan tree id1; 5995169689Skan tree superclass; 5996169689Skan if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE)) 5997169689Skan iface_p = true; 5998169689Skan else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION)) 5999260311Spfg /* APPLE LOCAL begin radar 4548636 - class attributes. */ 6000260311Spfg { 6001260311Spfg if (prefix_attrs) 6002260311Spfg { 6003260311Spfg error ("attributes may not be specified on an implementation"); 6004260311Spfg prefix_attrs = NULL_TREE; 6005260311Spfg } 6006260311Spfg iface_p = false; 6007260311Spfg } 6008260311Spfg /* APPLE LOCAL end radar 4548636 - class attributes. */ 6009169689Skan else 6010169689Skan gcc_unreachable (); 6011169689Skan c_parser_consume_token (parser); 6012169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6013169689Skan { 6014260311Spfg /* APPLE LOCAL radar 4965989 */ 6015260311Spfg tree id2 = NULL_TREE; 6016169689Skan tree proto = NULL_TREE; 6017169689Skan c_parser_consume_token (parser); 6018260311Spfg /* APPLE LOCAL begin radar 4965989 */ 6019260311Spfg if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) 6020169689Skan { 6021260311Spfg if (c_parser_next_token_is_not (parser, CPP_NAME)) 6022260311Spfg { 6023260311Spfg c_parser_error (parser, "expected identifier"); 6024260311Spfg c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 6025260311Spfg return; 6026260311Spfg } 6027260311Spfg id2 = c_parser_peek_token (parser)->value; 6028260311Spfg c_parser_consume_token (parser); 6029169689Skan } 6030260311Spfg /* APPLE LOCAL end radar 4965989 */ 6031169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 6032169689Skan if (!iface_p) 6033169689Skan { 6034260311Spfg /* APPLE LOCAL begin radar 4965989 */ 6035260311Spfg if (id2 == NULL_TREE) 6036260311Spfg { 6037260311Spfg error ("cannot implement anonymous category"); 6038260311Spfg return; 6039260311Spfg } 6040260311Spfg /* APPLE LOCAL end radar 4965989 */ 6041169689Skan objc_start_category_implementation (id1, id2); 6042169689Skan return; 6043169689Skan } 6044169689Skan if (c_parser_next_token_is (parser, CPP_LESS)) 6045169689Skan proto = c_parser_objc_protocol_refs (parser); 6046260311Spfg /* APPLE LOCAL begin radar 4548636 - class attributes. */ 6047260311Spfg if (prefix_attrs) 6048260311Spfg error ("attributes may not be specified on a category"); 6049260311Spfg /* APPLE LOCAL end radar 4548636 - class attributes. */ 6050169689Skan objc_start_category_interface (id1, id2, proto); 6051260311Spfg /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 q) */ 6052260311Spfg c_parser_objc_interfacedecllist (parser); 6053169689Skan c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 6054169689Skan objc_finish_interface (); 6055169689Skan return; 6056169689Skan } 6057169689Skan if (c_parser_next_token_is (parser, CPP_COLON)) 6058169689Skan { 6059169689Skan c_parser_consume_token (parser); 6060169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6061169689Skan { 6062169689Skan c_parser_error (parser, "expected identifier"); 6063169689Skan return; 6064169689Skan } 6065169689Skan superclass = c_parser_peek_token (parser)->value; 6066169689Skan c_parser_consume_token (parser); 6067169689Skan } 6068169689Skan else 6069169689Skan superclass = NULL_TREE; 6070169689Skan if (iface_p) 6071169689Skan { 6072169689Skan tree proto = NULL_TREE; 6073169689Skan if (c_parser_next_token_is (parser, CPP_LESS)) 6074169689Skan proto = c_parser_objc_protocol_refs (parser); 6075260311Spfg /* APPLE LOCAL radar 4548636 - class attributes. */ 6076260311Spfg objc_start_class_interface (id1, superclass, proto, prefix_attrs); 6077169689Skan } 6078169689Skan else 6079169689Skan objc_start_class_implementation (id1, superclass); 6080169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 6081169689Skan c_parser_objc_class_instance_variables (parser); 6082169689Skan if (iface_p) 6083169689Skan { 6084169689Skan objc_continue_interface (); 6085260311Spfg /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 q) */ 6086260311Spfg c_parser_objc_interfacedecllist (parser); 6087169689Skan c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 6088169689Skan objc_finish_interface (); 6089169689Skan } 6090169689Skan else 6091169689Skan { 6092169689Skan objc_continue_implementation (); 6093169689Skan return; 6094169689Skan } 6095169689Skan} 6096169689Skan 6097260311Spfg/* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 s) */ 6098260311Spfgstatic tree 6099260311Spfgc_parser_objc_eq_identifier (c_parser *parser) 6100260311Spfg{ 6101260311Spfg tree id; 6102260311Spfg if (c_parser_next_token_is_not (parser, CPP_EQ)) 6103260311Spfg { 6104260311Spfg c_parser_error (parser, "expected %<=%>"); 6105260311Spfg return NULL_TREE; 6106260311Spfg } 6107260311Spfg /* Consume '=' */ 6108260311Spfg c_parser_consume_token (parser); 6109260311Spfg if (c_parser_next_token_is_not (parser, CPP_NAME)) 6110260311Spfg { 6111260311Spfg c_parser_error (parser, "expected identifier"); 6112260311Spfg return NULL_TREE; 6113260311Spfg } 6114260311Spfg id = c_parser_peek_token (parser)->value; 6115260311Spfg c_parser_consume_token (parser); 6116260311Spfg return id; 6117260311Spfg} 6118260311Spfg 6119260311Spfg/* Parse obj-property-attribute. 6120260311Spfg*/ 6121260311Spfgstatic void 6122260311Spfgc_parser_objc_property_attribute (c_parser *parser) 6123260311Spfg{ 6124260311Spfg tree id; 6125260311Spfg if (c_parser_peek_token (parser)->type != CPP_KEYWORD) 6126260311Spfg { 6127260311Spfg c_parser_error (parser, "expected a property attribute"); 6128260311Spfg c_parser_consume_token (parser); 6129260311Spfg return; 6130260311Spfg } 6131260311Spfg switch (c_parser_peek_token (parser)->keyword) 6132260311Spfg { 6133260311Spfg case RID_READONLY: 6134260311Spfg c_parser_consume_token (parser); 6135260311Spfg objc_set_property_attr (1, NULL_TREE); 6136260311Spfg break; 6137260311Spfg case RID_GETTER: 6138260311Spfg c_parser_consume_token (parser); 6139260311Spfg id = c_parser_objc_eq_identifier (parser); 6140260311Spfg if (id) 6141260311Spfg objc_set_property_attr (2, id); 6142260311Spfg break; 6143260311Spfg case RID_SETTER: 6144260311Spfg c_parser_consume_token (parser); 6145260311Spfg id = c_parser_objc_eq_identifier (parser); 6146260311Spfg if (id) 6147260311Spfg objc_set_property_attr (3, id); 6148260311Spfg /* Consume the ':' which must always follow the setter name. */ 6149260311Spfg if (c_parser_next_token_is (parser, CPP_COLON)) 6150260311Spfg c_parser_consume_token (parser); 6151260311Spfg break; 6152260311Spfg /* APPLE LOCAL begin radar 4947014 - objc atomic property */ 6153260311Spfg case RID_NONATOMIC: 6154260311Spfg c_parser_consume_token (parser); 6155260311Spfg objc_set_property_attr (13, NULL_TREE); 6156260311Spfg break; 6157260311Spfg /* APPLE LOCAL end radar 4947014 - objc atomic property */ 6158260311Spfg default: 6159260311Spfg c_parser_error (parser, "expected a property attribute"); 6160260311Spfg c_parser_consume_token (parser); 6161260311Spfg } 6162260311Spfg} 6163260311Spfg 6164260311Spfgstatic void 6165260311Spfgc_parser_objc_property_attrlist (c_parser *parser) 6166260311Spfg{ 6167260311Spfg while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN) 6168260311Spfg && c_parser_next_token_is_not (parser, CPP_EOF)) 6169260311Spfg { 6170260311Spfg c_parser_objc_property_attribute (parser); 6171260311Spfg /* APPLE LOCAL begin radar 6302949 */ 6172260311Spfg if (c_parser_next_token_is_not (parser, CPP_COMMA) 6173260311Spfg && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN) 6174260311Spfg && c_parser_next_token_is_not (parser, CPP_EOF)) 6175260311Spfg warning (0, "property attributes must be separated by a comma"); 6176260311Spfg /* APPLE LOCAL end radar 6302949 */ 6177260311Spfg if (c_parser_next_token_is (parser, CPP_COMMA) 6178260311Spfg || c_parser_next_token_is (parser, CPP_NAME) /* error */) 6179260311Spfg c_parser_consume_token (parser); 6180260311Spfg } 6181260311Spfg} 6182260311Spfg 6183260311Spfgstatic void 6184260311Spfgc_parser_objc_property_attr_decl (c_parser *parser) 6185260311Spfg{ 6186260311Spfg if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 6187260311Spfg return; 6188260311Spfg c_parser_consume_token (parser); 6189260311Spfg c_parser_objc_property_attrlist (parser); 6190260311Spfg c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 6191260311Spfg} 6192260311Spfg 6193260311Spfgstatic tree 6194260311Spfgc_parser_component_decl (c_parser *parser) 6195260311Spfg{ 6196260311Spfg tree decl = c_parser_struct_declaration (parser); 6197260311Spfg return decl; 6198260311Spfg} 6199260311Spfg 6200260311Spfgstatic void 6201260311Spfgc_parser_objc_property_declaration (c_parser *parser) 6202260311Spfg{ 6203260311Spfg tree prop; 6204260311Spfg c_parser_require_keyword (parser, RID_AT_PROPERTY, "expected %<@property%>"); 6205260311Spfg objc_property_attr_context = 1; 6206260311Spfg objc_set_property_attr (0, NULL_TREE); 6207260311Spfg c_parser_objc_property_attr_decl (parser); 6208260311Spfg objc_property_attr_context = 0; 6209260311Spfg prop = c_parser_component_decl (parser); 6210260311Spfg /* Comma-separated properties are chained together in 6211260311Spfg reverse order; add them one by one. */ 6212260311Spfg prop = nreverse (prop); 6213260311Spfg 6214260311Spfg for (; prop; prop = TREE_CHAIN (prop)) 6215260311Spfg objc_add_property_variable (copy_node (prop)); 6216260311Spfg c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 6217260311Spfg} 6218260311Spfg/* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 s) */ 6219260311Spfg 6220169689Skan/* Parse objc-class-instance-variables. 6221169689Skan 6222169689Skan objc-class-instance-variables: 6223169689Skan { objc-instance-variable-decl-list[opt] } 6224169689Skan 6225169689Skan objc-instance-variable-decl-list: 6226169689Skan objc-visibility-spec 6227169689Skan objc-instance-variable-decl ; 6228169689Skan ; 6229169689Skan objc-instance-variable-decl-list objc-visibility-spec 6230169689Skan objc-instance-variable-decl-list objc-instance-variable-decl ; 6231169689Skan objc-instance-variable-decl-list ; 6232169689Skan 6233169689Skan objc-visibility-spec: 6234169689Skan @private 6235169689Skan @protected 6236169689Skan @public 6237169689Skan 6238169689Skan objc-instance-variable-decl: 6239169689Skan struct-declaration 6240169689Skan*/ 6241169689Skan 6242169689Skanstatic void 6243169689Skanc_parser_objc_class_instance_variables (c_parser *parser) 6244169689Skan{ 6245169689Skan gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); 6246169689Skan c_parser_consume_token (parser); 6247169689Skan while (c_parser_next_token_is_not (parser, CPP_EOF)) 6248169689Skan { 6249169689Skan tree decls; 6250169689Skan /* Parse any stray semicolon. */ 6251169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6252169689Skan { 6253169689Skan if (pedantic) 6254169689Skan pedwarn ("extra semicolon in struct or union specified"); 6255169689Skan c_parser_consume_token (parser); 6256169689Skan continue; 6257169689Skan } 6258169689Skan /* Stop if at the end of the instance variables. */ 6259169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 6260169689Skan { 6261169689Skan c_parser_consume_token (parser); 6262169689Skan break; 6263169689Skan } 6264169689Skan /* Parse any objc-visibility-spec. */ 6265169689Skan if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE)) 6266169689Skan { 6267169689Skan c_parser_consume_token (parser); 6268169689Skan objc_set_visibility (2); 6269169689Skan continue; 6270169689Skan } 6271169689Skan else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED)) 6272169689Skan { 6273169689Skan c_parser_consume_token (parser); 6274169689Skan objc_set_visibility (0); 6275169689Skan continue; 6276169689Skan } 6277169689Skan else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC)) 6278169689Skan { 6279169689Skan c_parser_consume_token (parser); 6280169689Skan objc_set_visibility (1); 6281169689Skan continue; 6282169689Skan } 6283260311Spfg /* APPLE LOCAL begin radar 4564694 */ 6284260311Spfg else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE)) 6285260311Spfg { 6286260311Spfg c_parser_consume_token (parser); 6287260311Spfg objc_set_visibility (3); 6288260311Spfg continue; 6289260311Spfg } 6290260311Spfg /* APPLE LOCAL end radar 4564694 */ 6291169689Skan else if (c_parser_next_token_is (parser, CPP_PRAGMA)) 6292169689Skan { 6293169689Skan c_parser_pragma (parser, pragma_external); 6294169689Skan continue; 6295169689Skan } 6296169689Skan 6297169689Skan /* Parse some comma-separated declarations. */ 6298169689Skan decls = c_parser_struct_declaration (parser); 6299169689Skan { 6300169689Skan /* Comma-separated instance variables are chained together in 6301169689Skan reverse order; add them one by one. */ 6302169689Skan tree ivar = nreverse (decls); 6303169689Skan for (; ivar; ivar = TREE_CHAIN (ivar)) 6304169689Skan objc_add_instance_variable (copy_node (ivar)); 6305169689Skan } 6306169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 6307169689Skan } 6308169689Skan} 6309169689Skan 6310169689Skan/* Parse an objc-class-declaration. 6311169689Skan 6312169689Skan objc-class-declaration: 6313169689Skan @class identifier-list ; 6314169689Skan*/ 6315169689Skan 6316169689Skanstatic void 6317169689Skanc_parser_objc_class_declaration (c_parser *parser) 6318169689Skan{ 6319169689Skan tree list = NULL_TREE; 6320169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS)); 6321169689Skan c_parser_consume_token (parser); 6322169689Skan /* Any identifiers, including those declared as type names, are OK 6323169689Skan here. */ 6324169689Skan while (true) 6325169689Skan { 6326169689Skan tree id; 6327169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6328169689Skan { 6329169689Skan c_parser_error (parser, "expected identifier"); 6330169689Skan break; 6331169689Skan } 6332169689Skan id = c_parser_peek_token (parser)->value; 6333169689Skan list = chainon (list, build_tree_list (NULL_TREE, id)); 6334169689Skan c_parser_consume_token (parser); 6335169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 6336169689Skan c_parser_consume_token (parser); 6337169689Skan else 6338169689Skan break; 6339169689Skan } 6340169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 6341169689Skan objc_declare_class (list); 6342169689Skan} 6343169689Skan 6344169689Skan/* Parse an objc-alias-declaration. 6345169689Skan 6346169689Skan objc-alias-declaration: 6347169689Skan @compatibility_alias identifier identifier ; 6348169689Skan*/ 6349169689Skan 6350169689Skanstatic void 6351169689Skanc_parser_objc_alias_declaration (c_parser *parser) 6352169689Skan{ 6353169689Skan tree id1, id2; 6354169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS)); 6355169689Skan c_parser_consume_token (parser); 6356169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6357169689Skan { 6358169689Skan c_parser_error (parser, "expected identifier"); 6359169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 6360169689Skan return; 6361169689Skan } 6362169689Skan id1 = c_parser_peek_token (parser)->value; 6363169689Skan c_parser_consume_token (parser); 6364169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6365169689Skan { 6366169689Skan c_parser_error (parser, "expected identifier"); 6367169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 6368169689Skan return; 6369169689Skan } 6370169689Skan id2 = c_parser_peek_token (parser)->value; 6371169689Skan c_parser_consume_token (parser); 6372169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 6373169689Skan objc_declare_alias (id1, id2); 6374169689Skan} 6375169689Skan 6376169689Skan/* Parse an objc-protocol-definition. 6377169689Skan 6378169689Skan objc-protocol-definition: 6379169689Skan @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end 6380169689Skan @protocol identifier-list ; 6381169689Skan 6382169689Skan "@protocol identifier ;" should be resolved as "@protocol 6383169689Skan identifier-list ;": objc-methodprotolist may not start with a 6384169689Skan semicolon in the first alternative if objc-protocol-refs are 6385169689Skan omitted. */ 6386169689Skan 6387169689Skanstatic void 6388260311Spfg/* APPLE LOCAL radar 4947311 - protocol attributes */ 6389260311Spfgc_parser_objc_protocol_definition (c_parser *parser, tree attributes) 6390169689Skan{ 6391169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL)); 6392169689Skan c_parser_consume_token (parser); 6393169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6394169689Skan { 6395169689Skan c_parser_error (parser, "expected identifier"); 6396169689Skan return; 6397169689Skan } 6398169689Skan if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 6399169689Skan || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON) 6400169689Skan { 6401169689Skan tree list = NULL_TREE; 6402169689Skan /* Any identifiers, including those declared as type names, are 6403169689Skan OK here. */ 6404169689Skan while (true) 6405169689Skan { 6406169689Skan tree id; 6407169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6408169689Skan { 6409169689Skan c_parser_error (parser, "expected identifier"); 6410169689Skan break; 6411169689Skan } 6412169689Skan id = c_parser_peek_token (parser)->value; 6413169689Skan list = chainon (list, build_tree_list (NULL_TREE, id)); 6414169689Skan c_parser_consume_token (parser); 6415169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 6416169689Skan c_parser_consume_token (parser); 6417169689Skan else 6418169689Skan break; 6419169689Skan } 6420169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 6421260311Spfg /* APPLE LOCAL radar 4947311 - protocol attributes */ 6422260311Spfg objc_declare_protocols (list, attributes); 6423169689Skan } 6424169689Skan else 6425169689Skan { 6426169689Skan tree id = c_parser_peek_token (parser)->value; 6427169689Skan tree proto = NULL_TREE; 6428169689Skan c_parser_consume_token (parser); 6429169689Skan if (c_parser_next_token_is (parser, CPP_LESS)) 6430169689Skan proto = c_parser_objc_protocol_refs (parser); 6431169689Skan objc_pq_context = 1; 6432260311Spfg /* APPLE LOCAL radar 4947311 - protocol attributes */ 6433260311Spfg objc_start_protocol (id, proto, attributes); 6434260311Spfg /* APPLE LOCAL C* property (Radar 4436866) (in 4.2 r) */ 6435260311Spfg c_parser_objc_interfacedecllist (parser); 6436169689Skan c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 6437169689Skan objc_pq_context = 0; 6438169689Skan objc_finish_interface (); 6439169689Skan } 6440169689Skan} 6441169689Skan 6442169689Skan/* Parse an objc-method-type. 6443169689Skan 6444169689Skan objc-method-type: 6445169689Skan + 6446169689Skan - 6447169689Skan*/ 6448169689Skan 6449169689Skanstatic enum tree_code 6450169689Skanc_parser_objc_method_type (c_parser *parser) 6451169689Skan{ 6452169689Skan switch (c_parser_peek_token (parser)->type) 6453169689Skan { 6454169689Skan case CPP_PLUS: 6455169689Skan c_parser_consume_token (parser); 6456169689Skan return PLUS_EXPR; 6457169689Skan case CPP_MINUS: 6458169689Skan c_parser_consume_token (parser); 6459169689Skan return MINUS_EXPR; 6460169689Skan default: 6461169689Skan gcc_unreachable (); 6462169689Skan } 6463169689Skan} 6464169689Skan 6465169689Skan/* Parse an objc-method-definition. 6466169689Skan 6467169689Skan objc-method-definition: 6468169689Skan objc-method-type objc-method-decl ;[opt] compound-statement 6469169689Skan*/ 6470169689Skan 6471169689Skanstatic void 6472169689Skanc_parser_objc_method_definition (c_parser *parser) 6473169689Skan{ 6474169689Skan enum tree_code type = c_parser_objc_method_type (parser); 6475169689Skan tree decl; 6476169689Skan objc_set_method_type (type); 6477169689Skan objc_pq_context = 1; 6478169689Skan decl = c_parser_objc_method_decl (parser); 6479169689Skan if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6480169689Skan { 6481169689Skan c_parser_consume_token (parser); 6482169689Skan if (pedantic) 6483169689Skan pedwarn ("extra semicolon in method definition specified"); 6484169689Skan } 6485169689Skan if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 6486169689Skan { 6487169689Skan c_parser_error (parser, "expected %<{%>"); 6488169689Skan return; 6489169689Skan } 6490169689Skan objc_pq_context = 0; 6491260311Spfg /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 a) */ 6492260311Spfg objc_start_method_definition (decl, objc_method_attributes); 6493260311Spfg objc_method_attributes = NULL_TREE; 6494260311Spfg /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 a) */ 6495169689Skan add_stmt (c_parser_compound_statement (parser)); 6496169689Skan objc_finish_method_definition (current_function_decl); 6497169689Skan} 6498169689Skan 6499260311Spfg/* APPLE LOCAL begin C* language (in 4.2 w) */ 6500260311Spfg/* True iff the gioven TOKEN starts a methodproto. */ 6501260311Spfg 6502260311Spfgstatic bool 6503260311Spfgc_token_starts_methodproto (c_token *token) 6504260311Spfg{ 6505260311Spfg return token->type == CPP_PLUS 6506260311Spfg || token->type == CPP_MINUS 6507260311Spfg || (token->type == CPP_KEYWORD 6508260311Spfg && (token->keyword == RID_AT_REQUIRED 6509260311Spfg || token->keyword == RID_AT_OPTIONAL)); 6510260311Spfg} 6511260311Spfg/* APPLE LOCAL end C* language (in 4.2 w) */ 6512260311Spfg 6513169689Skan/* Parse an objc-methodprotolist. 6514169689Skan 6515169689Skan objc-methodprotolist: 6516169689Skan empty 6517169689Skan objc-methodprotolist objc-methodproto 6518169689Skan objc-methodprotolist declaration 6519169689Skan objc-methodprotolist ; 6520169689Skan 6521169689Skan The declaration is a data definition, which may be missing 6522169689Skan declaration specifiers under the same rules and diagnostics as 6523169689Skan other data definitions outside functions, and the stray semicolon 6524169689Skan is diagnosed the same way as a stray semicolon outside a 6525169689Skan function. */ 6526169689Skan 6527169689Skanstatic void 6528260311Spfg/* APPLE LOCAL C* property (Radar 4436866) (in 4.2 b) */ 6529260311Spfgc_parser_objc_interfacedecllist (c_parser *parser) 6530169689Skan{ 6531169689Skan while (true) 6532169689Skan { 6533260311Spfg /* APPLE LOCAL begin C* property (Radar 4436866) (in 4.2 b) */ 6534260311Spfg c_token *token; 6535260311Spfg token = c_parser_peek_token (parser); 6536260311Spfg if (token->type == CPP_KEYWORD 6537260311Spfg && token->keyword == RID_AT_PROPERTY) 6538260311Spfg { 6539260311Spfg c_parser_objc_property_declaration (parser); 6540260311Spfg continue; 6541260311Spfg } 6542260311Spfg /* APPLE LOCAL end C* property (Radar 4436866) (in 4.2 b) */ 6543260311Spfg /* APPLE LOCAL begin C* language (in 4.2 w) */ 6544260311Spfg if (c_token_starts_methodproto (token)) 6545260311Spfg { 6546260311Spfg c_parser_objc_methodproto (parser); 6547260311Spfg continue; 6548260311Spfg } 6549260311Spfg /* APPLE LOCAL end C* language (in 4.2 w) */ 6550260311Spfg 6551169689Skan /* The list is terminated by @end. */ 6552169689Skan switch (c_parser_peek_token (parser)->type) 6553169689Skan { 6554169689Skan case CPP_SEMICOLON: 6555169689Skan if (pedantic) 6556169689Skan pedwarn ("ISO C does not allow extra %<;%> outside of a function"); 6557169689Skan c_parser_consume_token (parser); 6558169689Skan break; 6559260311Spfg /* APPLE LOCAL begin C* language (in 4.2 w) */ 6560260311Spfg /* CPP_PLUS and CPP_MINUS deleted */ 6561260311Spfg /* APPLE LOCAL end C* language (in 4.2 w) */ 6562169689Skan case CPP_PRAGMA: 6563169689Skan c_parser_pragma (parser, pragma_external); 6564169689Skan break; 6565169689Skan case CPP_EOF: 6566169689Skan return; 6567169689Skan default: 6568169689Skan if (c_parser_next_token_is_keyword (parser, RID_AT_END)) 6569169689Skan return; 6570260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 6571260311Spfg c_parser_declaration_or_fndef (parser, false, true, false, true, NULL); 6572169689Skan break; 6573169689Skan } 6574169689Skan } 6575169689Skan} 6576169689Skan 6577169689Skan/* Parse an objc-methodproto. 6578169689Skan 6579169689Skan objc-methodproto: 6580169689Skan objc-method-type objc-method-decl ; 6581169689Skan*/ 6582169689Skan 6583169689Skanstatic void 6584169689Skanc_parser_objc_methodproto (c_parser *parser) 6585169689Skan{ 6586260311Spfg /* APPLE LOCAL C* language */ 6587260311Spfg enum tree_code type; 6588169689Skan tree decl; 6589260311Spfg /* APPLE LOCAL begin C* language */ 6590260311Spfg if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED)) 6591260311Spfg { 6592260311Spfg objc_set_method_opt (0); 6593260311Spfg c_parser_consume_token (parser); 6594260311Spfg return; 6595260311Spfg } 6596260311Spfg if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL)) 6597260311Spfg { 6598260311Spfg objc_set_method_opt (1); 6599260311Spfg c_parser_consume_token (parser); 6600260311Spfg return; 6601260311Spfg } 6602260311Spfg /* APPLE LOCAL begin C* language */ 6603260311Spfg /* APPLE LOCAL C* language */ 6604260311Spfg type = c_parser_objc_method_type (parser); 6605169689Skan objc_set_method_type (type); 6606169689Skan /* Remember protocol qualifiers in prototypes. */ 6607169689Skan objc_pq_context = 1; 6608169689Skan decl = c_parser_objc_method_decl (parser); 6609169689Skan /* Forget protocol qualifiers here. */ 6610169689Skan objc_pq_context = 0; 6611260311Spfg /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 c) */ 6612260311Spfg objc_add_method_declaration (decl, objc_method_attributes); 6613260311Spfg objc_method_attributes = NULL_TREE; 6614260311Spfg /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 c) */ 6615169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 6616169689Skan} 6617169689Skan 6618169689Skan/* Parse an objc-method-decl. 6619169689Skan 6620169689Skan objc-method-decl: 6621169689Skan ( objc-type-name ) objc-selector 6622169689Skan objc-selector 6623169689Skan ( objc-type-name ) objc-keyword-selector objc-optparmlist 6624169689Skan objc-keyword-selector objc-optparmlist 6625169689Skan 6626169689Skan objc-keyword-selector: 6627169689Skan objc-keyword-decl 6628169689Skan objc-keyword-selector objc-keyword-decl 6629169689Skan 6630169689Skan objc-keyword-decl: 6631169689Skan objc-selector : ( objc-type-name ) identifier 6632169689Skan objc-selector : identifier 6633169689Skan : ( objc-type-name ) identifier 6634169689Skan : identifier 6635169689Skan 6636169689Skan objc-optparmlist: 6637169689Skan objc-optparms objc-optellipsis 6638169689Skan 6639169689Skan objc-optparms: 6640169689Skan empty 6641169689Skan objc-opt-parms , parameter-declaration 6642169689Skan 6643169689Skan objc-optellipsis: 6644169689Skan empty 6645169689Skan , ... 6646169689Skan*/ 6647169689Skan 6648169689Skanstatic tree 6649169689Skanc_parser_objc_method_decl (c_parser *parser) 6650169689Skan{ 6651169689Skan tree type = NULL_TREE; 6652169689Skan tree sel; 6653169689Skan tree parms = NULL_TREE; 6654169689Skan bool ellipsis = false; 6655169689Skan 6656169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 6657169689Skan { 6658169689Skan c_parser_consume_token (parser); 6659169689Skan type = c_parser_objc_type_name (parser); 6660169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 6661169689Skan } 6662169689Skan sel = c_parser_objc_selector (parser); 6663169689Skan /* If there is no selector, or a colon follows, we have an 6664169689Skan objc-keyword-selector. If there is a selector, and a colon does 6665169689Skan not follow, that selector ends the objc-method-decl. */ 6666169689Skan if (!sel || c_parser_next_token_is (parser, CPP_COLON)) 6667169689Skan { 6668169689Skan tree tsel = sel; 6669169689Skan tree list = NULL_TREE; 6670169689Skan while (true) 6671169689Skan { 6672260311Spfg /* APPLE LOCAL radar 4157812 */ 6673260311Spfg tree attr = NULL_TREE; 6674169689Skan tree atype = NULL_TREE, id, keyworddecl; 6675169689Skan if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 6676169689Skan break; 6677169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 6678169689Skan { 6679169689Skan c_parser_consume_token (parser); 6680169689Skan atype = c_parser_objc_type_name (parser); 6681169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 6682169689Skan "expected %<)%>"); 6683169689Skan } 6684260311Spfg /* APPLE LOCAL begin radar 4157812 */ 6685260311Spfg if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 6686260311Spfg attr = c_parser_attributes (parser); 6687260311Spfg /* APPLE LOCAL end radar 4157812 */ 6688169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6689169689Skan { 6690169689Skan c_parser_error (parser, "expected identifier"); 6691169689Skan return error_mark_node; 6692169689Skan } 6693169689Skan id = c_parser_peek_token (parser)->value; 6694169689Skan c_parser_consume_token (parser); 6695260311Spfg /* APPLE LOCAL radar 4157812 */ 6696260311Spfg keyworddecl = objc_build_keyword_decl (tsel, atype, id, attr); 6697169689Skan list = chainon (list, keyworddecl); 6698169689Skan tsel = c_parser_objc_selector (parser); 6699169689Skan if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON)) 6700169689Skan break; 6701169689Skan } 6702260311Spfg /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 y) */ 6703260311Spfg if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 6704260311Spfg objc_method_attributes = c_parser_attributes (parser); 6705260311Spfg /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */ 6706169689Skan /* Parse the optional parameter list. Optional Objective-C 6707169689Skan method parameters follow the C syntax, and may include '...' 6708169689Skan to denote a variable number of arguments. */ 6709169689Skan parms = make_node (TREE_LIST); 6710169689Skan while (c_parser_next_token_is (parser, CPP_COMMA)) 6711169689Skan { 6712169689Skan struct c_parm *parm; 6713169689Skan c_parser_consume_token (parser); 6714169689Skan if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 6715169689Skan { 6716169689Skan ellipsis = true; 6717169689Skan c_parser_consume_token (parser); 6718260311Spfg /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */ 6719260311Spfg if (objc_method_attributes) 6720260311Spfg error ("method attributes must be specified at the end only"); 6721260311Spfg if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 6722260311Spfg objc_method_attributes = c_parser_attributes (parser); 6723260311Spfg /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */ 6724169689Skan break; 6725169689Skan } 6726169689Skan parm = c_parser_parameter_declaration (parser, NULL_TREE); 6727169689Skan if (parm == NULL) 6728169689Skan break; 6729169689Skan parms = chainon (parms, 6730169689Skan build_tree_list (NULL_TREE, grokparm (parm))); 6731169689Skan } 6732169689Skan sel = list; 6733169689Skan } 6734260311Spfg /* APPLE LOCAL begin radar 3803157 - objc attribute (in 4.2 y) */ 6735260311Spfg else 6736260311Spfg { 6737260311Spfg gcc_assert (objc_method_attributes == NULL_TREE); 6738260311Spfg if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 6739260311Spfg objc_method_attributes = c_parser_attributes (parser); 6740260311Spfg } 6741260311Spfg /* APPLE LOCAL end radar 3803157 - objc attribute (in 4.2 y) */ 6742260311Spfg /* APPLE LOCAL begin radar 4157812 */ 6743260311Spfg if (sel == NULL) 6744260311Spfg { 6745260311Spfg c_parser_error (parser, "objective-c method declaration is expected"); 6746260311Spfg return error_mark_node; 6747260311Spfg } 6748260311Spfg /* APPLE LOCAL end radar 4157812 */ 6749169689Skan return objc_build_method_signature (type, sel, parms, ellipsis); 6750169689Skan} 6751169689Skan 6752169689Skan/* Parse an objc-type-name. 6753169689Skan 6754169689Skan objc-type-name: 6755169689Skan objc-type-qualifiers[opt] type-name 6756169689Skan objc-type-qualifiers[opt] 6757169689Skan 6758169689Skan objc-type-qualifiers: 6759169689Skan objc-type-qualifier 6760169689Skan objc-type-qualifiers objc-type-qualifier 6761169689Skan 6762169689Skan objc-type-qualifier: one of 6763169689Skan in out inout bycopy byref oneway 6764169689Skan*/ 6765169689Skan 6766169689Skanstatic tree 6767169689Skanc_parser_objc_type_name (c_parser *parser) 6768169689Skan{ 6769169689Skan tree quals = NULL_TREE; 6770169689Skan struct c_type_name *typename = NULL; 6771169689Skan tree type = NULL_TREE; 6772169689Skan while (true) 6773169689Skan { 6774169689Skan c_token *token = c_parser_peek_token (parser); 6775169689Skan if (token->type == CPP_KEYWORD 6776169689Skan && (token->keyword == RID_IN 6777169689Skan || token->keyword == RID_OUT 6778169689Skan || token->keyword == RID_INOUT 6779169689Skan || token->keyword == RID_BYCOPY 6780169689Skan || token->keyword == RID_BYREF 6781169689Skan || token->keyword == RID_ONEWAY)) 6782169689Skan { 6783260311Spfg /* APPLE LOCAL radar 4301047 (in 4.2 z) */ 6784260311Spfg quals = chainon (build_tree_list (NULL_TREE, token->value), quals); 6785169689Skan c_parser_consume_token (parser); 6786169689Skan } 6787169689Skan else 6788169689Skan break; 6789169689Skan } 6790169689Skan if (c_parser_next_token_starts_typename (parser)) 6791169689Skan typename = c_parser_type_name (parser); 6792169689Skan if (typename) 6793169689Skan type = groktypename (typename); 6794169689Skan return build_tree_list (quals, type); 6795169689Skan} 6796169689Skan 6797169689Skan/* Parse objc-protocol-refs. 6798169689Skan 6799169689Skan objc-protocol-refs: 6800169689Skan < identifier-list > 6801169689Skan*/ 6802169689Skan 6803169689Skanstatic tree 6804169689Skanc_parser_objc_protocol_refs (c_parser *parser) 6805169689Skan{ 6806169689Skan tree list = NULL_TREE; 6807169689Skan gcc_assert (c_parser_next_token_is (parser, CPP_LESS)); 6808169689Skan c_parser_consume_token (parser); 6809169689Skan /* Any identifiers, including those declared as type names, are OK 6810169689Skan here. */ 6811169689Skan while (true) 6812169689Skan { 6813169689Skan tree id; 6814169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME)) 6815169689Skan { 6816169689Skan c_parser_error (parser, "expected identifier"); 6817169689Skan break; 6818169689Skan } 6819169689Skan id = c_parser_peek_token (parser)->value; 6820169689Skan list = chainon (list, build_tree_list (NULL_TREE, id)); 6821169689Skan c_parser_consume_token (parser); 6822169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 6823169689Skan c_parser_consume_token (parser); 6824169689Skan else 6825169689Skan break; 6826169689Skan } 6827169689Skan c_parser_require (parser, CPP_GREATER, "expected %<>%>"); 6828169689Skan return list; 6829169689Skan} 6830169689Skan 6831169689Skan/* Parse an objc-try-catch-statement. 6832169689Skan 6833169689Skan objc-try-catch-statement: 6834169689Skan @try compound-statement objc-catch-list[opt] 6835169689Skan @try compound-statement objc-catch-list[opt] @finally compound-statement 6836169689Skan 6837169689Skan objc-catch-list: 6838169689Skan @catch ( parameter-declaration ) compound-statement 6839169689Skan objc-catch-list @catch ( parameter-declaration ) compound-statement 6840169689Skan*/ 6841169689Skan 6842169689Skanstatic void 6843169689Skanc_parser_objc_try_catch_statement (c_parser *parser) 6844169689Skan{ 6845169689Skan location_t loc; 6846169689Skan tree stmt; 6847169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY)); 6848169689Skan c_parser_consume_token (parser); 6849169689Skan loc = c_parser_peek_token (parser)->location; 6850169689Skan stmt = c_parser_compound_statement (parser); 6851169689Skan objc_begin_try_stmt (loc, stmt); 6852169689Skan while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH)) 6853169689Skan { 6854169689Skan struct c_parm *parm; 6855169689Skan c_parser_consume_token (parser); 6856169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 6857169689Skan break; 6858260311Spfg /* APPLE LOCAL begin radar 2848255 */ 6859260311Spfg if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 6860169689Skan { 6861260311Spfg /* @catch (...) */ 6862260311Spfg c_parser_consume_token (parser); 6863260311Spfg c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 6864260311Spfg objc_begin_catch_clause (NULL_TREE); 6865169689Skan } 6866260311Spfg else 6867260311Spfg { 6868260311Spfg parm = c_parser_parameter_declaration (parser, NULL_TREE); 6869260311Spfg if (parm == NULL) 6870260311Spfg { 6871260311Spfg c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 6872260311Spfg break; 6873260311Spfg } 6874260311Spfg c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 6875260311Spfg objc_begin_catch_clause (grokparm (parm)); 6876260311Spfg } 6877260311Spfg /* APPLE LOCAL end radar 2848255 */ 6878169689Skan if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 6879169689Skan c_parser_compound_statement_nostart (parser); 6880169689Skan objc_finish_catch_clause (); 6881169689Skan } 6882169689Skan if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY)) 6883169689Skan { 6884169689Skan location_t finloc; 6885169689Skan tree finstmt; 6886169689Skan c_parser_consume_token (parser); 6887169689Skan finloc = c_parser_peek_token (parser)->location; 6888169689Skan finstmt = c_parser_compound_statement (parser); 6889169689Skan objc_build_finally_clause (finloc, finstmt); 6890169689Skan } 6891169689Skan objc_finish_try_stmt (); 6892169689Skan} 6893169689Skan 6894260311Spfg/* APPLE LOCAL begin radar 5982990 */ 6895260311Spfg/* This routine is called from c_parser_objc_synchronized_statement 6896260311Spfg and is identical to c_parser_compound_statement with 6897260311Spfg the addition of volatizing local variables seen in the scope 6898260311Spfg of @synchroniz block. 6899260311Spfg*/ 6900260311Spfgstatic tree 6901260311Spfgc_parser_objc_synch_compound_statement (c_parser *parser) 6902260311Spfg{ 6903260311Spfg tree stmt; 6904260311Spfg if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 6905260311Spfg return error_mark_node; 6906260311Spfg stmt = c_begin_compound_stmt (true); 6907260311Spfg c_parser_compound_statement_nostart (parser); 6908260311Spfg if (flag_objc_sjlj_exceptions) 6909260311Spfg objc_mark_locals_volatile (NULL); 6910260311Spfg return c_end_compound_stmt (stmt, true); 6911260311Spfg} 6912260311Spfg/* APPLE LOCAL end radar 5982990 */ 6913260311Spfg 6914169689Skan/* Parse an objc-synchronized-statement. 6915169689Skan 6916169689Skan objc-synchronized-statement: 6917169689Skan @synchronized ( expression ) compound-statement 6918169689Skan*/ 6919169689Skan 6920169689Skanstatic void 6921169689Skanc_parser_objc_synchronized_statement (c_parser *parser) 6922169689Skan{ 6923169689Skan location_t loc; 6924169689Skan tree expr, stmt; 6925169689Skan gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED)); 6926169689Skan c_parser_consume_token (parser); 6927169689Skan loc = c_parser_peek_token (parser)->location; 6928169689Skan if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 6929169689Skan { 6930169689Skan expr = c_parser_expression (parser).value; 6931169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 6932169689Skan } 6933169689Skan else 6934169689Skan expr = error_mark_node; 6935260311Spfg /* APPLE LOCAL radar 5982990 */ 6936260311Spfg stmt = c_parser_objc_synch_compound_statement (parser); 6937169689Skan objc_build_synchronized (loc, expr, stmt); 6938169689Skan} 6939169689Skan 6940169689Skan/* Parse an objc-selector; return NULL_TREE without an error if the 6941169689Skan next token is not an objc-selector. 6942169689Skan 6943169689Skan objc-selector: 6944169689Skan identifier 6945169689Skan one of 6946169689Skan enum struct union if else while do for switch case default 6947169689Skan break continue return goto asm sizeof typeof __alignof 6948169689Skan unsigned long const short volatile signed restrict _Complex 6949169689Skan in out inout bycopy byref oneway int char float double void _Bool 6950169689Skan 6951169689Skan ??? Why this selection of keywords but not, for example, storage 6952169689Skan class specifiers? */ 6953169689Skan 6954169689Skanstatic tree 6955169689Skanc_parser_objc_selector (c_parser *parser) 6956169689Skan{ 6957169689Skan c_token *token = c_parser_peek_token (parser); 6958169689Skan tree value = token->value; 6959169689Skan if (token->type == CPP_NAME) 6960169689Skan { 6961169689Skan c_parser_consume_token (parser); 6962169689Skan return value; 6963169689Skan } 6964169689Skan if (token->type != CPP_KEYWORD) 6965169689Skan return NULL_TREE; 6966169689Skan switch (token->keyword) 6967169689Skan { 6968169689Skan case RID_ENUM: 6969169689Skan case RID_STRUCT: 6970169689Skan case RID_UNION: 6971169689Skan case RID_IF: 6972169689Skan case RID_ELSE: 6973169689Skan case RID_WHILE: 6974169689Skan case RID_DO: 6975169689Skan case RID_FOR: 6976169689Skan case RID_SWITCH: 6977169689Skan case RID_CASE: 6978169689Skan case RID_DEFAULT: 6979169689Skan case RID_BREAK: 6980169689Skan case RID_CONTINUE: 6981169689Skan case RID_RETURN: 6982169689Skan case RID_GOTO: 6983169689Skan case RID_ASM: 6984169689Skan case RID_SIZEOF: 6985169689Skan case RID_TYPEOF: 6986169689Skan case RID_ALIGNOF: 6987169689Skan case RID_UNSIGNED: 6988169689Skan case RID_LONG: 6989169689Skan case RID_CONST: 6990169689Skan case RID_SHORT: 6991169689Skan case RID_VOLATILE: 6992169689Skan case RID_SIGNED: 6993169689Skan case RID_RESTRICT: 6994169689Skan case RID_COMPLEX: 6995169689Skan case RID_IN: 6996169689Skan case RID_OUT: 6997169689Skan case RID_INOUT: 6998169689Skan case RID_BYCOPY: 6999169689Skan case RID_BYREF: 7000169689Skan case RID_ONEWAY: 7001169689Skan case RID_INT: 7002169689Skan case RID_CHAR: 7003169689Skan case RID_FLOAT: 7004169689Skan case RID_DOUBLE: 7005169689Skan case RID_VOID: 7006169689Skan case RID_BOOL: 7007169689Skan c_parser_consume_token (parser); 7008169689Skan return value; 7009169689Skan default: 7010169689Skan return NULL_TREE; 7011169689Skan } 7012169689Skan} 7013169689Skan 7014169689Skan/* Parse an objc-selector-arg. 7015169689Skan 7016169689Skan objc-selector-arg: 7017169689Skan objc-selector 7018169689Skan objc-keywordname-list 7019169689Skan 7020169689Skan objc-keywordname-list: 7021169689Skan objc-keywordname 7022169689Skan objc-keywordname-list objc-keywordname 7023169689Skan 7024169689Skan objc-keywordname: 7025169689Skan objc-selector : 7026169689Skan : 7027169689Skan*/ 7028169689Skan 7029169689Skanstatic tree 7030169689Skanc_parser_objc_selector_arg (c_parser *parser) 7031169689Skan{ 7032169689Skan tree sel = c_parser_objc_selector (parser); 7033169689Skan tree list = NULL_TREE; 7034169689Skan if (sel && c_parser_next_token_is_not (parser, CPP_COLON)) 7035169689Skan return sel; 7036169689Skan while (true) 7037169689Skan { 7038169689Skan if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 7039169689Skan return list; 7040169689Skan list = chainon (list, build_tree_list (sel, NULL_TREE)); 7041169689Skan sel = c_parser_objc_selector (parser); 7042169689Skan if (!sel && c_parser_next_token_is_not (parser, CPP_COLON)) 7043169689Skan break; 7044169689Skan } 7045169689Skan return list; 7046169689Skan} 7047169689Skan 7048169689Skan/* Parse an objc-receiver. 7049169689Skan 7050169689Skan objc-receiver: 7051169689Skan expression 7052169689Skan class-name 7053169689Skan type-name 7054169689Skan*/ 7055169689Skan 7056169689Skanstatic tree 7057169689Skanc_parser_objc_receiver (c_parser *parser) 7058169689Skan{ 7059169689Skan if (c_parser_peek_token (parser)->type == CPP_NAME 7060169689Skan && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME 7061169689Skan || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) 7062169689Skan { 7063169689Skan tree id = c_parser_peek_token (parser)->value; 7064169689Skan c_parser_consume_token (parser); 7065169689Skan return objc_get_class_reference (id); 7066169689Skan } 7067169689Skan return c_parser_expression (parser).value; 7068169689Skan} 7069169689Skan 7070169689Skan/* Parse objc-message-args. 7071169689Skan 7072169689Skan objc-message-args: 7073169689Skan objc-selector 7074169689Skan objc-keywordarg-list 7075169689Skan 7076169689Skan objc-keywordarg-list: 7077169689Skan objc-keywordarg 7078169689Skan objc-keywordarg-list objc-keywordarg 7079169689Skan 7080169689Skan objc-keywordarg: 7081169689Skan objc-selector : objc-keywordexpr 7082169689Skan : objc-keywordexpr 7083169689Skan*/ 7084169689Skan 7085169689Skanstatic tree 7086169689Skanc_parser_objc_message_args (c_parser *parser) 7087169689Skan{ 7088169689Skan tree sel = c_parser_objc_selector (parser); 7089169689Skan tree list = NULL_TREE; 7090169689Skan if (sel && c_parser_next_token_is_not (parser, CPP_COLON)) 7091169689Skan return sel; 7092169689Skan while (true) 7093169689Skan { 7094169689Skan tree keywordexpr; 7095169689Skan if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 7096169689Skan return list; 7097169689Skan keywordexpr = c_parser_objc_keywordexpr (parser); 7098169689Skan list = chainon (list, build_tree_list (sel, keywordexpr)); 7099169689Skan sel = c_parser_objc_selector (parser); 7100169689Skan if (!sel && c_parser_next_token_is_not (parser, CPP_COLON)) 7101169689Skan break; 7102169689Skan } 7103169689Skan return list; 7104169689Skan} 7105169689Skan 7106169689Skan/* Parse an objc-keywordexpr. 7107169689Skan 7108169689Skan objc-keywordexpr: 7109169689Skan nonempty-expr-list 7110169689Skan*/ 7111169689Skan 7112169689Skanstatic tree 7113169689Skanc_parser_objc_keywordexpr (c_parser *parser) 7114169689Skan{ 7115169689Skan tree list = c_parser_expr_list (parser, true); 7116169689Skan if (TREE_CHAIN (list) == NULL_TREE) 7117169689Skan { 7118169689Skan /* Just return the expression, remove a level of 7119169689Skan indirection. */ 7120169689Skan return TREE_VALUE (list); 7121169689Skan } 7122169689Skan else 7123169689Skan { 7124169689Skan /* We have a comma expression, we will collapse later. */ 7125169689Skan return list; 7126169689Skan } 7127169689Skan} 7128169689Skan 7129169689Skan 7130169689Skan/* Handle pragmas. Some OpenMP pragmas are associated with, and therefore 7131169689Skan should be considered, statements. ALLOW_STMT is true if we're within 7132169689Skan the context of a function and such pragmas are to be allowed. Returns 7133169689Skan true if we actually parsed such a pragma. */ 7134169689Skan 7135169689Skanstatic bool 7136169689Skanc_parser_pragma (c_parser *parser, enum pragma_context context) 7137169689Skan{ 7138169689Skan unsigned int id; 7139169689Skan 7140169689Skan id = c_parser_peek_token (parser)->pragma_kind; 7141169689Skan gcc_assert (id != PRAGMA_NONE); 7142169689Skan 7143169689Skan switch (id) 7144169689Skan { 7145169689Skan case PRAGMA_OMP_BARRIER: 7146169689Skan if (context != pragma_compound) 7147169689Skan { 7148169689Skan if (context == pragma_stmt) 7149169689Skan c_parser_error (parser, "%<#pragma omp barrier%> may only be " 7150169689Skan "used in compound statements"); 7151169689Skan goto bad_stmt; 7152169689Skan } 7153169689Skan c_parser_omp_barrier (parser); 7154169689Skan return false; 7155169689Skan 7156169689Skan case PRAGMA_OMP_FLUSH: 7157169689Skan if (context != pragma_compound) 7158169689Skan { 7159169689Skan if (context == pragma_stmt) 7160169689Skan c_parser_error (parser, "%<#pragma omp flush%> may only be " 7161169689Skan "used in compound statements"); 7162169689Skan goto bad_stmt; 7163169689Skan } 7164169689Skan c_parser_omp_flush (parser); 7165169689Skan return false; 7166169689Skan 7167169689Skan case PRAGMA_OMP_THREADPRIVATE: 7168169689Skan c_parser_omp_threadprivate (parser); 7169169689Skan return false; 7170169689Skan 7171169689Skan case PRAGMA_OMP_SECTION: 7172169689Skan error ("%<#pragma omp section%> may only be used in " 7173169689Skan "%<#pragma omp sections%> construct"); 7174169689Skan c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 7175169689Skan return false; 7176169689Skan 7177169689Skan case PRAGMA_GCC_PCH_PREPROCESS: 7178169689Skan c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first"); 7179169689Skan c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 7180169689Skan return false; 7181169689Skan 7182169689Skan default: 7183169689Skan if (id < PRAGMA_FIRST_EXTERNAL) 7184169689Skan { 7185169689Skan if (context == pragma_external) 7186169689Skan { 7187169689Skan bad_stmt: 7188169689Skan c_parser_error (parser, "expected declaration specifiers"); 7189169689Skan c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 7190169689Skan return false; 7191169689Skan } 7192169689Skan c_parser_omp_construct (parser); 7193169689Skan return true; 7194169689Skan } 7195169689Skan break; 7196169689Skan } 7197169689Skan 7198169689Skan c_parser_consume_pragma (parser); 7199169689Skan c_invoke_pragma_handler (id); 7200169689Skan 7201169689Skan /* Skip to EOL, but suppress any error message. Those will have been 7202169689Skan generated by the handler routine through calling error, as opposed 7203169689Skan to calling c_parser_error. */ 7204169689Skan parser->error = true; 7205169689Skan c_parser_skip_to_pragma_eol (parser); 7206169689Skan 7207169689Skan return false; 7208169689Skan} 7209169689Skan 7210169689Skan/* The interface the pragma parsers have to the lexer. */ 7211169689Skan 7212169689Skanenum cpp_ttype 7213169689Skanpragma_lex (tree *value) 7214169689Skan{ 7215169689Skan c_token *tok = c_parser_peek_token (the_parser); 7216169689Skan enum cpp_ttype ret = tok->type; 7217169689Skan 7218169689Skan *value = tok->value; 7219169689Skan if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF) 7220169689Skan ret = CPP_EOF; 7221169689Skan else 7222169689Skan { 7223169689Skan if (ret == CPP_KEYWORD) 7224169689Skan ret = CPP_NAME; 7225169689Skan c_parser_consume_token (the_parser); 7226169689Skan } 7227169689Skan 7228169689Skan return ret; 7229169689Skan} 7230169689Skan 7231169689Skanstatic void 7232169689Skanc_parser_pragma_pch_preprocess (c_parser *parser) 7233169689Skan{ 7234169689Skan tree name = NULL; 7235169689Skan 7236169689Skan c_parser_consume_pragma (parser); 7237169689Skan if (c_parser_next_token_is (parser, CPP_STRING)) 7238169689Skan { 7239169689Skan name = c_parser_peek_token (parser)->value; 7240169689Skan c_parser_consume_token (parser); 7241169689Skan } 7242169689Skan else 7243169689Skan c_parser_error (parser, "expected string literal"); 7244169689Skan c_parser_skip_to_pragma_eol (parser); 7245169689Skan 7246169689Skan if (name) 7247169689Skan c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name)); 7248169689Skan} 7249169689Skan 7250169689Skan/* OpenMP 2.5 parsing routines. */ 7251169689Skan 7252169689Skan/* Returns name of the next clause. 7253169689Skan If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and 7254169689Skan the token is not consumed. Otherwise appropriate pragma_omp_clause is 7255169689Skan returned and the token is consumed. */ 7256169689Skan 7257169689Skanstatic pragma_omp_clause 7258169689Skanc_parser_omp_clause_name (c_parser *parser) 7259169689Skan{ 7260169689Skan pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE; 7261169689Skan 7262169689Skan if (c_parser_next_token_is_keyword (parser, RID_IF)) 7263169689Skan result = PRAGMA_OMP_CLAUSE_IF; 7264169689Skan else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 7265169689Skan result = PRAGMA_OMP_CLAUSE_DEFAULT; 7266169689Skan else if (c_parser_next_token_is (parser, CPP_NAME)) 7267169689Skan { 7268169689Skan const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 7269169689Skan 7270169689Skan switch (p[0]) 7271169689Skan { 7272169689Skan case 'c': 7273169689Skan if (!strcmp ("copyin", p)) 7274169689Skan result = PRAGMA_OMP_CLAUSE_COPYIN; 7275169689Skan else if (!strcmp ("copyprivate", p)) 7276169689Skan result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; 7277169689Skan break; 7278169689Skan case 'f': 7279169689Skan if (!strcmp ("firstprivate", p)) 7280169689Skan result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE; 7281169689Skan break; 7282169689Skan case 'l': 7283169689Skan if (!strcmp ("lastprivate", p)) 7284169689Skan result = PRAGMA_OMP_CLAUSE_LASTPRIVATE; 7285169689Skan break; 7286169689Skan case 'n': 7287169689Skan if (!strcmp ("nowait", p)) 7288169689Skan result = PRAGMA_OMP_CLAUSE_NOWAIT; 7289169689Skan else if (!strcmp ("num_threads", p)) 7290169689Skan result = PRAGMA_OMP_CLAUSE_NUM_THREADS; 7291169689Skan break; 7292169689Skan case 'o': 7293169689Skan if (!strcmp ("ordered", p)) 7294169689Skan result = PRAGMA_OMP_CLAUSE_ORDERED; 7295169689Skan break; 7296169689Skan case 'p': 7297169689Skan if (!strcmp ("private", p)) 7298169689Skan result = PRAGMA_OMP_CLAUSE_PRIVATE; 7299169689Skan break; 7300169689Skan case 'r': 7301169689Skan if (!strcmp ("reduction", p)) 7302169689Skan result = PRAGMA_OMP_CLAUSE_REDUCTION; 7303169689Skan break; 7304169689Skan case 's': 7305169689Skan if (!strcmp ("schedule", p)) 7306169689Skan result = PRAGMA_OMP_CLAUSE_SCHEDULE; 7307169689Skan else if (!strcmp ("shared", p)) 7308169689Skan result = PRAGMA_OMP_CLAUSE_SHARED; 7309169689Skan break; 7310169689Skan } 7311169689Skan } 7312169689Skan 7313169689Skan if (result != PRAGMA_OMP_CLAUSE_NONE) 7314169689Skan c_parser_consume_token (parser); 7315169689Skan 7316169689Skan return result; 7317169689Skan} 7318169689Skan 7319169689Skan/* Validate that a clause of the given type does not already exist. */ 7320169689Skan 7321169689Skanstatic void 7322169689Skancheck_no_duplicate_clause (tree clauses, enum tree_code code, const char *name) 7323169689Skan{ 7324169689Skan tree c; 7325169689Skan 7326169689Skan for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) 7327169689Skan if (OMP_CLAUSE_CODE (c) == code) 7328169689Skan { 7329169689Skan error ("too many %qs clauses", name); 7330169689Skan break; 7331169689Skan } 7332169689Skan} 7333169689Skan 7334169689Skan/* OpenMP 2.5: 7335169689Skan variable-list: 7336169689Skan identifier 7337169689Skan variable-list , identifier 7338169689Skan 7339169689Skan If KIND is nonzero, create the appropriate node and install the decl 7340169689Skan in OMP_CLAUSE_DECL and add the node to the head of the list. 7341169689Skan 7342169689Skan If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE; 7343169689Skan return the list created. */ 7344169689Skan 7345169689Skanstatic tree 7346169689Skanc_parser_omp_variable_list (c_parser *parser, enum omp_clause_code kind, 7347169689Skan tree list) 7348169689Skan{ 7349169689Skan if (c_parser_next_token_is_not (parser, CPP_NAME) 7350169689Skan || c_parser_peek_token (parser)->id_kind != C_ID_ID) 7351169689Skan c_parser_error (parser, "expected identifier"); 7352169689Skan 7353169689Skan while (c_parser_next_token_is (parser, CPP_NAME) 7354169689Skan && c_parser_peek_token (parser)->id_kind == C_ID_ID) 7355169689Skan { 7356169689Skan tree t = lookup_name (c_parser_peek_token (parser)->value); 7357169689Skan 7358169689Skan if (t == NULL_TREE) 7359169689Skan undeclared_variable (c_parser_peek_token (parser)->value, 7360169689Skan c_parser_peek_token (parser)->location); 7361169689Skan else if (t == error_mark_node) 7362169689Skan ; 7363169689Skan else if (kind != 0) 7364169689Skan { 7365169689Skan tree u = build_omp_clause (kind); 7366169689Skan OMP_CLAUSE_DECL (u) = t; 7367169689Skan OMP_CLAUSE_CHAIN (u) = list; 7368169689Skan list = u; 7369169689Skan } 7370169689Skan else 7371169689Skan list = tree_cons (t, NULL_TREE, list); 7372169689Skan 7373169689Skan c_parser_consume_token (parser); 7374169689Skan 7375169689Skan if (c_parser_next_token_is_not (parser, CPP_COMMA)) 7376169689Skan break; 7377169689Skan 7378169689Skan c_parser_consume_token (parser); 7379169689Skan } 7380169689Skan 7381169689Skan return list; 7382169689Skan} 7383169689Skan 7384169689Skan/* Similarly, but expect leading and trailing parenthesis. This is a very 7385169689Skan common case for omp clauses. */ 7386169689Skan 7387169689Skanstatic tree 7388169689Skanc_parser_omp_var_list_parens (c_parser *parser, enum tree_code kind, tree list) 7389169689Skan{ 7390169689Skan if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 7391169689Skan { 7392169689Skan list = c_parser_omp_variable_list (parser, kind, list); 7393169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 7394169689Skan } 7395169689Skan return list; 7396169689Skan} 7397169689Skan 7398169689Skan/* OpenMP 2.5: 7399169689Skan copyin ( variable-list ) */ 7400169689Skan 7401169689Skanstatic tree 7402169689Skanc_parser_omp_clause_copyin (c_parser *parser, tree list) 7403169689Skan{ 7404169689Skan return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list); 7405169689Skan} 7406169689Skan 7407169689Skan/* OpenMP 2.5: 7408169689Skan copyprivate ( variable-list ) */ 7409169689Skan 7410169689Skanstatic tree 7411169689Skanc_parser_omp_clause_copyprivate (c_parser *parser, tree list) 7412169689Skan{ 7413169689Skan return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list); 7414169689Skan} 7415169689Skan 7416169689Skan/* OpenMP 2.5: 7417169689Skan default ( shared | none ) */ 7418169689Skan 7419169689Skanstatic tree 7420169689Skanc_parser_omp_clause_default (c_parser *parser, tree list) 7421169689Skan{ 7422169689Skan enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED; 7423169689Skan tree c; 7424169689Skan 7425169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 7426169689Skan return list; 7427169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 7428169689Skan { 7429169689Skan const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 7430169689Skan 7431169689Skan switch (p[0]) 7432169689Skan { 7433169689Skan case 'n': 7434169689Skan if (strcmp ("none", p) != 0) 7435169689Skan goto invalid_kind; 7436169689Skan kind = OMP_CLAUSE_DEFAULT_NONE; 7437169689Skan break; 7438169689Skan 7439169689Skan case 's': 7440169689Skan if (strcmp ("shared", p) != 0) 7441169689Skan goto invalid_kind; 7442169689Skan kind = OMP_CLAUSE_DEFAULT_SHARED; 7443169689Skan break; 7444169689Skan 7445169689Skan default: 7446169689Skan goto invalid_kind; 7447169689Skan } 7448169689Skan 7449169689Skan c_parser_consume_token (parser); 7450169689Skan } 7451169689Skan else 7452169689Skan { 7453169689Skan invalid_kind: 7454169689Skan c_parser_error (parser, "expected %<none%> or %<shared%>"); 7455169689Skan } 7456169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 7457169689Skan 7458169689Skan if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED) 7459169689Skan return list; 7460169689Skan 7461169689Skan check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default"); 7462169689Skan c = build_omp_clause (OMP_CLAUSE_DEFAULT); 7463169689Skan OMP_CLAUSE_CHAIN (c) = list; 7464169689Skan OMP_CLAUSE_DEFAULT_KIND (c) = kind; 7465169689Skan 7466169689Skan return c; 7467169689Skan} 7468169689Skan 7469169689Skan/* OpenMP 2.5: 7470169689Skan firstprivate ( variable-list ) */ 7471169689Skan 7472169689Skanstatic tree 7473169689Skanc_parser_omp_clause_firstprivate (c_parser *parser, tree list) 7474169689Skan{ 7475169689Skan return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list); 7476169689Skan} 7477169689Skan 7478169689Skan/* OpenMP 2.5: 7479169689Skan if ( expression ) */ 7480169689Skan 7481169689Skanstatic tree 7482169689Skanc_parser_omp_clause_if (c_parser *parser, tree list) 7483169689Skan{ 7484169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 7485169689Skan { 7486169689Skan tree t = c_parser_paren_condition (parser); 7487169689Skan tree c; 7488169689Skan 7489169689Skan check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if"); 7490169689Skan 7491169689Skan c = build_omp_clause (OMP_CLAUSE_IF); 7492169689Skan OMP_CLAUSE_IF_EXPR (c) = t; 7493169689Skan OMP_CLAUSE_CHAIN (c) = list; 7494169689Skan list = c; 7495169689Skan } 7496169689Skan else 7497169689Skan c_parser_error (parser, "expected %<(%>"); 7498169689Skan 7499169689Skan return list; 7500169689Skan} 7501169689Skan 7502169689Skan/* OpenMP 2.5: 7503169689Skan lastprivate ( variable-list ) */ 7504169689Skan 7505169689Skanstatic tree 7506169689Skanc_parser_omp_clause_lastprivate (c_parser *parser, tree list) 7507169689Skan{ 7508169689Skan return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LASTPRIVATE, list); 7509169689Skan} 7510169689Skan 7511169689Skan/* OpenMP 2.5: 7512169689Skan nowait */ 7513169689Skan 7514169689Skanstatic tree 7515169689Skanc_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list) 7516169689Skan{ 7517169689Skan tree c; 7518169689Skan 7519169689Skan check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait"); 7520169689Skan 7521169689Skan c = build_omp_clause (OMP_CLAUSE_NOWAIT); 7522169689Skan OMP_CLAUSE_CHAIN (c) = list; 7523169689Skan return c; 7524169689Skan} 7525169689Skan 7526169689Skan/* OpenMP 2.5: 7527169689Skan num_threads ( expression ) */ 7528169689Skan 7529169689Skanstatic tree 7530169689Skanc_parser_omp_clause_num_threads (c_parser *parser, tree list) 7531169689Skan{ 7532169689Skan if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 7533169689Skan { 7534169689Skan tree c, t = c_parser_expression (parser).value; 7535169689Skan 7536169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 7537169689Skan 7538169689Skan if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 7539169689Skan { 7540169689Skan c_parser_error (parser, "expected integer expression"); 7541169689Skan return list; 7542169689Skan } 7543169689Skan 7544169689Skan /* Attempt to statically determine when the number isn't positive. */ 7545169689Skan c = fold_build2 (LE_EXPR, boolean_type_node, t, 7546169689Skan build_int_cst (TREE_TYPE (t), 0)); 7547169689Skan if (c == boolean_true_node) 7548169689Skan { 7549169689Skan warning (0, "%<num_threads%> value must be positive"); 7550169689Skan t = integer_one_node; 7551169689Skan } 7552169689Skan 7553169689Skan check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads"); 7554169689Skan 7555169689Skan c = build_omp_clause (OMP_CLAUSE_NUM_THREADS); 7556169689Skan OMP_CLAUSE_NUM_THREADS_EXPR (c) = t; 7557169689Skan OMP_CLAUSE_CHAIN (c) = list; 7558169689Skan list = c; 7559169689Skan } 7560169689Skan 7561169689Skan return list; 7562169689Skan} 7563169689Skan 7564169689Skan/* OpenMP 2.5: 7565169689Skan ordered */ 7566169689Skan 7567169689Skanstatic tree 7568169689Skanc_parser_omp_clause_ordered (c_parser *parser ATTRIBUTE_UNUSED, tree list) 7569169689Skan{ 7570169689Skan tree c; 7571169689Skan 7572169689Skan check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered"); 7573169689Skan 7574169689Skan c = build_omp_clause (OMP_CLAUSE_ORDERED); 7575169689Skan OMP_CLAUSE_CHAIN (c) = list; 7576169689Skan return c; 7577169689Skan} 7578169689Skan 7579169689Skan/* OpenMP 2.5: 7580169689Skan private ( variable-list ) */ 7581169689Skan 7582169689Skanstatic tree 7583169689Skanc_parser_omp_clause_private (c_parser *parser, tree list) 7584169689Skan{ 7585169689Skan return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list); 7586169689Skan} 7587169689Skan 7588169689Skan/* OpenMP 2.5: 7589169689Skan reduction ( reduction-operator : variable-list ) 7590169689Skan 7591169689Skan reduction-operator: 7592169689Skan One of: + * - & ^ | && || */ 7593169689Skan 7594169689Skanstatic tree 7595169689Skanc_parser_omp_clause_reduction (c_parser *parser, tree list) 7596169689Skan{ 7597169689Skan if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 7598169689Skan { 7599169689Skan enum tree_code code; 7600169689Skan 7601169689Skan switch (c_parser_peek_token (parser)->type) 7602169689Skan { 7603169689Skan case CPP_PLUS: 7604169689Skan code = PLUS_EXPR; 7605169689Skan break; 7606169689Skan case CPP_MULT: 7607169689Skan code = MULT_EXPR; 7608169689Skan break; 7609169689Skan case CPP_MINUS: 7610169689Skan code = MINUS_EXPR; 7611169689Skan break; 7612169689Skan case CPP_AND: 7613169689Skan code = BIT_AND_EXPR; 7614169689Skan break; 7615169689Skan case CPP_XOR: 7616169689Skan code = BIT_XOR_EXPR; 7617169689Skan break; 7618169689Skan case CPP_OR: 7619169689Skan code = BIT_IOR_EXPR; 7620169689Skan break; 7621169689Skan case CPP_AND_AND: 7622169689Skan code = TRUTH_ANDIF_EXPR; 7623169689Skan break; 7624169689Skan case CPP_OR_OR: 7625169689Skan code = TRUTH_ORIF_EXPR; 7626169689Skan break; 7627169689Skan default: 7628169689Skan c_parser_error (parser, 7629169689Skan "expected %<+%>, %<*%>, %<-%>, %<&%>, " 7630169689Skan "%<^%>, %<|%>, %<&&%>, or %<||%>"); 7631169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 7632169689Skan return list; 7633169689Skan } 7634169689Skan c_parser_consume_token (parser); 7635169689Skan if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 7636169689Skan { 7637169689Skan tree nl, c; 7638169689Skan 7639169689Skan nl = c_parser_omp_variable_list (parser, OMP_CLAUSE_REDUCTION, list); 7640169689Skan for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 7641169689Skan OMP_CLAUSE_REDUCTION_CODE (c) = code; 7642169689Skan 7643169689Skan list = nl; 7644169689Skan } 7645169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 7646169689Skan } 7647169689Skan return list; 7648169689Skan} 7649169689Skan 7650169689Skan/* OpenMP 2.5: 7651169689Skan schedule ( schedule-kind ) 7652169689Skan schedule ( schedule-kind , expression ) 7653169689Skan 7654169689Skan schedule-kind: 7655169689Skan static | dynamic | guided | runtime 7656169689Skan*/ 7657169689Skan 7658169689Skanstatic tree 7659169689Skanc_parser_omp_clause_schedule (c_parser *parser, tree list) 7660169689Skan{ 7661169689Skan tree c, t; 7662169689Skan 7663169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 7664169689Skan return list; 7665169689Skan 7666169689Skan c = build_omp_clause (OMP_CLAUSE_SCHEDULE); 7667169689Skan 7668169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 7669169689Skan { 7670169689Skan tree kind = c_parser_peek_token (parser)->value; 7671169689Skan const char *p = IDENTIFIER_POINTER (kind); 7672169689Skan 7673169689Skan switch (p[0]) 7674169689Skan { 7675169689Skan case 'd': 7676169689Skan if (strcmp ("dynamic", p) != 0) 7677169689Skan goto invalid_kind; 7678169689Skan OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC; 7679169689Skan break; 7680169689Skan 7681169689Skan case 'g': 7682169689Skan if (strcmp ("guided", p) != 0) 7683169689Skan goto invalid_kind; 7684169689Skan OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED; 7685169689Skan break; 7686169689Skan 7687169689Skan case 'r': 7688169689Skan if (strcmp ("runtime", p) != 0) 7689169689Skan goto invalid_kind; 7690169689Skan OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME; 7691169689Skan break; 7692169689Skan 7693169689Skan default: 7694169689Skan goto invalid_kind; 7695169689Skan } 7696169689Skan } 7697169689Skan else if (c_parser_next_token_is_keyword (parser, RID_STATIC)) 7698169689Skan OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC; 7699169689Skan else 7700169689Skan goto invalid_kind; 7701169689Skan 7702169689Skan c_parser_consume_token (parser); 7703169689Skan if (c_parser_next_token_is (parser, CPP_COMMA)) 7704169689Skan { 7705169689Skan c_parser_consume_token (parser); 7706169689Skan 7707169689Skan t = c_parser_expr_no_commas (parser, NULL).value; 7708169689Skan 7709169689Skan if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) 7710169689Skan error ("schedule %<runtime%> does not take " 7711169689Skan "a %<chunk_size%> parameter"); 7712169689Skan else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE) 7713169689Skan OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; 7714169689Skan else 7715169689Skan c_parser_error (parser, "expected integer expression"); 7716169689Skan 7717169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 7718169689Skan } 7719169689Skan else 7720169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 7721169689Skan "expected %<,%> or %<)%>"); 7722169689Skan 7723169689Skan check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule"); 7724169689Skan OMP_CLAUSE_CHAIN (c) = list; 7725169689Skan return c; 7726169689Skan 7727169689Skan invalid_kind: 7728169689Skan c_parser_error (parser, "invalid schedule kind"); 7729169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 7730169689Skan return list; 7731169689Skan} 7732169689Skan 7733169689Skan/* OpenMP 2.5: 7734169689Skan shared ( variable-list ) */ 7735169689Skan 7736169689Skanstatic tree 7737169689Skanc_parser_omp_clause_shared (c_parser *parser, tree list) 7738169689Skan{ 7739169689Skan return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list); 7740169689Skan} 7741169689Skan 7742169689Skan/* Parse all OpenMP clauses. The set clauses allowed by the directive 7743169689Skan is a bitmask in MASK. Return the list of clauses found; the result 7744169689Skan of clause default goes in *pdefault. */ 7745169689Skan 7746169689Skanstatic tree 7747169689Skanc_parser_omp_all_clauses (c_parser *parser, unsigned int mask, 7748169689Skan const char *where) 7749169689Skan{ 7750169689Skan tree clauses = NULL; 7751169689Skan 7752169689Skan while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 7753169689Skan { 7754169689Skan const pragma_omp_clause c_kind = c_parser_omp_clause_name (parser); 7755169689Skan const char *c_name; 7756169689Skan tree prev = clauses; 7757169689Skan 7758169689Skan switch (c_kind) 7759169689Skan { 7760169689Skan case PRAGMA_OMP_CLAUSE_COPYIN: 7761169689Skan clauses = c_parser_omp_clause_copyin (parser, clauses); 7762169689Skan c_name = "copyin"; 7763169689Skan break; 7764169689Skan case PRAGMA_OMP_CLAUSE_COPYPRIVATE: 7765169689Skan clauses = c_parser_omp_clause_copyprivate (parser, clauses); 7766169689Skan c_name = "copyprivate"; 7767169689Skan break; 7768169689Skan case PRAGMA_OMP_CLAUSE_DEFAULT: 7769169689Skan clauses = c_parser_omp_clause_default (parser, clauses); 7770169689Skan c_name = "default"; 7771169689Skan break; 7772169689Skan case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: 7773169689Skan clauses = c_parser_omp_clause_firstprivate (parser, clauses); 7774169689Skan c_name = "firstprivate"; 7775169689Skan break; 7776169689Skan case PRAGMA_OMP_CLAUSE_IF: 7777169689Skan clauses = c_parser_omp_clause_if (parser, clauses); 7778169689Skan c_name = "if"; 7779169689Skan break; 7780169689Skan case PRAGMA_OMP_CLAUSE_LASTPRIVATE: 7781169689Skan clauses = c_parser_omp_clause_lastprivate (parser, clauses); 7782169689Skan c_name = "lastprivate"; 7783169689Skan break; 7784169689Skan case PRAGMA_OMP_CLAUSE_NOWAIT: 7785169689Skan clauses = c_parser_omp_clause_nowait (parser, clauses); 7786169689Skan c_name = "nowait"; 7787169689Skan break; 7788169689Skan case PRAGMA_OMP_CLAUSE_NUM_THREADS: 7789169689Skan clauses = c_parser_omp_clause_num_threads (parser, clauses); 7790169689Skan c_name = "num_threads"; 7791169689Skan break; 7792169689Skan case PRAGMA_OMP_CLAUSE_ORDERED: 7793169689Skan clauses = c_parser_omp_clause_ordered (parser, clauses); 7794169689Skan c_name = "ordered"; 7795169689Skan break; 7796169689Skan case PRAGMA_OMP_CLAUSE_PRIVATE: 7797169689Skan clauses = c_parser_omp_clause_private (parser, clauses); 7798169689Skan c_name = "private"; 7799169689Skan break; 7800169689Skan case PRAGMA_OMP_CLAUSE_REDUCTION: 7801169689Skan clauses = c_parser_omp_clause_reduction (parser, clauses); 7802169689Skan c_name = "reduction"; 7803169689Skan break; 7804169689Skan case PRAGMA_OMP_CLAUSE_SCHEDULE: 7805169689Skan clauses = c_parser_omp_clause_schedule (parser, clauses); 7806169689Skan c_name = "schedule"; 7807169689Skan break; 7808169689Skan case PRAGMA_OMP_CLAUSE_SHARED: 7809169689Skan clauses = c_parser_omp_clause_shared (parser, clauses); 7810169689Skan c_name = "shared"; 7811169689Skan break; 7812169689Skan default: 7813169689Skan c_parser_error (parser, "expected %<#pragma omp%> clause"); 7814169689Skan goto saw_error; 7815169689Skan } 7816169689Skan 7817169689Skan if (((mask >> c_kind) & 1) == 0 && !parser->error) 7818169689Skan { 7819169689Skan /* Remove the invalid clause(s) from the list to avoid 7820169689Skan confusing the rest of the compiler. */ 7821169689Skan clauses = prev; 7822169689Skan error ("%qs is not valid for %qs", c_name, where); 7823169689Skan } 7824169689Skan } 7825169689Skan 7826169689Skan saw_error: 7827169689Skan c_parser_skip_to_pragma_eol (parser); 7828169689Skan 7829169689Skan return c_finish_omp_clauses (clauses); 7830169689Skan} 7831169689Skan 7832169689Skan/* OpenMP 2.5: 7833169689Skan structured-block: 7834169689Skan statement 7835169689Skan 7836169689Skan In practice, we're also interested in adding the statement to an 7837169689Skan outer node. So it is convenient if we work around the fact that 7838169689Skan c_parser_statement calls add_stmt. */ 7839169689Skan 7840169689Skanstatic tree 7841169689Skanc_parser_omp_structured_block (c_parser *parser) 7842169689Skan{ 7843169689Skan tree stmt = push_stmt_list (); 7844169689Skan c_parser_statement (parser); 7845169689Skan return pop_stmt_list (stmt); 7846169689Skan} 7847169689Skan 7848169689Skan/* OpenMP 2.5: 7849169689Skan # pragma omp atomic new-line 7850169689Skan expression-stmt 7851169689Skan 7852169689Skan expression-stmt: 7853169689Skan x binop= expr | x++ | ++x | x-- | --x 7854169689Skan binop: 7855169689Skan +, *, -, /, &, ^, |, <<, >> 7856169689Skan 7857169689Skan where x is an lvalue expression with scalar type. */ 7858169689Skan 7859169689Skanstatic void 7860169689Skanc_parser_omp_atomic (c_parser *parser) 7861169689Skan{ 7862169689Skan tree lhs, rhs; 7863169689Skan tree stmt; 7864169689Skan enum tree_code code; 7865169689Skan 7866169689Skan c_parser_skip_to_pragma_eol (parser); 7867169689Skan 7868169689Skan lhs = c_parser_unary_expression (parser).value; 7869169689Skan switch (TREE_CODE (lhs)) 7870169689Skan { 7871169689Skan case ERROR_MARK: 7872169689Skan saw_error: 7873169689Skan c_parser_skip_to_end_of_block_or_statement (parser); 7874169689Skan return; 7875169689Skan 7876169689Skan case PREINCREMENT_EXPR: 7877169689Skan case POSTINCREMENT_EXPR: 7878169689Skan lhs = TREE_OPERAND (lhs, 0); 7879169689Skan code = PLUS_EXPR; 7880169689Skan rhs = integer_one_node; 7881169689Skan break; 7882169689Skan 7883169689Skan case PREDECREMENT_EXPR: 7884169689Skan case POSTDECREMENT_EXPR: 7885169689Skan lhs = TREE_OPERAND (lhs, 0); 7886169689Skan code = MINUS_EXPR; 7887169689Skan rhs = integer_one_node; 7888169689Skan break; 7889169689Skan 7890169689Skan default: 7891169689Skan switch (c_parser_peek_token (parser)->type) 7892169689Skan { 7893169689Skan case CPP_MULT_EQ: 7894169689Skan code = MULT_EXPR; 7895169689Skan break; 7896169689Skan case CPP_DIV_EQ: 7897169689Skan code = TRUNC_DIV_EXPR; 7898169689Skan break; 7899169689Skan case CPP_PLUS_EQ: 7900169689Skan code = PLUS_EXPR; 7901169689Skan break; 7902169689Skan case CPP_MINUS_EQ: 7903169689Skan code = MINUS_EXPR; 7904169689Skan break; 7905169689Skan case CPP_LSHIFT_EQ: 7906169689Skan code = LSHIFT_EXPR; 7907169689Skan break; 7908169689Skan case CPP_RSHIFT_EQ: 7909169689Skan code = RSHIFT_EXPR; 7910169689Skan break; 7911169689Skan case CPP_AND_EQ: 7912169689Skan code = BIT_AND_EXPR; 7913169689Skan break; 7914169689Skan case CPP_OR_EQ: 7915169689Skan code = BIT_IOR_EXPR; 7916169689Skan break; 7917169689Skan case CPP_XOR_EQ: 7918169689Skan code = BIT_XOR_EXPR; 7919169689Skan break; 7920169689Skan default: 7921169689Skan c_parser_error (parser, 7922169689Skan "invalid operator for %<#pragma omp atomic%>"); 7923169689Skan goto saw_error; 7924169689Skan } 7925169689Skan 7926169689Skan c_parser_consume_token (parser); 7927169689Skan rhs = c_parser_expression (parser).value; 7928169689Skan break; 7929169689Skan } 7930169689Skan stmt = c_finish_omp_atomic (code, lhs, rhs); 7931169689Skan if (stmt != error_mark_node) 7932169689Skan add_stmt (stmt); 7933169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 7934169689Skan} 7935169689Skan 7936169689Skan 7937169689Skan/* OpenMP 2.5: 7938169689Skan # pragma omp barrier new-line 7939169689Skan*/ 7940169689Skan 7941169689Skanstatic void 7942169689Skanc_parser_omp_barrier (c_parser *parser) 7943169689Skan{ 7944169689Skan c_parser_consume_pragma (parser); 7945169689Skan c_parser_skip_to_pragma_eol (parser); 7946169689Skan 7947169689Skan c_finish_omp_barrier (); 7948169689Skan} 7949169689Skan 7950169689Skan/* OpenMP 2.5: 7951169689Skan # pragma omp critical [(name)] new-line 7952169689Skan structured-block 7953169689Skan*/ 7954169689Skan 7955169689Skanstatic tree 7956169689Skanc_parser_omp_critical (c_parser *parser) 7957169689Skan{ 7958169689Skan tree stmt, name = NULL; 7959169689Skan 7960169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 7961169689Skan { 7962169689Skan c_parser_consume_token (parser); 7963169689Skan if (c_parser_next_token_is (parser, CPP_NAME)) 7964169689Skan { 7965169689Skan name = c_parser_peek_token (parser)->value; 7966169689Skan c_parser_consume_token (parser); 7967169689Skan c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 7968169689Skan } 7969169689Skan else 7970169689Skan c_parser_error (parser, "expected identifier"); 7971169689Skan } 7972169689Skan else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 7973169689Skan c_parser_error (parser, "expected %<(%> or end of line"); 7974169689Skan c_parser_skip_to_pragma_eol (parser); 7975169689Skan 7976169689Skan stmt = c_parser_omp_structured_block (parser); 7977169689Skan return c_finish_omp_critical (stmt, name); 7978169689Skan} 7979169689Skan 7980169689Skan/* OpenMP 2.5: 7981169689Skan # pragma omp flush flush-vars[opt] new-line 7982169689Skan 7983169689Skan flush-vars: 7984169689Skan ( variable-list ) */ 7985169689Skan 7986169689Skanstatic void 7987169689Skanc_parser_omp_flush (c_parser *parser) 7988169689Skan{ 7989169689Skan c_parser_consume_pragma (parser); 7990169689Skan if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 7991169689Skan c_parser_omp_var_list_parens (parser, 0, NULL); 7992169689Skan else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 7993169689Skan c_parser_error (parser, "expected %<(%> or end of line"); 7994169689Skan c_parser_skip_to_pragma_eol (parser); 7995169689Skan 7996169689Skan c_finish_omp_flush (); 7997169689Skan} 7998169689Skan 7999169689Skan/* Parse the restricted form of the for statment allowed by OpenMP. 8000169689Skan The real trick here is to determine the loop control variable early 8001169689Skan so that we can push a new decl if necessary to make it private. */ 8002169689Skan 8003169689Skanstatic tree 8004169689Skanc_parser_omp_for_loop (c_parser *parser) 8005169689Skan{ 8006169689Skan tree decl, cond, incr, save_break, save_cont, body, init; 8007169689Skan location_t loc; 8008169689Skan 8009169689Skan if (!c_parser_next_token_is_keyword (parser, RID_FOR)) 8010169689Skan { 8011169689Skan c_parser_error (parser, "for statement expected"); 8012169689Skan return NULL; 8013169689Skan } 8014169689Skan loc = c_parser_peek_token (parser)->location; 8015169689Skan c_parser_consume_token (parser); 8016169689Skan 8017169689Skan if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 8018169689Skan return NULL; 8019169689Skan 8020169689Skan /* Parse the initialization declaration or expression. */ 8021169689Skan if (c_parser_next_token_starts_declspecs (parser)) 8022169689Skan { 8023260311Spfg /* APPLE LOCAL radar 4708210 (for_objc_collection in 4.2) */ 8024260311Spfg c_parser_declaration_or_fndef (parser, true, true, true, true, NULL); 8025169689Skan decl = check_for_loop_decls (); 8026169689Skan if (decl == NULL) 8027169689Skan goto error_init; 8028169689Skan init = decl; 8029169689Skan } 8030169689Skan else if (c_parser_next_token_is (parser, CPP_NAME) 8031169689Skan && c_parser_peek_2nd_token (parser)->type == CPP_EQ) 8032169689Skan { 8033169689Skan decl = c_parser_postfix_expression (parser).value; 8034169689Skan 8035169689Skan c_parser_require (parser, CPP_EQ, "expected %<=%>"); 8036169689Skan 8037169689Skan init = c_parser_expr_no_commas (parser, NULL).value; 8038169689Skan init = build_modify_expr (decl, NOP_EXPR, init); 8039169689Skan init = c_process_expr_stmt (init); 8040169689Skan 8041169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 8042169689Skan } 8043169689Skan else 8044169689Skan goto error_init; 8045169689Skan 8046169689Skan /* Parse the loop condition. */ 8047169689Skan cond = NULL_TREE; 8048169689Skan if (c_parser_next_token_is_not (parser, CPP_SEMICOLON)) 8049169689Skan { 8050169689Skan cond = c_parser_expression_conv (parser).value; 8051169689Skan cond = c_objc_common_truthvalue_conversion (cond); 8052169689Skan if (EXPR_P (cond)) 8053169689Skan SET_EXPR_LOCATION (cond, input_location); 8054169689Skan } 8055169689Skan c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 8056169689Skan 8057169689Skan /* Parse the increment expression. */ 8058169689Skan incr = NULL_TREE; 8059169689Skan if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) 8060169689Skan incr = c_process_expr_stmt (c_parser_expression (parser).value); 8061169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 8062169689Skan 8063169689Skan parse_body: 8064169689Skan save_break = c_break_label; 8065169689Skan c_break_label = size_one_node; 8066169689Skan save_cont = c_cont_label; 8067169689Skan c_cont_label = NULL_TREE; 8068169689Skan body = push_stmt_list (); 8069169689Skan 8070169689Skan add_stmt (c_parser_c99_block_statement (parser)); 8071169689Skan if (c_cont_label) 8072169689Skan add_stmt (build1 (LABEL_EXPR, void_type_node, c_cont_label)); 8073169689Skan 8074169689Skan body = pop_stmt_list (body); 8075169689Skan c_break_label = save_break; 8076169689Skan c_cont_label = save_cont; 8077169689Skan 8078169689Skan /* Only bother calling c_finish_omp_for if we havn't already generated 8079169689Skan an error from the initialization parsing. */ 8080169689Skan if (decl != NULL && decl != error_mark_node && init != error_mark_node) 8081169689Skan return c_finish_omp_for (loc, decl, init, cond, incr, body, NULL); 8082169689Skan return NULL; 8083169689Skan 8084169689Skan error_init: 8085169689Skan c_parser_error (parser, "expected iteration declaration or initialization"); 8086169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 8087169689Skan decl = init = cond = incr = NULL_TREE; 8088169689Skan goto parse_body; 8089169689Skan} 8090169689Skan 8091169689Skan/* OpenMP 2.5: 8092169689Skan #pragma omp for for-clause[optseq] new-line 8093169689Skan for-loop 8094169689Skan*/ 8095169689Skan 8096169689Skan#define OMP_FOR_CLAUSE_MASK \ 8097169689Skan ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ 8098169689Skan | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 8099169689Skan | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 8100169689Skan | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ 8101169689Skan | (1u << PRAGMA_OMP_CLAUSE_ORDERED) \ 8102169689Skan | (1u << PRAGMA_OMP_CLAUSE_SCHEDULE) \ 8103169689Skan | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) 8104169689Skan 8105169689Skanstatic tree 8106169689Skanc_parser_omp_for (c_parser *parser) 8107169689Skan{ 8108169689Skan tree block, clauses, ret; 8109169689Skan 8110169689Skan clauses = c_parser_omp_all_clauses (parser, OMP_FOR_CLAUSE_MASK, 8111169689Skan "#pragma omp for"); 8112169689Skan 8113169689Skan block = c_begin_compound_stmt (true); 8114169689Skan ret = c_parser_omp_for_loop (parser); 8115169689Skan if (ret) 8116169689Skan OMP_FOR_CLAUSES (ret) = clauses; 8117169689Skan block = c_end_compound_stmt (block, true); 8118169689Skan add_stmt (block); 8119169689Skan 8120169689Skan return ret; 8121169689Skan} 8122169689Skan 8123169689Skan/* OpenMP 2.5: 8124169689Skan # pragma omp master new-line 8125169689Skan structured-block 8126169689Skan*/ 8127169689Skan 8128169689Skanstatic tree 8129169689Skanc_parser_omp_master (c_parser *parser) 8130169689Skan{ 8131169689Skan c_parser_skip_to_pragma_eol (parser); 8132169689Skan return c_finish_omp_master (c_parser_omp_structured_block (parser)); 8133169689Skan} 8134169689Skan 8135169689Skan/* OpenMP 2.5: 8136169689Skan # pragma omp ordered new-line 8137169689Skan structured-block 8138169689Skan*/ 8139169689Skan 8140169689Skanstatic tree 8141169689Skanc_parser_omp_ordered (c_parser *parser) 8142169689Skan{ 8143169689Skan c_parser_skip_to_pragma_eol (parser); 8144169689Skan return c_finish_omp_ordered (c_parser_omp_structured_block (parser)); 8145169689Skan} 8146169689Skan 8147169689Skan/* OpenMP 2.5: 8148169689Skan 8149169689Skan section-scope: 8150169689Skan { section-sequence } 8151169689Skan 8152169689Skan section-sequence: 8153169689Skan section-directive[opt] structured-block 8154169689Skan section-sequence section-directive structured-block */ 8155169689Skan 8156169689Skanstatic tree 8157169689Skanc_parser_omp_sections_scope (c_parser *parser) 8158169689Skan{ 8159169689Skan tree stmt, substmt; 8160169689Skan bool error_suppress = false; 8161169689Skan location_t loc; 8162169689Skan 8163169689Skan if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 8164169689Skan { 8165169689Skan /* Avoid skipping until the end of the block. */ 8166169689Skan parser->error = false; 8167169689Skan return NULL_TREE; 8168169689Skan } 8169169689Skan 8170169689Skan stmt = push_stmt_list (); 8171169689Skan 8172169689Skan loc = c_parser_peek_token (parser)->location; 8173169689Skan if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION) 8174169689Skan { 8175169689Skan substmt = push_stmt_list (); 8176169689Skan 8177169689Skan while (1) 8178169689Skan { 8179169689Skan c_parser_statement (parser); 8180169689Skan 8181169689Skan if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION) 8182169689Skan break; 8183169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 8184169689Skan break; 8185169689Skan if (c_parser_next_token_is (parser, CPP_EOF)) 8186169689Skan break; 8187169689Skan } 8188169689Skan 8189169689Skan substmt = pop_stmt_list (substmt); 8190169689Skan substmt = build1 (OMP_SECTION, void_type_node, substmt); 8191169689Skan SET_EXPR_LOCATION (substmt, loc); 8192169689Skan add_stmt (substmt); 8193169689Skan } 8194169689Skan 8195169689Skan while (1) 8196169689Skan { 8197169689Skan if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 8198169689Skan break; 8199169689Skan if (c_parser_next_token_is (parser, CPP_EOF)) 8200169689Skan break; 8201169689Skan 8202169689Skan loc = c_parser_peek_token (parser)->location; 8203169689Skan if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION) 8204169689Skan { 8205169689Skan c_parser_consume_pragma (parser); 8206169689Skan c_parser_skip_to_pragma_eol (parser); 8207169689Skan error_suppress = false; 8208169689Skan } 8209169689Skan else if (!error_suppress) 8210169689Skan { 8211169689Skan error ("expected %<#pragma omp section%> or %<}%>"); 8212169689Skan error_suppress = true; 8213169689Skan } 8214169689Skan 8215169689Skan substmt = c_parser_omp_structured_block (parser); 8216169689Skan substmt = build1 (OMP_SECTION, void_type_node, substmt); 8217169689Skan SET_EXPR_LOCATION (substmt, loc); 8218169689Skan add_stmt (substmt); 8219169689Skan } 8220169689Skan c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, 8221169689Skan "expected %<#pragma omp section%> or %<}%>"); 8222169689Skan 8223169689Skan substmt = pop_stmt_list (stmt); 8224169689Skan 8225169689Skan stmt = make_node (OMP_SECTIONS); 8226169689Skan TREE_TYPE (stmt) = void_type_node; 8227169689Skan OMP_SECTIONS_BODY (stmt) = substmt; 8228169689Skan 8229169689Skan return add_stmt (stmt); 8230169689Skan} 8231169689Skan 8232169689Skan/* OpenMP 2.5: 8233169689Skan # pragma omp sections sections-clause[optseq] newline 8234169689Skan sections-scope 8235169689Skan*/ 8236169689Skan 8237169689Skan#define OMP_SECTIONS_CLAUSE_MASK \ 8238169689Skan ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ 8239169689Skan | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 8240169689Skan | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 8241169689Skan | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ 8242169689Skan | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) 8243169689Skan 8244169689Skanstatic tree 8245169689Skanc_parser_omp_sections (c_parser *parser) 8246169689Skan{ 8247169689Skan tree block, clauses, ret; 8248169689Skan 8249169689Skan clauses = c_parser_omp_all_clauses (parser, OMP_SECTIONS_CLAUSE_MASK, 8250169689Skan "#pragma omp sections"); 8251169689Skan 8252169689Skan block = c_begin_compound_stmt (true); 8253169689Skan ret = c_parser_omp_sections_scope (parser); 8254169689Skan if (ret) 8255169689Skan OMP_SECTIONS_CLAUSES (ret) = clauses; 8256169689Skan block = c_end_compound_stmt (block, true); 8257169689Skan add_stmt (block); 8258169689Skan 8259169689Skan return ret; 8260169689Skan} 8261169689Skan 8262169689Skan/* OpenMP 2.5: 8263169689Skan # pragma parallel parallel-clause new-line 8264169689Skan # pragma parallel for parallel-for-clause new-line 8265169689Skan # pragma parallel sections parallel-sections-clause new-line 8266169689Skan*/ 8267169689Skan 8268169689Skan#define OMP_PARALLEL_CLAUSE_MASK \ 8269169689Skan ( (1u << PRAGMA_OMP_CLAUSE_IF) \ 8270169689Skan | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ 8271169689Skan | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 8272169689Skan | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ 8273169689Skan | (1u << PRAGMA_OMP_CLAUSE_SHARED) \ 8274169689Skan | (1u << PRAGMA_OMP_CLAUSE_COPYIN) \ 8275169689Skan | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ 8276169689Skan | (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS)) 8277169689Skan 8278169689Skanstatic tree 8279169689Skanc_parser_omp_parallel (c_parser *parser) 8280169689Skan{ 8281169689Skan enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL; 8282169689Skan const char *p_name = "#pragma omp parallel"; 8283169689Skan tree stmt, clauses, par_clause, ws_clause, block; 8284169689Skan unsigned int mask = OMP_PARALLEL_CLAUSE_MASK; 8285169689Skan 8286169689Skan if (c_parser_next_token_is_keyword (parser, RID_FOR)) 8287169689Skan { 8288169689Skan c_parser_consume_token (parser); 8289169689Skan p_kind = PRAGMA_OMP_PARALLEL_FOR; 8290169689Skan p_name = "#pragma omp parallel for"; 8291169689Skan mask |= OMP_FOR_CLAUSE_MASK; 8292169689Skan mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT); 8293169689Skan } 8294169689Skan else if (c_parser_next_token_is (parser, CPP_NAME)) 8295169689Skan { 8296169689Skan const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 8297169689Skan if (strcmp (p, "sections") == 0) 8298169689Skan { 8299169689Skan c_parser_consume_token (parser); 8300169689Skan p_kind = PRAGMA_OMP_PARALLEL_SECTIONS; 8301169689Skan p_name = "#pragma omp parallel sections"; 8302169689Skan mask |= OMP_SECTIONS_CLAUSE_MASK; 8303169689Skan mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT); 8304169689Skan } 8305169689Skan } 8306169689Skan 8307169689Skan clauses = c_parser_omp_all_clauses (parser, mask, p_name); 8308169689Skan 8309169689Skan switch (p_kind) 8310169689Skan { 8311169689Skan case PRAGMA_OMP_PARALLEL: 8312169689Skan block = c_begin_omp_parallel (); 8313169689Skan c_parser_statement (parser); 8314169689Skan stmt = c_finish_omp_parallel (clauses, block); 8315169689Skan break; 8316169689Skan 8317169689Skan case PRAGMA_OMP_PARALLEL_FOR: 8318169689Skan block = c_begin_omp_parallel (); 8319169689Skan c_split_parallel_clauses (clauses, &par_clause, &ws_clause); 8320169689Skan stmt = c_parser_omp_for_loop (parser); 8321169689Skan if (stmt) 8322169689Skan OMP_FOR_CLAUSES (stmt) = ws_clause; 8323169689Skan stmt = c_finish_omp_parallel (par_clause, block); 8324169689Skan OMP_PARALLEL_COMBINED (stmt) = 1; 8325169689Skan break; 8326169689Skan 8327169689Skan case PRAGMA_OMP_PARALLEL_SECTIONS: 8328169689Skan block = c_begin_omp_parallel (); 8329169689Skan c_split_parallel_clauses (clauses, &par_clause, &ws_clause); 8330169689Skan stmt = c_parser_omp_sections_scope (parser); 8331169689Skan if (stmt) 8332169689Skan OMP_SECTIONS_CLAUSES (stmt) = ws_clause; 8333169689Skan stmt = c_finish_omp_parallel (par_clause, block); 8334169689Skan OMP_PARALLEL_COMBINED (stmt) = 1; 8335169689Skan break; 8336169689Skan 8337169689Skan default: 8338169689Skan gcc_unreachable (); 8339169689Skan } 8340169689Skan 8341169689Skan return stmt; 8342169689Skan} 8343169689Skan 8344169689Skan/* OpenMP 2.5: 8345169689Skan # pragma omp single single-clause[optseq] new-line 8346169689Skan structured-block 8347169689Skan*/ 8348169689Skan 8349169689Skan#define OMP_SINGLE_CLAUSE_MASK \ 8350169689Skan ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ 8351169689Skan | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 8352169689Skan | (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ 8353169689Skan | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) 8354169689Skan 8355169689Skanstatic tree 8356169689Skanc_parser_omp_single (c_parser *parser) 8357169689Skan{ 8358169689Skan tree stmt = make_node (OMP_SINGLE); 8359169689Skan TREE_TYPE (stmt) = void_type_node; 8360169689Skan 8361169689Skan OMP_SINGLE_CLAUSES (stmt) 8362169689Skan = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK, 8363169689Skan "#pragma omp single"); 8364169689Skan OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser); 8365169689Skan 8366169689Skan return add_stmt (stmt); 8367169689Skan} 8368169689Skan 8369169689Skan 8370169689Skan/* Main entry point to parsing most OpenMP pragmas. */ 8371169689Skan 8372169689Skanstatic void 8373169689Skanc_parser_omp_construct (c_parser *parser) 8374169689Skan{ 8375169689Skan enum pragma_kind p_kind; 8376169689Skan location_t loc; 8377169689Skan tree stmt; 8378169689Skan 8379169689Skan loc = c_parser_peek_token (parser)->location; 8380169689Skan p_kind = c_parser_peek_token (parser)->pragma_kind; 8381169689Skan c_parser_consume_pragma (parser); 8382169689Skan 8383169689Skan /* For all constructs below except #pragma omp atomic 8384169689Skan MUST_NOT_THROW catch handlers are needed when exceptions 8385169689Skan are enabled. */ 8386169689Skan if (p_kind != PRAGMA_OMP_ATOMIC) 8387169689Skan c_maybe_initialize_eh (); 8388169689Skan 8389169689Skan switch (p_kind) 8390169689Skan { 8391169689Skan case PRAGMA_OMP_ATOMIC: 8392169689Skan c_parser_omp_atomic (parser); 8393169689Skan return; 8394169689Skan case PRAGMA_OMP_CRITICAL: 8395169689Skan stmt = c_parser_omp_critical (parser); 8396169689Skan break; 8397169689Skan case PRAGMA_OMP_FOR: 8398169689Skan stmt = c_parser_omp_for (parser); 8399169689Skan break; 8400169689Skan case PRAGMA_OMP_MASTER: 8401169689Skan stmt = c_parser_omp_master (parser); 8402169689Skan break; 8403169689Skan case PRAGMA_OMP_ORDERED: 8404169689Skan stmt = c_parser_omp_ordered (parser); 8405169689Skan break; 8406169689Skan case PRAGMA_OMP_PARALLEL: 8407169689Skan stmt = c_parser_omp_parallel (parser); 8408169689Skan break; 8409169689Skan case PRAGMA_OMP_SECTIONS: 8410169689Skan stmt = c_parser_omp_sections (parser); 8411169689Skan break; 8412169689Skan case PRAGMA_OMP_SINGLE: 8413169689Skan stmt = c_parser_omp_single (parser); 8414169689Skan break; 8415169689Skan default: 8416169689Skan gcc_unreachable (); 8417169689Skan } 8418169689Skan 8419169689Skan if (stmt) 8420169689Skan SET_EXPR_LOCATION (stmt, loc); 8421169689Skan} 8422169689Skan 8423169689Skan 8424169689Skan/* OpenMP 2.5: 8425169689Skan # pragma omp threadprivate (variable-list) */ 8426169689Skan 8427169689Skanstatic void 8428169689Skanc_parser_omp_threadprivate (c_parser *parser) 8429169689Skan{ 8430169689Skan tree vars, t; 8431169689Skan 8432169689Skan c_parser_consume_pragma (parser); 8433169689Skan vars = c_parser_omp_var_list_parens (parser, 0, NULL); 8434169689Skan 8435169689Skan if (!targetm.have_tls) 8436169689Skan sorry ("threadprivate variables not supported in this target"); 8437169689Skan 8438169689Skan /* Mark every variable in VARS to be assigned thread local storage. */ 8439169689Skan for (t = vars; t; t = TREE_CHAIN (t)) 8440169689Skan { 8441169689Skan tree v = TREE_PURPOSE (t); 8442169689Skan 8443169689Skan /* If V had already been marked threadprivate, it doesn't matter 8444169689Skan whether it had been used prior to this point. */ 8445169689Skan if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v)) 8446169689Skan error ("%qE declared %<threadprivate%> after first use", v); 8447169689Skan else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v)) 8448169689Skan error ("automatic variable %qE cannot be %<threadprivate%>", v); 8449169689Skan else if (! COMPLETE_TYPE_P (TREE_TYPE (v))) 8450169689Skan error ("%<threadprivate%> %qE has incomplete type", v); 8451169689Skan else 8452169689Skan { 8453169689Skan if (! DECL_THREAD_LOCAL_P (v)) 8454169689Skan { 8455169689Skan DECL_TLS_MODEL (v) = decl_default_tls_model (v); 8456169689Skan /* If rtl has been already set for this var, call 8457169689Skan make_decl_rtl once again, so that encode_section_info 8458169689Skan has a chance to look at the new decl flags. */ 8459169689Skan if (DECL_RTL_SET_P (v)) 8460169689Skan make_decl_rtl (v); 8461169689Skan } 8462169689Skan C_DECL_THREADPRIVATE_P (v) = 1; 8463169689Skan } 8464169689Skan } 8465169689Skan 8466169689Skan c_parser_skip_to_pragma_eol (parser); 8467169689Skan} 8468169689Skan 8469169689Skan 8470169689Skan/* Parse a single source file. */ 8471169689Skan 8472169689Skanvoid 8473169689Skanc_parse_file (void) 8474169689Skan{ 8475169689Skan /* Use local storage to begin. If the first token is a pragma, parse it. 8476169689Skan If it is #pragma GCC pch_preprocess, then this will load a PCH file 8477169689Skan which will cause garbage collection. */ 8478169689Skan c_parser tparser; 8479169689Skan 8480169689Skan memset (&tparser, 0, sizeof tparser); 8481169689Skan the_parser = &tparser; 8482169689Skan 8483169689Skan if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS) 8484169689Skan c_parser_pragma_pch_preprocess (&tparser); 8485169689Skan 8486169689Skan the_parser = GGC_NEW (c_parser); 8487169689Skan *the_parser = tparser; 8488169689Skan 8489169689Skan c_parser_translation_unit (the_parser); 8490169689Skan the_parser = NULL; 8491169689Skan} 8492169689Skan 8493260311Spfg/* APPLE LOCAL begin radar 5732232 - blocks (C++ ce) */ 8494260311Spfg 8495260311Spfg/* APPLE LOCAL begin radar 6300081 */ 8496260311Spfg 8497260311Spfg/* This function builds a "generic" block struct type, to be passed 8498260311Spfg into the debug information for blocks pointers, to allow gdb to 8499260311Spfg find the actual function pointer for the block. Any time the Blocks 8500260311Spfg structure layout changes, this may also need to change. 8501260311Spfg 8502260311Spfg Currently a block pointer is a pointer to a __block_literal_n struct, 8503260311Spfg the third field of which is a pointer to a __block_descriptor struct, 8504260311Spfg whose third field is the function pointer. There are other fields as 8505260311Spfg well, but these are the ones gdb needs to know about to find the 8506260311Spfg function pointer. Therefore a generic block struct currently looks 8507260311Spfg like this: 8508260311Spfg 8509260311Spfg struct __block_literal_generic 8510260311Spfg { 8511260311Spfg void * __isa; 8512260311Spfg int __flags; 8513260311Spfg int __reserved; 8514260311Spfg void (*__FuncPtr)(void *); 8515260311Spfg struct __block_descriptor 8516260311Spfg { 8517260311Spfg unsigned long int reserved; 8518260311Spfg unsigned long int Size; 8519260311Spfg } *__descriptor; 8520260311Spfg }; 8521260311Spfg 8522260311Spfg IF AT ANY TIME THE STRUCTURE OF A __BLOCK_LITERAL_N CHANGES, THIS 8523260311Spfg MUST BE CHANGED ALSO!! 8524260311Spfg 8525260311Spfg*/ 8526260311Spfg 8527260311Spfgtree 8528260311Spfg/* APPLE LOCAL radar 6353006 */ 8529260311Spfgc_build_generic_block_struct_type (void) 8530260311Spfg{ 8531260311Spfg tree field_decl_chain; 8532260311Spfg tree field_decl; 8533260311Spfg tree block_struct_type; 8534260311Spfg 8535260311Spfg push_to_top_level (); 8536260311Spfg block_struct_type = start_struct (RECORD_TYPE, 8537260311Spfg get_identifier ("__block_literal_generic")); 8538260311Spfg 8539260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__isa"), ptr_type_node); 8540260311Spfg field_decl_chain = field_decl; 8541260311Spfg 8542260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__flags"), 8543260311Spfg integer_type_node); 8544260311Spfg chainon (field_decl_chain, field_decl); 8545260311Spfg 8546260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__reserved"), 8547260311Spfg integer_type_node); 8548260311Spfg chainon (field_decl_chain, field_decl); 8549260311Spfg 8550260311Spfg /* void *__FuncPtr; */ 8551260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__FuncPtr"), ptr_type_node); 8552260311Spfg chainon (field_decl_chain, field_decl); 8553260311Spfg 8554260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__descriptor"), 8555260311Spfg build_block_descriptor_type (false)); 8556260311Spfg chainon (field_decl_chain, field_decl); 8557260311Spfg 8558260311Spfg TYPE_BLOCK_IMPL_STRUCT (block_struct_type) = 1; 8559260311Spfg finish_struct (block_struct_type, field_decl_chain, NULL_TREE); 8560260311Spfg pop_from_top_level (); 8561260311Spfg return block_struct_type; 8562260311Spfg} 8563260311Spfg/* APPLE LOCAL end radar 6300081 */ 8564260311Spfg 8565260311Spfg/* APPLE LOCAL begin radar 5847213 - radar 6329245 */ 8566260311Spfg/** build_block_struct_type - 8567260311Spfg struct __block_literal_n { 8568260311Spfg void *__isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock 8569260311Spfg int __flags; 8570260311Spfg int __reserved; 8571260311Spfg void *__FuncPtr; 8572260311Spfg struct __block_descriptor { 8573260311Spfg unsigned long int reserved; // NULL 8574260311Spfg unsigned long int Size; // sizeof(struct __block_literal_n) 8575260311Spfg 8576260311Spfg // optional helper functions 8577260311Spfg void *CopyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE 8578260311Spfg void *DestroyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE 8579260311Spfg } *__descriptor; 8580260311Spfg 8581260311Spfg // imported variables 8582260311Spfg int x; // ref variable list ... 8583260311Spfg int *y; // byref variable list 8584260311Spfg }; 8585260311Spfg*/ 8586260311Spfgstatic tree 8587260311Spfgbuild_block_struct_type (struct block_sema_info * block_impl) 8588260311Spfg{ 8589260311Spfg tree field_decl_chain, field_decl, chain; 8590260311Spfg char buffer[32]; 8591260311Spfg static int unique_count; 8592260311Spfg tree block_struct_type; 8593260311Spfg 8594260311Spfg /* Check and see if this block is required to have a Copy/Dispose 8595260311Spfg helper function. If yes, set BlockHasCopyDispose to TRUE. */ 8596260311Spfg for (chain = block_impl->block_ref_decl_list; chain; 8597260311Spfg chain = TREE_CHAIN (chain)) 8598260311Spfg if (block_requires_copying (TREE_VALUE (chain))) 8599260311Spfg { 8600260311Spfg block_impl->BlockHasCopyDispose = TRUE; 8601260311Spfg break; 8602260311Spfg } 8603260311Spfg 8604260311Spfg /* Further check to see that we have __block variables which require 8605260311Spfg Copy/Dispose helpers. */ 8606260311Spfg for (chain = block_impl->block_byref_decl_list; chain; 8607260311Spfg chain = TREE_CHAIN (chain)) 8608260311Spfg if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain))) 8609260311Spfg { 8610260311Spfg block_impl->BlockHasCopyDispose = TRUE; 8611260311Spfg break; 8612260311Spfg } 8613260311Spfg 8614260311Spfg sprintf(buffer, "__block_literal_%d", ++unique_count); 8615260311Spfg push_to_top_level (); 8616260311Spfg block_struct_type = start_struct (RECORD_TYPE, get_identifier (buffer)); 8617260311Spfg 8618260311Spfg /* void *__isa; */ 8619260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__isa"), ptr_type_node); 8620260311Spfg field_decl_chain = field_decl; 8621260311Spfg 8622260311Spfg /* int __flags */ 8623260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__flags"), 8624260311Spfg integer_type_node); 8625260311Spfg chainon (field_decl_chain, field_decl); 8626260311Spfg 8627260311Spfg /* int __reserved */ 8628260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__reserved"), 8629260311Spfg integer_type_node); 8630260311Spfg chainon (field_decl_chain, field_decl); 8631260311Spfg 8632260311Spfg /* void *__FuncPtr; */ 8633260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__FuncPtr"), ptr_type_node); 8634260311Spfg chainon (field_decl_chain, field_decl); 8635260311Spfg 8636260311Spfg /* struct __block_descriptor *__descriptor */ 8637260311Spfg field_decl = build_decl (FIELD_DECL, get_identifier ("__descriptor"), 8638260311Spfg build_block_descriptor_type (block_impl->BlockHasCopyDispose)); 8639260311Spfg chainon (field_decl_chain, field_decl); 8640260311Spfg 8641260311Spfg if (block_impl->BlockHasCopyDispose) 8642260311Spfg { 8643260311Spfg /* If inner block of a nested block has BlockHasCopyDispose, so 8644260311Spfg does its outer block. */ 8645260311Spfg if (block_impl->prev_block_info) 8646260311Spfg block_impl->prev_block_info->BlockHasCopyDispose = TRUE; 8647260311Spfg } 8648260311Spfg 8649260311Spfg /* int x; // ref variable list ... */ 8650260311Spfg for (chain = block_impl->block_ref_decl_list; chain; chain = TREE_CHAIN (chain)) 8651260311Spfg { 8652260311Spfg tree p = TREE_VALUE (chain); 8653260311Spfg /* Note! const-ness of copied in variable must not be carried over to the 8654260311Spfg type of the synthesized struct field. It prevents to assign to this 8655260311Spfg field when copy constructor is synthesized. */ 8656260311Spfg field_decl = build_decl (FIELD_DECL, DECL_NAME (p), 8657260311Spfg c_build_qualified_type (TREE_TYPE (p), 8658260311Spfg TYPE_UNQUALIFIED)); 8659260311Spfg chainon (field_decl_chain, field_decl); 8660260311Spfg } 8661260311Spfg 8662260311Spfg /* int *y; // byref variable list */ 8663260311Spfg for (chain = block_impl->block_byref_decl_list; chain; chain = TREE_CHAIN (chain)) 8664260311Spfg { 8665260311Spfg tree p = TREE_VALUE (chain); 8666260311Spfg field_decl = build_decl (FIELD_DECL, DECL_NAME (p), 8667260311Spfg TREE_TYPE (p)); 8668260311Spfg chainon (field_decl_chain, field_decl); 8669260311Spfg } 8670260311Spfg pop_from_top_level (); 8671260311Spfg finish_struct (block_struct_type, field_decl_chain, NULL_TREE); 8672260311Spfg return block_struct_type; 8673260311Spfg} 8674260311Spfg 8675260311Spfg/** build_descriptor_block_decl - 8676260311Spfg This routine builds a static block_descriptior variable of type: 8677260311Spfg struct __block_descriptor; and initializes it to: 8678260311Spfg {0, sizeof(struct literal_block_n), 8679260311Spfg copy_helper_block_1, // only if block BLOCK_HAS_COPY_DISPOSE 8680260311Spfg destroy_helper_block_1, // only if block BLOCK_HAS_COPY_DISPOSE 8681260311Spfg } 8682260311Spfg*/ 8683260311Spfgstatic tree 8684260311Spfgbuild_descriptor_block_decl (tree block_struct_type, struct block_sema_info *block_impl) 8685260311Spfg{ 8686260311Spfg extern tree create_tmp_var_raw (tree, const char *); 8687260311Spfg static int desc_unique_count; 8688260311Spfg int size; 8689260311Spfg tree helper_addr, fields; 8690260311Spfg tree decl, constructor, initlist; 8691260311Spfg tree exp, bind; 8692260311Spfg char name [32]; 8693260311Spfg tree descriptor_type = 8694260311Spfg TREE_TYPE (build_block_descriptor_type (block_impl->BlockHasCopyDispose)); 8695260311Spfg 8696260311Spfg sprintf (name, "__block_descriptor_tmp_%d", ++desc_unique_count); 8697260311Spfg decl = create_tmp_var_raw (descriptor_type, name); 8698260311Spfg DECL_CONTEXT (decl) = NULL_TREE; 8699260311Spfg DECL_ARTIFICIAL (decl) = 1; 8700260311Spfg 8701260311Spfg /* Initialize "reserved" field to 0 for now. */ 8702260311Spfg fields = TYPE_FIELDS (descriptor_type); 8703260311Spfg initlist = build_tree_list (fields, build_int_cst (long_unsigned_type_node, 0)); 8704260311Spfg fields = TREE_CHAIN (fields); 8705260311Spfg 8706260311Spfg /* Initialize "Size" field. */ 8707260311Spfg size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (block_struct_type)); 8708260311Spfg initlist = tree_cons (fields, 8709260311Spfg build_int_cst (long_unsigned_type_node, size), 8710260311Spfg initlist); 8711260311Spfg 8712260311Spfg if (block_impl->BlockHasCopyDispose) 8713260311Spfg { 8714260311Spfg /* Initialize "CopyFuncPtr" and "DestroyFuncPtr" fields. */ 8715260311Spfg /* Helpers were previously generated completeley as a nested 8716260311Spfg function (and context was required for code gen.) But they are not, 8717260311Spfg so context must be set to NULL so initialization logic does not complain. */ 8718260311Spfg DECL_CONTEXT (block_impl->copy_helper_func_decl) = NULL_TREE; 8719260311Spfg fields = TREE_CHAIN (fields); 8720260311Spfg helper_addr = build_fold_addr_expr (block_impl->copy_helper_func_decl); 8721260311Spfg helper_addr = convert (ptr_type_node, helper_addr); 8722260311Spfg initlist = tree_cons (fields, helper_addr, initlist); 8723260311Spfg DECL_CONTEXT (block_impl->destroy_helper_func_decl) = NULL_TREE; 8724260311Spfg fields = TREE_CHAIN (fields); 8725260311Spfg helper_addr = build_fold_addr_expr (block_impl->destroy_helper_func_decl); 8726260311Spfg helper_addr = convert (ptr_type_node, helper_addr); 8727260311Spfg initlist = tree_cons (fields, helper_addr, initlist); 8728260311Spfg } 8729260311Spfg constructor = build_constructor_from_list (descriptor_type, 8730260311Spfg nreverse (initlist)); 8731260311Spfg TREE_CONSTANT (constructor) = 1; 8732260311Spfg TREE_STATIC (constructor) = 1; 8733260311Spfg TREE_READONLY (constructor) = 1; 8734260311Spfg DECL_INITIAL (decl) = constructor; 8735260311Spfg exp = build_stmt (DECL_EXPR, decl); 8736260311Spfg bind = build3 (BIND_EXPR, void_type_node, decl, exp, NULL); 8737260311Spfg TREE_SIDE_EFFECTS (bind) = 1; 8738260311Spfg add_stmt (bind); 8739260311Spfg TREE_PUBLIC (decl) = 0; 8740260311Spfg TREE_STATIC (decl) = 1; 8741260311Spfg finish_decl (decl, constructor, NULL_TREE); 8742260311Spfg return decl; 8743260311Spfg} 8744260311Spfg 8745260311Spfg/** 8746260311Spfg build_block_struct_initlist - builds the initializer list: 8747260311Spfg { &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa, 8748260311Spfg BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags, 8749260311Spfg 0, // __reserved 8750260311Spfg &helper_1, // __FuncPtr, 8751260311Spfg &static_descriptor_variable // __descriptor, 8752260311Spfg x, // user variables. 8753260311Spfg &y 8754260311Spfg ... 8755260311Spfg } 8756260311Spfg*/ 8757260311Spfgstatic tree 8758260311Spfgbuild_block_struct_initlist (tree block_struct_type, 8759260311Spfg struct block_sema_info *block_impl) 8760260311Spfg{ 8761260311Spfg tree initlist, helper_addr; 8762260311Spfg tree chain, fields; 8763260311Spfg /* APPLE LOCAL radar 7735196 */ 8764260311Spfg unsigned int flags = 0; 8765260311Spfg static tree NSConcreteStackBlock_decl = NULL_TREE; 8766260311Spfg static tree NSConcreteGlobalBlock_decl = NULL_TREE; 8767260311Spfg tree descriptor_block_decl = build_descriptor_block_decl (block_struct_type, block_impl); 8768260311Spfg 8769260311Spfg if (block_impl->BlockHasCopyDispose) 8770260311Spfg /* Note! setting of this flag merely indicates to the runtime that 8771260311Spfg we have destroy_helper_block/copy_helper_block helper 8772260311Spfg routines. */ 8773260311Spfg flags |= BLOCK_HAS_COPY_DISPOSE; 8774260311Spfg /* APPLE LOCAL begin radar 7735196 */ 8775260311Spfg if (block_impl->return_type && aggregate_value_p(block_impl->return_type, 0)) 8776260311Spfg flags |= BLOCK_USE_STRET; 8777260311Spfg /* APPLE LOCAL end 7735196 */ 8778260311Spfg 8779260311Spfg fields = TYPE_FIELDS (block_struct_type); 8780260311Spfg /* APPLE LOCAL begin radar 6230297 */ 8781260311Spfg if (!current_function_decl || 8782260311Spfg (block_impl->block_ref_decl_list == NULL_TREE && 8783260311Spfg block_impl->block_byref_decl_list == NULL_TREE)) 8784260311Spfg /* APPLE LOCAL end radar 6230297 */ 8785260311Spfg { 8786260311Spfg /* This is a global block. */ 8787260311Spfg /* Find an existing declaration for _NSConcreteGlobalBlock or declare 8788260311Spfg extern void *_NSConcreteGlobalBlock; */ 8789260311Spfg if (NSConcreteGlobalBlock_decl == NULL_TREE) 8790260311Spfg { 8791260311Spfg tree name_id = get_identifier("_NSConcreteGlobalBlock"); 8792260311Spfg NSConcreteGlobalBlock_decl = lookup_name (name_id); 8793260311Spfg if (!NSConcreteGlobalBlock_decl) 8794260311Spfg { 8795260311Spfg NSConcreteGlobalBlock_decl = build_decl (VAR_DECL, name_id, ptr_type_node); 8796260311Spfg DECL_EXTERNAL (NSConcreteGlobalBlock_decl) = 1; 8797260311Spfg TREE_PUBLIC (NSConcreteGlobalBlock_decl) = 1; 8798260311Spfg pushdecl_top_level (NSConcreteGlobalBlock_decl); 8799260311Spfg rest_of_decl_compilation (NSConcreteGlobalBlock_decl, 0, 0); 8800260311Spfg } 8801260311Spfg } 8802260311Spfg /* APPLE LOCAL begin radar 6457359 */ 8803260311Spfg initlist = build_tree_list (fields, 8804260311Spfg convert (ptr_type_node, 8805260311Spfg build_fold_addr_expr (NSConcreteGlobalBlock_decl))); 8806260311Spfg /* APPLE LOCAL end radar 6457359 */ 8807260311Spfg flags |= BLOCK_IS_GLOBAL; 8808260311Spfg } 8809260311Spfg else 8810260311Spfg { 8811260311Spfg /* Find an existing declaration for _NSConcreteStackBlock or declare 8812260311Spfg extern void *_NSConcreteStackBlock; */ 8813260311Spfg if (NSConcreteStackBlock_decl == NULL_TREE) 8814260311Spfg { 8815260311Spfg tree name_id = get_identifier("_NSConcreteStackBlock"); 8816260311Spfg NSConcreteStackBlock_decl = lookup_name (name_id); 8817260311Spfg if (!NSConcreteStackBlock_decl) 8818260311Spfg { 8819260311Spfg NSConcreteStackBlock_decl = build_decl (VAR_DECL, name_id, ptr_type_node); 8820260311Spfg DECL_EXTERNAL (NSConcreteStackBlock_decl) = 1; 8821260311Spfg TREE_PUBLIC (NSConcreteStackBlock_decl) = 1; 8822260311Spfg pushdecl_top_level (NSConcreteStackBlock_decl); 8823260311Spfg rest_of_decl_compilation (NSConcreteStackBlock_decl, 0, 0); 8824260311Spfg } 8825260311Spfg } 8826260311Spfg /* APPLE LOCAL begin radar 6457359 */ 8827260311Spfg initlist = build_tree_list (fields, 8828260311Spfg convert (ptr_type_node, 8829260311Spfg build_fold_addr_expr (NSConcreteStackBlock_decl))); 8830260311Spfg /* APPLE LOCAL end radar 6457359 */ 8831260311Spfg } 8832260311Spfg fields = TREE_CHAIN (fields); 8833260311Spfg 8834260311Spfg /* __flags */ 8835260311Spfg initlist = tree_cons (fields, 8836260311Spfg build_int_cst (integer_type_node, flags), 8837260311Spfg initlist); 8838260311Spfg fields = TREE_CHAIN (fields); 8839260311Spfg 8840260311Spfg /* __reserved */ 8841260311Spfg initlist = tree_cons (fields, 8842260311Spfg build_int_cst (integer_type_node, 0), 8843260311Spfg initlist); 8844260311Spfg fields = TREE_CHAIN (fields); 8845260311Spfg 8846260311Spfg /* __FuncPtr */ 8847260311Spfg helper_addr = build_fold_addr_expr (block_impl->helper_func_decl); 8848260311Spfg helper_addr = convert (ptr_type_node, helper_addr); 8849260311Spfg initlist = tree_cons (fields, helper_addr, initlist); 8850260311Spfg fields = TREE_CHAIN (fields); 8851260311Spfg 8852260311Spfg /* __descriptor */ 8853260311Spfg /* APPLE LOCAL begin radar 6457359 */ 8854260311Spfg initlist = tree_cons (fields, 8855260311Spfg build_fold_addr_expr (descriptor_block_decl), 8856260311Spfg initlist); 8857260311Spfg /* APPLE LOCAL end radar 6457359 */ 8858260311Spfg for (chain = block_impl->block_original_ref_decl_list; chain; 8859260311Spfg chain = TREE_CHAIN (chain)) 8860260311Spfg { 8861260311Spfg tree y = TREE_VALUE (chain); 8862260311Spfg TREE_USED (y) = 1; 8863260311Spfg fields = TREE_CHAIN (fields); 8864260311Spfg initlist = tree_cons (fields, y, initlist); 8865260311Spfg } 8866260311Spfg for (chain = block_impl->block_byref_decl_list; chain; 8867260311Spfg chain = TREE_CHAIN (chain)) 8868260311Spfg { 8869260311Spfg tree y = lookup_name (DECL_NAME (TREE_VALUE (chain))); 8870260311Spfg tree forwarding_expr; 8871260311Spfg gcc_assert (y); 8872260311Spfg TREE_USED (y) = 1; 8873260311Spfg if (COPYABLE_BYREF_LOCAL_VAR (y)) 8874260311Spfg { 8875260311Spfg /* For variables declared __block, either the original one 8876260311Spfg at the point of declaration or the imported version (which is 8877260311Spfg initialized in the helper function's prologue) is used to 8878260311Spfg initilize the byref variable field in the temporary. */ 8879260311Spfg if (TREE_CODE (TREE_TYPE (y)) != RECORD_TYPE) 8880260311Spfg y = build_indirect_ref (y, "unary *"); 8881260311Spfg /* We will be using the __block_struct_variable.__forwarding as the 8882260311Spfg initializer. */ 8883260311Spfg forwarding_expr = build_component_ref (y, get_identifier ("__forwarding")); 8884260311Spfg } 8885260311Spfg else 8886260311Spfg /* Global variable is always assumed passed by its address. */ 8887260311Spfg forwarding_expr = build_fold_addr_expr (y); 8888260311Spfg fields = TREE_CHAIN (fields); 8889260311Spfg initlist = tree_cons (fields, forwarding_expr, initlist); 8890260311Spfg } 8891260311Spfg return initlist; 8892260311Spfg} 8893260311Spfg 8894260311Spfg/** 8895260311Spfg build_block_literal_tmp - This routine: 8896260311Spfg 8897260311Spfg 1) builds block type: 8898260311Spfg struct __block_literal_n { 8899260311Spfg void *__isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock 8900260311Spfg int __flags; 8901260311Spfg int __reserved; 8902260311Spfg void *__FuncPtr 8903260311Spfg struct __block_descriptor { 8904260311Spfg unsigned long int reserved; // NULL 8905260311Spfg unsigned long int Size; // sizeof(struct Block_literal_1) 8906260311Spfg 8907260311Spfg // optional helper functions 8908260311Spfg void *CopyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE 8909260311Spfg void *DestroyFuncPtr; // When BLOCK_HAS_COPY_DISPOSE 8910260311Spfg } *__descriptor; 8911260311Spfg 8912260311Spfg // imported variables 8913260311Spfg int x; // ref variable list ... 8914260311Spfg int *y; // byref variable list 8915260311Spfg }; 8916260311Spfg 8917260311Spfg 2) build function prototype: 8918260311Spfg double helper_1(struct __block_literal_n *ii, int z); 8919260311Spfg 8920260311Spfg 3) build the temporary initialization: 8921260311Spfg struct __block_literal_n I = { 8922260311Spfg &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa, 8923260311Spfg BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags, 8924260311Spfg 0, // __reserved 8925260311Spfg &helper_1, // __FuncPtr 8926260311Spfg &static_descriptor_variable // __descriptor, 8927260311Spfg x, // user variables. 8928260311Spfg &y 8929260311Spfg ... 8930260311Spfg }; 8931260311SpfgIt return the temporary. 8932260311Spfg*/ 8933260311Spfg 8934260311Spfgstatic tree 8935260311Spfgbuild_block_literal_tmp (const char *name, 8936260311Spfg struct block_sema_info * block_impl) 8937260311Spfg{ 8938260311Spfg extern tree create_tmp_var_raw (tree, const char *); 8939260311Spfg tree block_holder_tmp_decl; 8940260311Spfg tree constructor, initlist; 8941260311Spfg tree exp, bind; 8942260311Spfg tree block_struct_type = TREE_TYPE (block_impl->block_arg_ptr_type); 8943260311Spfg /* APPLE LOCAL begin radar 6230297 */ 8944260311Spfg bool staticBlockTmp = (block_impl->block_ref_decl_list == NULL_TREE && 8945260311Spfg block_impl->block_byref_decl_list == NULL_TREE); 8946260311Spfg 8947260311Spfg 8948260311Spfg block_holder_tmp_decl = create_tmp_var_raw (block_struct_type, name); 8949260311Spfg /* Context will not be known until when the literal is synthesized. 8950260311Spfg This is more so in the case of nested block literal blocks. */ 8951260311Spfg DECL_CONTEXT (block_holder_tmp_decl) = staticBlockTmp ? NULL_TREE 8952260311Spfg : current_function_decl; 8953260311Spfg /* In the new ABI, helper function decl. is the initializer for the 8954260311Spfg descriptor variable which is always declared static. So, it must 8955260311Spfg have no context; otherwise, gcc thinks that it requires trampoline! when 8956260311Spfg address of this function is used as initializer. */ 8957260311Spfg DECL_CONTEXT (block_impl->helper_func_decl) = NULL_TREE; 8958260311Spfg /* APPLE LOCAL end radar 6230297 */ 8959260311Spfg DECL_ARTIFICIAL (block_holder_tmp_decl) = 1; 8960260311Spfg 8961260311Spfg initlist = build_block_struct_initlist (block_struct_type, 8962260311Spfg block_impl); 8963260311Spfg initlist = nreverse (initlist); 8964260311Spfg constructor = build_constructor_from_list (block_struct_type, 8965260311Spfg initlist); 8966260311Spfg TREE_CONSTANT (constructor) = 1; 8967260311Spfg TREE_STATIC (constructor) = 1; 8968260311Spfg TREE_READONLY (constructor) = 1; 8969260311Spfg DECL_INITIAL (block_holder_tmp_decl) = constructor; 8970260311Spfg exp = build_stmt (DECL_EXPR, block_holder_tmp_decl); 8971260311Spfg bind = build3 (BIND_EXPR, void_type_node, block_holder_tmp_decl, exp, NULL); 8972260311Spfg TREE_SIDE_EFFECTS (bind) = 1; 8973260311Spfg add_stmt (bind); 8974260311Spfg /* Temporary representing a global block is made global static. */ 8975260311Spfg /* APPLE LOCAL radar 6230297 */ 8976260311Spfg if (staticBlockTmp || global_bindings_p ()) { 8977260311Spfg TREE_PUBLIC (block_holder_tmp_decl) = 0; 8978260311Spfg TREE_STATIC (block_holder_tmp_decl) = 1; 8979260311Spfg finish_decl (block_holder_tmp_decl, constructor, NULL_TREE); 8980260311Spfg } 8981260311Spfg return block_holder_tmp_decl; 8982260311Spfg} 8983260311Spfg/* APPLE LOCAL end radar 5847213 - radar 6329245 */ 8984260311Spfg 8985260311Spfgstatic tree 8986260311Spfgclean_and_exit (tree block) 8987260311Spfg{ 8988260311Spfg pop_function_context (); 8989260311Spfg free (finish_block (block)); 8990260311Spfg return error_mark_node; 8991260311Spfg} 8992260311Spfg 8993260311Spfg/** synth_copy_helper_block_func - This function synthesizes 8994260311Spfg void copy_helper_block (struct block* _dest, struct block *_src) function. 8995260311Spfg*/ 8996260311Spfg 8997260311Spfgstatic void 8998260311Spfgsynth_copy_helper_block_func (struct block_sema_info * block_impl) 8999260311Spfg{ 9000260311Spfg tree stmt, chain, fnbody; 9001260311Spfg tree dst_arg, src_arg; 9002260311Spfg struct c_arg_info * arg_info; 9003260311Spfg /* Set up: (struct block* _dest, struct block *_src) parameters. */ 9004260311Spfg dst_arg = build_decl (PARM_DECL, get_identifier ("_dst"), 9005260311Spfg block_impl->block_arg_ptr_type); 9006260311Spfg DECL_CONTEXT (dst_arg) = cur_block->copy_helper_func_decl; 9007260311Spfg TREE_USED (dst_arg) = 1; 9008260311Spfg DECL_ARG_TYPE (dst_arg) = block_impl->block_arg_ptr_type; 9009260311Spfg src_arg = build_decl (PARM_DECL, get_identifier ("_src"), 9010260311Spfg block_impl->block_arg_ptr_type); 9011260311Spfg /* APPLE LOCAL radar 5847213 */ 9012260311Spfg DECL_CONTEXT (src_arg) = cur_block->copy_helper_func_decl; 9013260311Spfg TREE_USED (src_arg) = 1; 9014260311Spfg DECL_ARG_TYPE (src_arg) = block_impl->block_arg_ptr_type; 9015260311Spfg arg_info = xcalloc (1, sizeof (struct c_arg_info)); 9016260311Spfg TREE_CHAIN (dst_arg) = src_arg; 9017260311Spfg arg_info->parms = dst_arg; 9018260311Spfg arg_info->types = tree_cons (NULL_TREE, block_impl->block_arg_ptr_type, 9019260311Spfg tree_cons (NULL_TREE, 9020260311Spfg block_impl->block_arg_ptr_type, 9021260311Spfg NULL_TREE)); 9022260311Spfg /* function header synthesis. */ 9023260311Spfg push_function_context (); 9024260311Spfg start_block_helper_function (cur_block->copy_helper_func_decl); 9025260311Spfg store_parm_decls_from (arg_info); 9026260311Spfg 9027260311Spfg /* Body of the function. */ 9028260311Spfg stmt = c_begin_compound_stmt (true); 9029260311Spfg for (chain = block_impl->block_ref_decl_list; chain; 9030260311Spfg chain = TREE_CHAIN (chain)) 9031260311Spfg if (block_requires_copying (TREE_VALUE (chain))) 9032260311Spfg { 9033260311Spfg /* APPLE LOCAL begin radar 6175959 */ 9034260311Spfg int flag; 9035260311Spfg tree call_exp; 9036260311Spfg tree p = TREE_VALUE (chain); 9037260311Spfg tree dst_block_component, src_block_component; 9038260311Spfg dst_block_component = build_component_ref (build_indirect_ref (dst_arg, "->"), 9039260311Spfg DECL_NAME (p)); 9040260311Spfg src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), 9041260311Spfg DECL_NAME (p)); 9042260311Spfg 9043260311Spfg if (TREE_CODE (TREE_TYPE (p)) == BLOCK_POINTER_TYPE) 9044260311Spfg /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, BLOCK_FIELD_IS_BLOCK) */ 9045260311Spfg flag = BLOCK_FIELD_IS_BLOCK; 9046260311Spfg else 9047260311Spfg /* _Block_object_assign(&_dest->myImportedBlock, _src->myImportedClosure, BLOCK_FIELD_IS_OBJECT) */ 9048260311Spfg flag = BLOCK_FIELD_IS_OBJECT; 9049260311Spfg dst_block_component = build_fold_addr_expr (dst_block_component); 9050260311Spfg call_exp = build_block_object_assign_call_exp (dst_block_component, src_block_component, flag); 9051260311Spfg add_stmt (call_exp); 9052260311Spfg /* APPLE LOCAL end radar 6175959 */ 9053260311Spfg } 9054260311Spfg 9055260311Spfg /* For each __block declared variable must generate call to: 9056260311Spfg _Block_object_assign(&_dest->myImportedBlock, _src->myImportedBlock, BLOCK_FIELD_IS_BYREF [|BLOCK_FIELD_IS_WEAK]) 9057260311Spfg */ 9058260311Spfg for (chain = block_impl->block_byref_decl_list; chain; 9059260311Spfg chain = TREE_CHAIN (chain)) 9060260311Spfg if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain))) 9061260311Spfg { 9062260311Spfg int flag = BLOCK_FIELD_IS_BYREF; 9063260311Spfg tree call_exp; 9064260311Spfg tree p = TREE_VALUE (chain); 9065260311Spfg tree dst_block_component, src_block_component; 9066260311Spfg dst_block_component = build_component_ref (build_indirect_ref (dst_arg, "->"), 9067260311Spfg DECL_NAME (p)); 9068260311Spfg src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), 9069260311Spfg DECL_NAME (p)); 9070260311Spfg 9071260311Spfg /* _Block_object_assign(&_dest->myImportedClosure, _src->myImportedClosure, BLOCK_FIELD_IS_BYREF [|BLOCK_FIELD_IS_WEAK]) */ 9072260311Spfg if (COPYABLE_WEAK_BLOCK (p)) 9073260311Spfg flag |= BLOCK_FIELD_IS_WEAK; 9074260311Spfg 9075260311Spfg dst_block_component = build_fold_addr_expr (dst_block_component); 9076260311Spfg call_exp = build_block_object_assign_call_exp (dst_block_component, src_block_component, flag); 9077260311Spfg add_stmt (call_exp); 9078260311Spfg } 9079260311Spfg 9080260311Spfg fnbody = c_end_compound_stmt (stmt, true); 9081260311Spfg add_stmt (fnbody); 9082260311Spfg finish_function (); 9083260311Spfg pop_function_context (); 9084260311Spfg free (arg_info); 9085260311Spfg} 9086260311Spfg 9087260311Spfgstatic void 9088260311Spfgsynth_destroy_helper_block_func (struct block_sema_info * block_impl) 9089260311Spfg{ 9090260311Spfg tree stmt, chain, fnbody; 9091260311Spfg tree src_arg; 9092260311Spfg struct c_arg_info * arg_info; 9093260311Spfg /* Set up: (struct block *_src) parameter. */ 9094260311Spfg src_arg = build_decl (PARM_DECL, get_identifier ("_src"), 9095260311Spfg block_impl->block_arg_ptr_type); 9096260311Spfg TREE_USED (src_arg) = 1; 9097260311Spfg DECL_ARG_TYPE (src_arg) = block_impl->block_arg_ptr_type; 9098260311Spfg arg_info = xcalloc (1, sizeof (struct c_arg_info)); 9099260311Spfg arg_info->parms = src_arg; 9100260311Spfg arg_info->types = tree_cons (NULL_TREE, block_impl->block_arg_ptr_type, 9101260311Spfg NULL_TREE); 9102260311Spfg 9103260311Spfg /* function header synthesis. */ 9104260311Spfg push_function_context (); 9105260311Spfg start_block_helper_function (cur_block->destroy_helper_func_decl); 9106260311Spfg store_parm_decls_from (arg_info); 9107260311Spfg 9108260311Spfg /* Body of the function. */ 9109260311Spfg stmt = c_begin_compound_stmt (true); 9110260311Spfg for (chain = block_impl->block_ref_decl_list; chain; 9111260311Spfg chain = TREE_CHAIN (chain)) 9112260311Spfg if (block_requires_copying (TREE_VALUE (chain))) 9113260311Spfg { 9114260311Spfg int flag; 9115260311Spfg tree rel_exp; 9116260311Spfg tree p = TREE_VALUE (chain); 9117260311Spfg tree src_block_component; 9118260311Spfg src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), 9119260311Spfg DECL_NAME (p)); 9120260311Spfg 9121260311Spfg if (TREE_CODE (TREE_TYPE (p)) == BLOCK_POINTER_TYPE) 9122260311Spfg /* _Block_object_dispose(_src->imported_object_0, BLOCK_FIELD_IS_BLOCK); */ 9123260311Spfg flag = BLOCK_FIELD_IS_BLOCK; 9124260311Spfg else 9125260311Spfg /* _Block_object_dispose(_src->imported_object_0, BLOCK_FIELD_IS_OBJECT); */ 9126260311Spfg flag = BLOCK_FIELD_IS_OBJECT; 9127260311Spfg rel_exp = build_block_object_dispose_call_exp (src_block_component, flag); 9128260311Spfg add_stmt (rel_exp); 9129260311Spfg } 9130260311Spfg 9131260311Spfg /* For each __block declared variable must generate call to: 9132260311Spfg _Block_object_dispose(_src->myImportedClosure, BLOCK_FIELD_IS_BYREF[|BLOCK_FIELD_IS_WEAK]) 9133260311Spfg */ 9134260311Spfg for (chain = block_impl->block_byref_decl_list; chain; 9135260311Spfg chain = TREE_CHAIN (chain)) 9136260311Spfg if (COPYABLE_BYREF_LOCAL_VAR (TREE_VALUE (chain))) 9137260311Spfg { 9138260311Spfg tree call_exp; 9139260311Spfg int flag = BLOCK_FIELD_IS_BYREF; 9140260311Spfg tree p = TREE_VALUE (chain); 9141260311Spfg tree src_block_component; 9142260311Spfg 9143260311Spfg src_block_component = build_component_ref (build_indirect_ref (src_arg, "->"), 9144260311Spfg DECL_NAME (p)); 9145260311Spfg if (COPYABLE_WEAK_BLOCK (p)) 9146260311Spfg flag |= BLOCK_FIELD_IS_WEAK; 9147260311Spfg /* _Block_object_dispose(_src->myImportedClosure, BLOCK_FIELD_IS_BYREF[|BLOCK_FIELD_IS_WEAK]) */ 9148260311Spfg call_exp = build_block_object_dispose_call_exp (src_block_component, flag); 9149260311Spfg add_stmt (call_exp); 9150260311Spfg } 9151260311Spfg 9152260311Spfg fnbody = c_end_compound_stmt (stmt, true); 9153260311Spfg add_stmt (fnbody); 9154260311Spfg finish_function (); 9155260311Spfg pop_function_context (); 9156260311Spfg free (arg_info); 9157260311Spfg} 9158260311Spfg 9159260311Spfg/* Parse a block-id. 9160260311Spfg 9161260311Spfg GNU Extension: 9162260311Spfg 9163260311Spfg block-id: 9164260311Spfg specifier-qualifier-list block-declarator 9165260311Spfg 9166260311Spfg Returns the DECL specified or implied. */ 9167260311Spfg 9168260311Spfgstatic tree 9169260311Spfgc_parser_block_id (c_parser* parser) 9170260311Spfg{ 9171260311Spfg struct c_declspecs *specs = build_null_declspecs (); 9172260311Spfg struct c_declarator *declarator; 9173260311Spfg bool dummy = false; 9174260311Spfg 9175260311Spfg c_parser_declspecs (parser, specs, false, true, true); 9176260311Spfg if (!specs->declspecs_seen_p) 9177260311Spfg { 9178260311Spfg c_parser_error (parser, "expected specifier-qualifier-list"); 9179260311Spfg return NULL; 9180260311Spfg } 9181260311Spfg pending_xref_error (); 9182260311Spfg finish_declspecs (specs); 9183260311Spfg declarator = c_parser_declarator (parser, specs->type_seen_p, 9184260311Spfg C_DTR_BLOCK, &dummy); 9185260311Spfg if (declarator == NULL) 9186260311Spfg return NULL; 9187260311Spfg 9188260311Spfg return grokblockdecl (specs, declarator); 9189260311Spfg} 9190260311Spfg 9191260311Spfg/* Parse a block-literal-expr. 9192260311Spfg 9193260311Spfg GNU Extension: 9194260311Spfg 9195260311Spfg block-literal-expr: 9196260311Spfg ^ parameter-declation-clause exception-specification [opt] compound-statement 9197260311Spfg ^ block-id compound-statement 9198260311Spfg 9199260311Spfg It synthesizes the helper function for later generation and builds 9200260311Spfg the necessary data to represent the block literal where it is 9201260311Spfg declared. */ 9202260311Spfgstatic tree 9203260311Spfgc_parser_block_literal_expr (c_parser* parser) 9204260311Spfg{ 9205260311Spfg char name [32]; 9206260311Spfg static int global_unique_count; 9207260311Spfg int unique_count = ++global_unique_count; 9208260311Spfg tree block_helper_function_decl; 9209260311Spfg tree expr, body, type, arglist = void_list_node, ftype; 9210260311Spfg tree self_arg, stmt; 9211260311Spfg struct c_arg_info *args = NULL; 9212260311Spfg tree arg_type = void_list_node; 9213260311Spfg struct block_sema_info *block_impl; 9214260311Spfg tree tmp; 9215260311Spfg bool open_paren_seen = false; 9216260311Spfg tree restype; 9217260311Spfg tree fnbody, typelist; 9218260311Spfg tree helper_function_type; 9219260311Spfg tree block; 9220260311Spfg /* APPLE LOCAL radar 6185344 */ 9221260311Spfg tree declared_block_return_type = NULL_TREE; 9222260311Spfg /* APPLE LOCAL radar 6237713 */ 9223260311Spfg tree attributes = NULL_TREE; 9224260311Spfg 9225260311Spfg c_parser_consume_token (parser); /* eat '^' */ 9226260311Spfg 9227260311Spfg /* APPLE LOCAL begin radar 6237713 */ 9228260311Spfg if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 9229260311Spfg attributes = c_parser_attributes (parser); 9230260311Spfg /* APPLE LOCAL end radar 6237713 */ 9231260311Spfg 9232260311Spfg if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 9233260311Spfg { 9234260311Spfg /* Parse the optional argument list */ 9235260311Spfg c_parser_consume_token (parser); 9236260311Spfg /* Open the scope to collect parameter decls */ 9237260311Spfg push_scope (); 9238260311Spfg args = c_parser_parms_declarator (parser, true, NULL_TREE); 9239260311Spfg /* Check for args as it might be NULL due to error. */ 9240260311Spfg if (args) 9241260311Spfg { 9242260311Spfg arglist = args->parms; 9243260311Spfg arg_type = args->types; 9244260311Spfg } 9245260311Spfg else 9246260311Spfg { 9247260311Spfg pop_scope (); 9248260311Spfg return error_mark_node; 9249260311Spfg } 9250260311Spfg open_paren_seen = true; 9251260311Spfg pop_scope (); 9252260311Spfg } 9253260311Spfg else if (c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) 9254260311Spfg { 9255260311Spfg /* Parse user declared return type. */ 9256260311Spfg tree decl; 9257260311Spfg 9258260311Spfg /* APPLE LOCAL begin radar 6237713 */ 9259260311Spfg if (attributes) 9260260311Spfg { 9261260311Spfg warning (0, "attributes before block type are ignored"); 9262260311Spfg attributes = NULL_TREE; 9263260311Spfg } 9264260311Spfg /* APPLE LOCAL end radar 6237713 */ 9265260311Spfg 9266260311Spfg decl = c_parser_block_id (parser); 9267260311Spfg 9268260311Spfg if (decl && decl != error_mark_node) 9269260311Spfg { 9270260311Spfg arg_type = TYPE_ARG_TYPES (TREE_TYPE (decl)); 9271260311Spfg arglist = DECL_ARGUMENTS (decl); 9272260311Spfg declared_block_return_type = TREE_TYPE (TREE_TYPE (decl)); 9273260311Spfg } 9274260311Spfg } 9275260311Spfg 9276260311Spfg block = begin_block (); 9277260311Spfg 9278260311Spfg cur_block->arg_info = NULL; 9279260311Spfg if (declared_block_return_type) 9280260311Spfg { 9281260311Spfg cur_block->return_type = TYPE_MAIN_VARIANT (declared_block_return_type); 9282260311Spfg cur_block->block_has_return_type = true; 9283260311Spfg } 9284260311Spfg else 9285260311Spfg cur_block->return_type = NULL_TREE; 9286260311Spfg 9287260311Spfg if (args) 9288260311Spfg cur_block->arg_info = args; 9289260311Spfg else 9290260311Spfg cur_block->arg_info = xcalloc (1, sizeof (struct c_arg_info)); 9291260311Spfg 9292260311Spfg if (declared_block_return_type) 9293260311Spfg { 9294260311Spfg cur_block->arg_info->parms = arglist; 9295260311Spfg cur_block->arg_info->types = arg_type; 9296260311Spfg } 9297260311Spfg 9298260311Spfg /* Must also build hidden parameter .block_descriptor added to the helper 9299260311Spfg function, even though we do not know its type yet. */ 9300260311Spfg /* APPLE LOCAL radar 6404979 */ 9301260311Spfg self_arg = build_decl (PARM_DECL, get_identifier (".block_descriptor"), 9302260311Spfg ptr_type_node); 9303260311Spfg TREE_USED (self_arg) = 1; /* Prevent unused parameter '.block_descriptor' warning. */ 9304260311Spfg TREE_CHAIN (self_arg) = cur_block->arg_info->parms; 9305260311Spfg cur_block->arg_info->types = tree_cons (NULL_TREE, ptr_type_node, arg_type); 9306260311Spfg cur_block->arg_info->parms = self_arg; 9307260311Spfg 9308260311Spfg /* APPLE LOCAL begin radar 6185344 */ 9309260311Spfg /* Build the declaration of the helper function (if we do not know its result 9310260311Spfg type yet, assume it is 'void'. If user provided it, use it). 9311260311Spfg Treat this as a nested function and use nested function infrastructure for 9312260311Spfg its generation. */ 9313260311Spfg 9314260311Spfg ftype = build_function_type ((!cur_block->block_has_return_type 9315260311Spfg ? void_type_node : cur_block->return_type), 9316260311Spfg cur_block->arg_info->types); 9317260311Spfg /* APPLE LOCAL end radar 6185344 */ 9318260311Spfg /* APPLE LOCAL radar 6160536 - radar 6411649 */ 9319260311Spfg block_helper_function_decl = build_helper_func_decl (build_block_helper_name (0), 9320260311Spfg ftype); 9321260311Spfg DECL_CONTEXT (block_helper_function_decl) = current_function_decl; 9322260311Spfg cur_block->helper_func_decl = block_helper_function_decl; 9323260311Spfg 9324260311Spfg push_function_context (); 9325260311Spfg start_block_helper_function (cur_block->helper_func_decl); 9326260311Spfg /* Set block's scope to the scope of the helper function's main body. 9327260311Spfg This is primarily used when nested blocks are declared. */ 9328260311Spfg /* FIXME: Name of objc_get_current_scope needs to get changed. */ 9329260311Spfg cur_block->the_scope = (struct c_scope*)objc_get_current_scope (); 9330260311Spfg 9331260311Spfg /* Enter parameter list to the scope of the helper function. */ 9332260311Spfg store_parm_decls_from (cur_block->arg_info); 9333260311Spfg 9334260311Spfg /* APPLE LOCAL begin radar 6237713 */ 9335260311Spfg if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 9336260311Spfg attributes = c_parser_attributes (parser); 9337260311Spfg /* APPLE LOCAL radar 6246527 */ 9338260311Spfg any_recognized_block_attribute (attributes); 9339260311Spfg decl_attributes (&cur_block->helper_func_decl, attributes, 0); 9340260311Spfg /* APPLE LOCAL end radar 6237713 */ 9341260311Spfg 9342260311Spfg /* Start parsing body or expression part of the block literal. */ 9343260311Spfg if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) { 9344260311Spfg tree save_c_break_label = c_break_label; 9345260311Spfg tree save_c_cont_label = c_cont_label; 9346260311Spfg /* Indicate no valid break/continue context by setting these variables 9347260311Spfg to some non-null, non-label value. We'll notice and emit the proper 9348260311Spfg error message in c_finish_bc_stmt. */ 9349260311Spfg c_break_label = c_cont_label = size_zero_node; 9350260311Spfg c_parser_consume_token (parser); /* Consure '{'. */ 9351260311Spfg stmt = c_begin_compound_stmt (true); 9352260311Spfg c_parser_compound_statement_nostart (parser); 9353260311Spfg c_cont_label = save_c_cont_label; 9354260311Spfg c_break_label = save_c_break_label; 9355260311Spfg } 9356260311Spfg else 9357260311Spfg { 9358260311Spfg struct c_expr expr; 9359260311Spfg stmt = c_begin_compound_stmt (true); 9360260311Spfg error ("blocks require { }"); 9361260311Spfg expr = c_parser_cast_expression (parser, NULL); 9362260311Spfg body = expr.value; 9363260311Spfg if (body == error_mark_node) 9364260311Spfg return clean_and_exit (block); 9365260311Spfg 9366260311Spfg if (cur_block->return_type) 9367260311Spfg { 9368260311Spfg error ("return not allowed in block expression literal"); 9369260311Spfg return clean_and_exit (block); 9370260311Spfg } 9371260311Spfg else if (!open_paren_seen) 9372260311Spfg { 9373260311Spfg error ("argument list is required for block expression literals"); 9374260311Spfg return clean_and_exit (block); 9375260311Spfg } 9376260311Spfg else 9377260311Spfg { 9378260311Spfg tree restype = TYPE_MAIN_VARIANT (TREE_TYPE (body)); 9379260311Spfg 9380260311Spfg add_stmt (body); 9381260311Spfg TREE_TYPE (current_function_decl) 9382260311Spfg = build_function_type (restype, 9383260311Spfg TYPE_ARG_TYPES (TREE_TYPE (current_function_decl))); 9384260311Spfg TREE_TYPE (DECL_RESULT (current_function_decl)) = restype; 9385260311Spfg relayout_decl (DECL_RESULT (current_function_decl)); 9386260311Spfg cur_block->return_type = restype; 9387260311Spfg } 9388260311Spfg } 9389260311Spfg 9390260311Spfg cur_block->block_arg_ptr_type = 9391260311Spfg build_pointer_type (build_block_struct_type (cur_block)); 9392260311Spfg 9393260311Spfg restype = !cur_block->return_type ? void_type_node 9394260311Spfg : cur_block->return_type; 9395260311Spfg if (restype == error_mark_node) 9396260311Spfg return clean_and_exit (block); 9397260311Spfg 9398260311Spfg /* Now that we know type of the hidden .block_descriptor argument, fix its type. */ 9399260311Spfg TREE_TYPE (self_arg) = cur_block->block_arg_ptr_type; 9400260311Spfg DECL_ARG_TYPE (self_arg) = cur_block->block_arg_ptr_type; 9401260311Spfg 9402260311Spfg /* The DECL_RESULT should already have the correct type by now. */ 9403260311Spfg gcc_assert (TREE_TYPE (DECL_RESULT (current_function_decl)) 9404260311Spfg == restype); 9405260311Spfg 9406260311Spfg cur_block->block_body = stmt; 9407260311Spfg block_build_prologue (cur_block); 9408260311Spfg 9409260311Spfg fnbody = c_end_compound_stmt (stmt, true); 9410260311Spfg add_stmt (fnbody); 9411260311Spfg 9412260311Spfg /* We are done parsing of the block body. Return type of block is now known. 9413260311Spfg We also know all we need to know about the helper function. So, fix its 9414260311Spfg type here. */ 9415260311Spfg /* We moved this here because for global blocks, helper function body is 9416260311Spfg not nested and is gimplified in call to finish_function() and return type 9417260311Spfg of the function must be correct. */ 9418260311Spfg ftype = build_function_type (restype, arg_type); 9419260311Spfg /* Declare helper function; as in: 9420260311Spfg double helper_1(struct block_1 *ii, int z); */ 9421260311Spfg typelist = TYPE_ARG_TYPES (ftype); 9422260311Spfg /* (struct block_1 *ii, int z, ...) */ 9423260311Spfg typelist = tree_cons (NULL_TREE, cur_block->block_arg_ptr_type, 9424260311Spfg typelist); 9425260311Spfg helper_function_type = build_function_type (TREE_TYPE (ftype), typelist); 9426260311Spfg TREE_TYPE (cur_block->helper_func_decl) = helper_function_type; 9427260311Spfg finish_function (); 9428260311Spfg pop_function_context (); 9429260311Spfg 9430260311Spfg /* Build the declaration for copy_helper_block and destroy_helper_block 9431260311Spfg helper functions for later use. */ 9432260311Spfg 9433260311Spfg if (cur_block->BlockHasCopyDispose) 9434260311Spfg { 9435260311Spfg /* void copy_helper_block (struct block*, struct block *); */ 9436260311Spfg tree s_ftype = build_function_type (void_type_node, 9437260311Spfg tree_cons (NULL_TREE, cur_block->block_arg_ptr_type, 9438260311Spfg tree_cons (NULL_TREE, 9439260311Spfg cur_block->block_arg_ptr_type, 9440260311Spfg void_list_node))); 9441260311Spfg sprintf (name, "__copy_helper_block_%d", unique_count); 9442260311Spfg cur_block->copy_helper_func_decl = 9443260311Spfg build_helper_func_decl (get_identifier (name), s_ftype); 9444260311Spfg synth_copy_helper_block_func (cur_block); 9445260311Spfg 9446260311Spfg /* void destroy_helper_block (struct block*); */ 9447260311Spfg s_ftype = build_function_type (void_type_node, 9448260311Spfg tree_cons (NULL_TREE, 9449260311Spfg cur_block->block_arg_ptr_type, void_list_node)); 9450260311Spfg sprintf (name, "__destroy_helper_block_%d", unique_count); 9451260311Spfg cur_block->destroy_helper_func_decl = 9452260311Spfg build_helper_func_decl (get_identifier (name), s_ftype); 9453260311Spfg synth_destroy_helper_block_func (cur_block); 9454260311Spfg } 9455260311Spfg 9456260311Spfg block_impl = finish_block (block); 9457260311Spfg 9458260311Spfg /* Build unqiue name of the temporary used in code gen. */ 9459260311Spfg sprintf (name, "__block_holder_tmp_%d", unique_count); 9460260311Spfg tmp = build_block_literal_tmp (name, block_impl); 9461260311Spfg tmp = build_fold_addr_expr (tmp); 9462260311Spfg type = build_block_pointer_type (ftype); 9463260311Spfg expr = convert (type, convert (ptr_type_node, tmp)); 9464260311Spfg free (block_impl); 9465260311Spfg return expr; 9466260311Spfg} 9467260311Spfg/* APPLE LOCAL end radar 5732232 - blocks (C++ ce) */ 9468260311Spfg 9469169689Skan#include "gt-c-parser.h" 9470