1 //===--- ParseObjC.cpp - Objective C Parsing ------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Objective-C portions of the Parser interface. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Parse/Parser.h" 15 #include "clang/Parse/DeclSpec.h" 16 #include "clang/Parse/Scope.h" 17 #include "clang/Parse/ParseDiagnostic.h" 18 #include "llvm/ADT/SmallVector.h" 19 using namespace clang; 20 21 22 /// ParseObjCAtDirectives - Handle parts of the external-declaration production: 23 /// external-declaration: [C99 6.9] 24 /// [OBJC] objc-class-definition 25 /// [OBJC] objc-class-declaration 26 /// [OBJC] objc-alias-declaration 27 /// [OBJC] objc-protocol-definition 28 /// [OBJC] objc-method-definition 29 /// [OBJC] '@' 'end' 30 Parser::DeclPtrTy Parser::ParseObjCAtDirectives() { 31 SourceLocation AtLoc = ConsumeToken(); // the "@" 32 33 switch (Tok.getObjCKeywordID()) { 34 case tok::objc_class: 35 return ParseObjCAtClassDeclaration(AtLoc); 36 case tok::objc_interface: 37 return ParseObjCAtInterfaceDeclaration(AtLoc); 38 case tok::objc_protocol: 39 return ParseObjCAtProtocolDeclaration(AtLoc); 40 case tok::objc_implementation: 41 return ParseObjCAtImplementationDeclaration(AtLoc); 42 case tok::objc_end: 43 return ParseObjCAtEndDeclaration(AtLoc); 44 case tok::objc_compatibility_alias: 45 return ParseObjCAtAliasDeclaration(AtLoc); 46 case tok::objc_synthesize: 47 return ParseObjCPropertySynthesize(AtLoc); 48 case tok::objc_dynamic: 49 return ParseObjCPropertyDynamic(AtLoc); 50 default: 51 Diag(AtLoc, diag::err_unexpected_at); 52 SkipUntil(tok::semi); 53 return DeclPtrTy(); 54 } 55 } 56 57 /// 58 /// objc-class-declaration: 59 /// '@' 'class' identifier-list ';' 60 /// 61 Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { 62 ConsumeToken(); // the identifier "class" 63 llvm::SmallVector<IdentifierInfo *, 8> ClassNames; 64 65 while (1) { 66 if (Tok.isNot(tok::identifier)) { 67 Diag(Tok, diag::err_expected_ident); 68 SkipUntil(tok::semi); 69 return DeclPtrTy(); 70 } 71 ClassNames.push_back(Tok.getIdentifierInfo()); 72 ConsumeToken(); 73 74 if (Tok.isNot(tok::comma)) 75 break; 76 77 ConsumeToken(); 78 } 79 80 // Consume the ';'. 81 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class")) 82 return DeclPtrTy(); 83 84 return Actions.ActOnForwardClassDeclaration(atLoc, 85 &ClassNames[0], ClassNames.size()); 86 } 87 88 /// 89 /// objc-interface: 90 /// objc-class-interface-attributes[opt] objc-class-interface 91 /// objc-category-interface 92 /// 93 /// objc-class-interface: 94 /// '@' 'interface' identifier objc-superclass[opt] 95 /// objc-protocol-refs[opt] 96 /// objc-class-instance-variables[opt] 97 /// objc-interface-decl-list 98 /// @end 99 /// 100 /// objc-category-interface: 101 /// '@' 'interface' identifier '(' identifier[opt] ')' 102 /// objc-protocol-refs[opt] 103 /// objc-interface-decl-list 104 /// @end 105 /// 106 /// objc-superclass: 107 /// ':' identifier 108 /// 109 /// objc-class-interface-attributes: 110 /// __attribute__((visibility("default"))) 111 /// __attribute__((visibility("hidden"))) 112 /// __attribute__((deprecated)) 113 /// __attribute__((unavailable)) 114 /// __attribute__((objc_exception)) - used by NSException on 64-bit 115 /// 116 Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( 117 SourceLocation atLoc, AttributeList *attrList) { 118 assert(Tok.isObjCAtKeyword(tok::objc_interface) && 119 "ParseObjCAtInterfaceDeclaration(): Expected @interface"); 120 ConsumeToken(); // the "interface" identifier 121 122 if (Tok.isNot(tok::identifier)) { 123 Diag(Tok, diag::err_expected_ident); // missing class or category name. 124 return DeclPtrTy(); 125 } 126 // We have a class or category name - consume it. 127 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 128 SourceLocation nameLoc = ConsumeToken(); 129 130 if (Tok.is(tok::l_paren)) { // we have a category. 131 SourceLocation lparenLoc = ConsumeParen(); 132 SourceLocation categoryLoc, rparenLoc; 133 IdentifierInfo *categoryId = 0; 134 135 // For ObjC2, the category name is optional (not an error). 136 if (Tok.is(tok::identifier)) { 137 categoryId = Tok.getIdentifierInfo(); 138 categoryLoc = ConsumeToken(); 139 } else if (!getLang().ObjC2) { 140 Diag(Tok, diag::err_expected_ident); // missing category name. 141 return DeclPtrTy(); 142 } 143 if (Tok.isNot(tok::r_paren)) { 144 Diag(Tok, diag::err_expected_rparen); 145 SkipUntil(tok::r_paren, false); // don't stop at ';' 146 return DeclPtrTy(); 147 } 148 rparenLoc = ConsumeParen(); 149 150 // Next, we need to check for any protocol references. 151 SourceLocation EndProtoLoc; 152 llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs; 153 if (Tok.is(tok::less) && 154 ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc)) 155 return DeclPtrTy(); 156 157 if (attrList) // categories don't support attributes. 158 Diag(Tok, diag::err_objc_no_attributes_on_category); 159 160 DeclPtrTy CategoryType = 161 Actions.ActOnStartCategoryInterface(atLoc, 162 nameId, nameLoc, 163 categoryId, categoryLoc, 164 ProtocolRefs.data(), 165 ProtocolRefs.size(), 166 EndProtoLoc); 167 168 ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword); 169 return CategoryType; 170 } 171 // Parse a class interface. 172 IdentifierInfo *superClassId = 0; 173 SourceLocation superClassLoc; 174 175 if (Tok.is(tok::colon)) { // a super class is specified. 176 ConsumeToken(); 177 if (Tok.isNot(tok::identifier)) { 178 Diag(Tok, diag::err_expected_ident); // missing super class name. 179 return DeclPtrTy(); 180 } 181 superClassId = Tok.getIdentifierInfo(); 182 superClassLoc = ConsumeToken(); 183 } 184 // Next, we need to check for any protocol references. 185 llvm::SmallVector<Action::DeclPtrTy, 8> ProtocolRefs; 186 SourceLocation EndProtoLoc; 187 if (Tok.is(tok::less) && 188 ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc)) 189 return DeclPtrTy(); 190 191 DeclPtrTy ClsType = 192 Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc, 193 superClassId, superClassLoc, 194 ProtocolRefs.data(), ProtocolRefs.size(), 195 EndProtoLoc, attrList); 196 197 if (Tok.is(tok::l_brace)) 198 ParseObjCClassInstanceVariables(ClsType, atLoc); 199 200 ParseObjCInterfaceDeclList(ClsType, tok::objc_interface); 201 return ClsType; 202 } 203 204 /// objc-interface-decl-list: 205 /// empty 206 /// objc-interface-decl-list objc-property-decl [OBJC2] 207 /// objc-interface-decl-list objc-method-requirement [OBJC2] 208 /// objc-interface-decl-list objc-method-proto ';' 209 /// objc-interface-decl-list declaration 210 /// objc-interface-decl-list ';' 211 /// 212 /// objc-method-requirement: [OBJC2] 213 /// @required 214 /// @optional 215 /// 216 void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, 217 tok::ObjCKeywordKind contextKey) { 218 llvm::SmallVector<DeclPtrTy, 32> allMethods; 219 llvm::SmallVector<DeclPtrTy, 16> allProperties; 220 llvm::SmallVector<DeclGroupPtrTy, 8> allTUVariables; 221 tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword; 222 223 SourceLocation AtEndLoc; 224 225 while (1) { 226 // If this is a method prototype, parse it. 227 if (Tok.is(tok::minus) || Tok.is(tok::plus)) { 228 DeclPtrTy methodPrototype = 229 ParseObjCMethodPrototype(interfaceDecl, MethodImplKind); 230 allMethods.push_back(methodPrototype); 231 // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for 232 // method definitions. 233 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_method_proto, 234 "", tok::semi); 235 continue; 236 } 237 238 // Ignore excess semicolons. 239 if (Tok.is(tok::semi)) { 240 ConsumeToken(); 241 continue; 242 } 243 244 // If we got to the end of the file, exit the loop. 245 if (Tok.is(tok::eof)) 246 break; 247 248 // If we don't have an @ directive, parse it as a function definition. 249 if (Tok.isNot(tok::at)) { 250 // The code below does not consume '}'s because it is afraid of eating the 251 // end of a namespace. Because of the way this code is structured, an 252 // erroneous r_brace would cause an infinite loop if not handled here. 253 if (Tok.is(tok::r_brace)) 254 break; 255 256 // FIXME: as the name implies, this rule allows function definitions. 257 // We could pass a flag or check for functions during semantic analysis. 258 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition()); 259 continue; 260 } 261 262 // Otherwise, we have an @ directive, eat the @. 263 SourceLocation AtLoc = ConsumeToken(); // the "@" 264 tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID(); 265 266 if (DirectiveKind == tok::objc_end) { // @end -> terminate list 267 AtEndLoc = AtLoc; 268 break; 269 } 270 271 // Eat the identifier. 272 ConsumeToken(); 273 274 switch (DirectiveKind) { 275 default: 276 // FIXME: If someone forgets an @end on a protocol, this loop will 277 // continue to eat up tons of stuff and spew lots of nonsense errors. It 278 // would probably be better to bail out if we saw an @class or @interface 279 // or something like that. 280 Diag(AtLoc, diag::err_objc_illegal_interface_qual); 281 // Skip until we see an '@' or '}' or ';'. 282 SkipUntil(tok::r_brace, tok::at); 283 break; 284 285 case tok::objc_required: 286 case tok::objc_optional: 287 // This is only valid on protocols. 288 // FIXME: Should this check for ObjC2 being enabled? 289 if (contextKey != tok::objc_protocol) 290 Diag(AtLoc, diag::err_objc_directive_only_in_protocol); 291 else 292 MethodImplKind = DirectiveKind; 293 break; 294 295 case tok::objc_property: 296 if (!getLang().ObjC2) 297 Diag(AtLoc, diag::err_objc_propertoes_require_objc2); 298 299 ObjCDeclSpec OCDS; 300 // Parse property attribute list, if any. 301 if (Tok.is(tok::l_paren)) 302 ParseObjCPropertyAttribute(OCDS); 303 304 // Parse all the comma separated declarators. 305 DeclSpec DS; 306 llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators; 307 ParseStructDeclaration(DS, FieldDeclarators); 308 309 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "", 310 tok::at); 311 312 // Convert them all to property declarations. 313 for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) { 314 FieldDeclarator &FD = FieldDeclarators[i]; 315 if (FD.D.getIdentifier() == 0) { 316 Diag(AtLoc, diag::err_objc_property_requires_field_name) 317 << FD.D.getSourceRange(); 318 continue; 319 } 320 if (FD.BitfieldSize) { 321 Diag(AtLoc, diag::err_objc_property_bitfield) 322 << FD.D.getSourceRange(); 323 continue; 324 } 325 326 // Install the property declarator into interfaceDecl. 327 IdentifierInfo *SelName = 328 OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier(); 329 330 Selector GetterSel = 331 PP.getSelectorTable().getNullarySelector(SelName); 332 IdentifierInfo *SetterName = OCDS.getSetterName(); 333 Selector SetterSel; 334 if (SetterName) 335 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName); 336 else 337 SetterSel = SelectorTable::constructSetterName(PP.getIdentifierTable(), 338 PP.getSelectorTable(), 339 FD.D.getIdentifier()); 340 bool isOverridingProperty = false; 341 DeclPtrTy Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS, 342 GetterSel, SetterSel, 343 interfaceDecl, 344 &isOverridingProperty, 345 MethodImplKind); 346 if (!isOverridingProperty) 347 allProperties.push_back(Property); 348 } 349 break; 350 } 351 } 352 353 // We break out of the big loop in two cases: when we see @end or when we see 354 // EOF. In the former case, eat the @end. In the later case, emit an error. 355 if (Tok.isObjCAtKeyword(tok::objc_end)) 356 ConsumeToken(); // the "end" identifier 357 else 358 Diag(Tok, diag::err_objc_missing_end); 359 360 // Insert collected methods declarations into the @interface object. 361 // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit. 362 Actions.ActOnAtEnd(AtEndLoc, interfaceDecl, 363 allMethods.data(), allMethods.size(), 364 allProperties.data(), allProperties.size(), 365 allTUVariables.data(), allTUVariables.size()); 366 } 367 368 /// Parse property attribute declarations. 369 /// 370 /// property-attr-decl: '(' property-attrlist ')' 371 /// property-attrlist: 372 /// property-attribute 373 /// property-attrlist ',' property-attribute 374 /// property-attribute: 375 /// getter '=' identifier 376 /// setter '=' identifier ':' 377 /// readonly 378 /// readwrite 379 /// assign 380 /// retain 381 /// copy 382 /// nonatomic 383 /// 384 void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { 385 assert(Tok.getKind() == tok::l_paren); 386 SourceLocation LHSLoc = ConsumeParen(); // consume '(' 387 388 while (1) { 389 const IdentifierInfo *II = Tok.getIdentifierInfo(); 390 391 // If this is not an identifier at all, bail out early. 392 if (II == 0) { 393 MatchRHSPunctuation(tok::r_paren, LHSLoc); 394 return; 395 } 396 397 SourceLocation AttrName = ConsumeToken(); // consume last attribute name 398 399 if (II->isStr("readonly")) 400 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly); 401 else if (II->isStr("assign")) 402 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign); 403 else if (II->isStr("readwrite")) 404 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite); 405 else if (II->isStr("retain")) 406 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain); 407 else if (II->isStr("copy")) 408 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy); 409 else if (II->isStr("nonatomic")) 410 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic); 411 else if (II->isStr("getter") || II->isStr("setter")) { 412 // getter/setter require extra treatment. 413 if (ExpectAndConsume(tok::equal, diag::err_objc_expected_equal, "", 414 tok::r_paren)) 415 return; 416 417 if (Tok.isNot(tok::identifier)) { 418 Diag(Tok, diag::err_expected_ident); 419 SkipUntil(tok::r_paren); 420 return; 421 } 422 423 if (II->getName()[0] == 's') { 424 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter); 425 DS.setSetterName(Tok.getIdentifierInfo()); 426 ConsumeToken(); // consume method name 427 428 if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "", 429 tok::r_paren)) 430 return; 431 } else { 432 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter); 433 DS.setGetterName(Tok.getIdentifierInfo()); 434 ConsumeToken(); // consume method name 435 } 436 } else { 437 Diag(AttrName, diag::err_objc_expected_property_attr) << II; 438 SkipUntil(tok::r_paren); 439 return; 440 } 441 442 if (Tok.isNot(tok::comma)) 443 break; 444 445 ConsumeToken(); 446 } 447 448 MatchRHSPunctuation(tok::r_paren, LHSLoc); 449 } 450 451 /// objc-method-proto: 452 /// objc-instance-method objc-method-decl objc-method-attributes[opt] 453 /// objc-class-method objc-method-decl objc-method-attributes[opt] 454 /// 455 /// objc-instance-method: '-' 456 /// objc-class-method: '+' 457 /// 458 /// objc-method-attributes: [OBJC2] 459 /// __attribute__((deprecated)) 460 /// 461 Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl, 462 tok::ObjCKeywordKind MethodImplKind) { 463 assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-"); 464 465 tok::TokenKind methodType = Tok.getKind(); 466 SourceLocation mLoc = ConsumeToken(); 467 468 DeclPtrTy MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind); 469 // Since this rule is used for both method declarations and definitions, 470 // the caller is (optionally) responsible for consuming the ';'. 471 return MDecl; 472 } 473 474 /// objc-selector: 475 /// identifier 476 /// one of 477 /// enum struct union if else while do for switch case default 478 /// break continue return goto asm sizeof typeof __alignof 479 /// unsigned long const short volatile signed restrict _Complex 480 /// in out inout bycopy byref oneway int char float double void _Bool 481 /// 482 IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) { 483 switch (Tok.getKind()) { 484 default: 485 return 0; 486 case tok::identifier: 487 case tok::kw_asm: 488 case tok::kw_auto: 489 case tok::kw_bool: 490 case tok::kw_break: 491 case tok::kw_case: 492 case tok::kw_catch: 493 case tok::kw_char: 494 case tok::kw_class: 495 case tok::kw_const: 496 case tok::kw_const_cast: 497 case tok::kw_continue: 498 case tok::kw_default: 499 case tok::kw_delete: 500 case tok::kw_do: 501 case tok::kw_double: 502 case tok::kw_dynamic_cast: 503 case tok::kw_else: 504 case tok::kw_enum: 505 case tok::kw_explicit: 506 case tok::kw_export: 507 case tok::kw_extern: 508 case tok::kw_false: 509 case tok::kw_float: 510 case tok::kw_for: 511 case tok::kw_friend: 512 case tok::kw_goto: 513 case tok::kw_if: 514 case tok::kw_inline: 515 case tok::kw_int: 516 case tok::kw_long: 517 case tok::kw_mutable: 518 case tok::kw_namespace: 519 case tok::kw_new: 520 case tok::kw_operator: 521 case tok::kw_private: 522 case tok::kw_protected: 523 case tok::kw_public: 524 case tok::kw_register: 525 case tok::kw_reinterpret_cast: 526 case tok::kw_restrict: 527 case tok::kw_return: 528 case tok::kw_short: 529 case tok::kw_signed: 530 case tok::kw_sizeof: 531 case tok::kw_static: 532 case tok::kw_static_cast: 533 case tok::kw_struct: 534 case tok::kw_switch: 535 case tok::kw_template: 536 case tok::kw_this: 537 case tok::kw_throw: 538 case tok::kw_true: 539 case tok::kw_try: 540 case tok::kw_typedef: 541 case tok::kw_typeid: 542 case tok::kw_typename: 543 case tok::kw_typeof: 544 case tok::kw_union: 545 case tok::kw_unsigned: 546 case tok::kw_using: 547 case tok::kw_virtual: 548 case tok::kw_void: 549 case tok::kw_volatile: 550 case tok::kw_wchar_t: 551 case tok::kw_while: 552 case tok::kw__Bool: 553 case tok::kw__Complex: 554 case tok::kw___alignof: 555 IdentifierInfo *II = Tok.getIdentifierInfo(); 556 SelectorLoc = ConsumeToken(); 557 return II; 558 } 559 } 560 561 /// objc-for-collection-in: 'in' 562 /// 563 bool Parser::isTokIdentifier_in() const { 564 // FIXME: May have to do additional look-ahead to only allow for 565 // valid tokens following an 'in'; such as an identifier, unary operators, 566 // '[' etc. 567 return (getLang().ObjC2 && Tok.is(tok::identifier) && 568 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]); 569 } 570 571 /// ParseObjCTypeQualifierList - This routine parses the objective-c's type 572 /// qualifier list and builds their bitmask representation in the input 573 /// argument. 574 /// 575 /// objc-type-qualifiers: 576 /// objc-type-qualifier 577 /// objc-type-qualifiers objc-type-qualifier 578 /// 579 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) { 580 while (1) { 581 if (Tok.isNot(tok::identifier)) 582 return; 583 584 const IdentifierInfo *II = Tok.getIdentifierInfo(); 585 for (unsigned i = 0; i != objc_NumQuals; ++i) { 586 if (II != ObjCTypeQuals[i]) 587 continue; 588 589 ObjCDeclSpec::ObjCDeclQualifier Qual; 590 switch (i) { 591 default: assert(0 && "Unknown decl qualifier"); 592 case objc_in: Qual = ObjCDeclSpec::DQ_In; break; 593 case objc_out: Qual = ObjCDeclSpec::DQ_Out; break; 594 case objc_inout: Qual = ObjCDeclSpec::DQ_Inout; break; 595 case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break; 596 case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break; 597 case objc_byref: Qual = ObjCDeclSpec::DQ_Byref; break; 598 } 599 DS.setObjCDeclQualifier(Qual); 600 ConsumeToken(); 601 II = 0; 602 break; 603 } 604 605 // If this wasn't a recognized qualifier, bail out. 606 if (II) return; 607 } 608 } 609 610 /// objc-type-name: 611 /// '(' objc-type-qualifiers[opt] type-name ')' 612 /// '(' objc-type-qualifiers[opt] ')' 613 /// 614 Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) { 615 assert(Tok.is(tok::l_paren) && "expected ("); 616 617 SourceLocation LParenLoc = ConsumeParen(); 618 SourceLocation TypeStartLoc = Tok.getLocation(); 619 620 // Parse type qualifiers, in, inout, etc. 621 ParseObjCTypeQualifierList(DS); 622 623 TypeTy *Ty = 0; 624 if (isTypeSpecifierQualifier()) { 625 TypeResult TypeSpec = ParseTypeName(); 626 if (!TypeSpec.isInvalid()) 627 Ty = TypeSpec.get(); 628 } 629 630 if (Tok.is(tok::r_paren)) 631 ConsumeParen(); 632 else if (Tok.getLocation() == TypeStartLoc) { 633 // If we didn't eat any tokens, then this isn't a type. 634 Diag(Tok, diag::err_expected_type); 635 SkipUntil(tok::r_paren); 636 } else { 637 // Otherwise, we found *something*, but didn't get a ')' in the right 638 // place. Emit an error then return what we have as the type. 639 MatchRHSPunctuation(tok::r_paren, LParenLoc); 640 } 641 return Ty; 642 } 643 644 /// objc-method-decl: 645 /// objc-selector 646 /// objc-keyword-selector objc-parmlist[opt] 647 /// objc-type-name objc-selector 648 /// objc-type-name objc-keyword-selector objc-parmlist[opt] 649 /// 650 /// objc-keyword-selector: 651 /// objc-keyword-decl 652 /// objc-keyword-selector objc-keyword-decl 653 /// 654 /// objc-keyword-decl: 655 /// objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier 656 /// objc-selector ':' objc-keyword-attributes[opt] identifier 657 /// ':' objc-type-name objc-keyword-attributes[opt] identifier 658 /// ':' objc-keyword-attributes[opt] identifier 659 /// 660 /// objc-parmlist: 661 /// objc-parms objc-ellipsis[opt] 662 /// 663 /// objc-parms: 664 /// objc-parms , parameter-declaration 665 /// 666 /// objc-ellipsis: 667 /// , ... 668 /// 669 /// objc-keyword-attributes: [OBJC2] 670 /// __attribute__((unused)) 671 /// 672 Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, 673 tok::TokenKind mType, 674 DeclPtrTy IDecl, 675 tok::ObjCKeywordKind MethodImplKind) { 676 // Parse the return type if present. 677 TypeTy *ReturnType = 0; 678 ObjCDeclSpec DSRet; 679 if (Tok.is(tok::l_paren)) 680 ReturnType = ParseObjCTypeName(DSRet); 681 682 SourceLocation selLoc; 683 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc); 684 685 // An unnamed colon is valid. 686 if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name. 687 Diag(Tok, diag::err_expected_selector_for_method) 688 << SourceRange(mLoc, Tok.getLocation()); 689 // Skip until we get a ; or {}. 690 SkipUntil(tok::r_brace); 691 return DeclPtrTy(); 692 } 693 694 llvm::SmallVector<Declarator, 8> CargNames; 695 if (Tok.isNot(tok::colon)) { 696 // If attributes exist after the method, parse them. 697 AttributeList *MethodAttrs = 0; 698 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 699 MethodAttrs = ParseAttributes(); 700 701 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); 702 return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), 703 mType, IDecl, DSRet, ReturnType, Sel, 704 0, CargNames, MethodAttrs, 705 MethodImplKind); 706 } 707 708 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 709 llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos; 710 711 while (1) { 712 Action::ObjCArgInfo ArgInfo; 713 714 // Each iteration parses a single keyword argument. 715 if (Tok.isNot(tok::colon)) { 716 Diag(Tok, diag::err_expected_colon); 717 break; 718 } 719 ConsumeToken(); // Eat the ':'. 720 721 ArgInfo.Type = 0; 722 if (Tok.is(tok::l_paren)) // Parse the argument type if present. 723 ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec); 724 725 // If attributes exist before the argument name, parse them. 726 ArgInfo.ArgAttrs = 0; 727 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 728 ArgInfo.ArgAttrs = ParseAttributes(); 729 730 if (Tok.isNot(tok::identifier)) { 731 Diag(Tok, diag::err_expected_ident); // missing argument name. 732 break; 733 } 734 735 ArgInfo.Name = Tok.getIdentifierInfo(); 736 ArgInfo.NameLoc = Tok.getLocation(); 737 ConsumeToken(); // Eat the identifier. 738 739 ArgInfos.push_back(ArgInfo); 740 KeyIdents.push_back(SelIdent); 741 742 // Check for another keyword selector. 743 SourceLocation Loc; 744 SelIdent = ParseObjCSelectorPiece(Loc); 745 if (!SelIdent && Tok.isNot(tok::colon)) 746 break; 747 // We have a selector or a colon, continue parsing. 748 } 749 750 bool isVariadic = false; 751 752 // Parse the (optional) parameter list. 753 while (Tok.is(tok::comma)) { 754 ConsumeToken(); 755 if (Tok.is(tok::ellipsis)) { 756 isVariadic = true; 757 ConsumeToken(); 758 break; 759 } 760 DeclSpec DS; 761 ParseDeclarationSpecifiers(DS); 762 // Parse the declarator. 763 Declarator ParmDecl(DS, Declarator::PrototypeContext); 764 ParseDeclarator(ParmDecl); 765 CargNames.push_back(ParmDecl); 766 } 767 768 // FIXME: Add support for optional parmameter list... 769 // If attributes exist after the method, parse them. 770 AttributeList *MethodAttrs = 0; 771 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 772 MethodAttrs = ParseAttributes(); 773 774 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), 775 &KeyIdents[0]); 776 return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), 777 mType, IDecl, DSRet, ReturnType, Sel, 778 &ArgInfos[0], CargNames, MethodAttrs, 779 MethodImplKind, isVariadic); 780 } 781 782 /// objc-protocol-refs: 783 /// '<' identifier-list '>' 784 /// 785 bool Parser:: 786 ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols, 787 bool WarnOnDeclarations, SourceLocation &EndLoc) { 788 assert(Tok.is(tok::less) && "expected <"); 789 790 ConsumeToken(); // the "<" 791 792 llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents; 793 794 while (1) { 795 if (Tok.isNot(tok::identifier)) { 796 Diag(Tok, diag::err_expected_ident); 797 SkipUntil(tok::greater); 798 return true; 799 } 800 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(), 801 Tok.getLocation())); 802 ConsumeToken(); 803 804 if (Tok.isNot(tok::comma)) 805 break; 806 ConsumeToken(); 807 } 808 809 // Consume the '>'. 810 if (Tok.isNot(tok::greater)) { 811 Diag(Tok, diag::err_expected_greater); 812 return true; 813 } 814 815 EndLoc = ConsumeAnyToken(); 816 817 // Convert the list of protocols identifiers into a list of protocol decls. 818 Actions.FindProtocolDeclaration(WarnOnDeclarations, 819 &ProtocolIdents[0], ProtocolIdents.size(), 820 Protocols); 821 return false; 822 } 823 824 /// objc-class-instance-variables: 825 /// '{' objc-instance-variable-decl-list[opt] '}' 826 /// 827 /// objc-instance-variable-decl-list: 828 /// objc-visibility-spec 829 /// objc-instance-variable-decl ';' 830 /// ';' 831 /// objc-instance-variable-decl-list objc-visibility-spec 832 /// objc-instance-variable-decl-list objc-instance-variable-decl ';' 833 /// objc-instance-variable-decl-list ';' 834 /// 835 /// objc-visibility-spec: 836 /// @private 837 /// @protected 838 /// @public 839 /// @package [OBJC2] 840 /// 841 /// objc-instance-variable-decl: 842 /// struct-declaration 843 /// 844 void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, 845 SourceLocation atLoc) { 846 assert(Tok.is(tok::l_brace) && "expected {"); 847 llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls; 848 llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators; 849 850 ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope); 851 852 SourceLocation LBraceLoc = ConsumeBrace(); // the "{" 853 854 tok::ObjCKeywordKind visibility = tok::objc_protected; 855 // While we still have something to read, read the instance variables. 856 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 857 // Each iteration of this loop reads one objc-instance-variable-decl. 858 859 // Check for extraneous top-level semicolon. 860 if (Tok.is(tok::semi)) { 861 Diag(Tok, diag::ext_extra_struct_semi); 862 ConsumeToken(); 863 continue; 864 } 865 866 // Set the default visibility to private. 867 if (Tok.is(tok::at)) { // parse objc-visibility-spec 868 ConsumeToken(); // eat the @ sign 869 switch (Tok.getObjCKeywordID()) { 870 case tok::objc_private: 871 case tok::objc_public: 872 case tok::objc_protected: 873 case tok::objc_package: 874 visibility = Tok.getObjCKeywordID(); 875 ConsumeToken(); 876 continue; 877 default: 878 Diag(Tok, diag::err_objc_illegal_visibility_spec); 879 continue; 880 } 881 } 882 883 // Parse all the comma separated declarators. 884 DeclSpec DS; 885 FieldDeclarators.clear(); 886 ParseStructDeclaration(DS, FieldDeclarators); 887 888 // Convert them all to fields. 889 for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) { 890 FieldDeclarator &FD = FieldDeclarators[i]; 891 // Install the declarator into interfaceDecl. 892 DeclPtrTy Field = Actions.ActOnIvar(CurScope, 893 DS.getSourceRange().getBegin(), 894 interfaceDecl, 895 FD.D, FD.BitfieldSize, visibility); 896 AllIvarDecls.push_back(Field); 897 } 898 899 if (Tok.is(tok::semi)) { 900 ConsumeToken(); 901 } else { 902 Diag(Tok, diag::err_expected_semi_decl_list); 903 // Skip to end of block or statement 904 SkipUntil(tok::r_brace, true, true); 905 } 906 } 907 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); 908 // Call ActOnFields() even if we don't have any decls. This is useful 909 // for code rewriting tools that need to be aware of the empty list. 910 Actions.ActOnFields(CurScope, atLoc, interfaceDecl, 911 AllIvarDecls.data(), AllIvarDecls.size(), 912 LBraceLoc, RBraceLoc, 0); 913 return; 914 } 915 916 /// objc-protocol-declaration: 917 /// objc-protocol-definition 918 /// objc-protocol-forward-reference 919 /// 920 /// objc-protocol-definition: 921 /// @protocol identifier 922 /// objc-protocol-refs[opt] 923 /// objc-interface-decl-list 924 /// @end 925 /// 926 /// objc-protocol-forward-reference: 927 /// @protocol identifier-list ';' 928 /// 929 /// "@protocol identifier ;" should be resolved as "@protocol 930 /// identifier-list ;": objc-interface-decl-list may not start with a 931 /// semicolon in the first alternative if objc-protocol-refs are omitted. 932 Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, 933 AttributeList *attrList) { 934 assert(Tok.isObjCAtKeyword(tok::objc_protocol) && 935 "ParseObjCAtProtocolDeclaration(): Expected @protocol"); 936 ConsumeToken(); // the "protocol" identifier 937 938 if (Tok.isNot(tok::identifier)) { 939 Diag(Tok, diag::err_expected_ident); // missing protocol name. 940 return DeclPtrTy(); 941 } 942 // Save the protocol name, then consume it. 943 IdentifierInfo *protocolName = Tok.getIdentifierInfo(); 944 SourceLocation nameLoc = ConsumeToken(); 945 946 if (Tok.is(tok::semi)) { // forward declaration of one protocol. 947 IdentifierLocPair ProtoInfo(protocolName, nameLoc); 948 ConsumeToken(); 949 return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1, 950 attrList); 951 } 952 953 if (Tok.is(tok::comma)) { // list of forward declarations. 954 llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs; 955 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc)); 956 957 // Parse the list of forward declarations. 958 while (1) { 959 ConsumeToken(); // the ',' 960 if (Tok.isNot(tok::identifier)) { 961 Diag(Tok, diag::err_expected_ident); 962 SkipUntil(tok::semi); 963 return DeclPtrTy(); 964 } 965 ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(), 966 Tok.getLocation())); 967 ConsumeToken(); // the identifier 968 969 if (Tok.isNot(tok::comma)) 970 break; 971 } 972 // Consume the ';'. 973 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol")) 974 return DeclPtrTy(); 975 976 return Actions.ActOnForwardProtocolDeclaration(AtLoc, 977 &ProtocolRefs[0], 978 ProtocolRefs.size(), 979 attrList); 980 } 981 982 // Last, and definitely not least, parse a protocol declaration. 983 SourceLocation EndProtoLoc; 984 985 llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs; 986 if (Tok.is(tok::less) && 987 ParseObjCProtocolReferences(ProtocolRefs, false, EndProtoLoc)) 988 return DeclPtrTy(); 989 990 DeclPtrTy ProtoType = 991 Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, 992 ProtocolRefs.data(), 993 ProtocolRefs.size(), 994 EndProtoLoc, attrList); 995 ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol); 996 return ProtoType; 997 } 998 999 /// objc-implementation: 1000 /// objc-class-implementation-prologue 1001 /// objc-category-implementation-prologue 1002 /// 1003 /// objc-class-implementation-prologue: 1004 /// @implementation identifier objc-superclass[opt] 1005 /// objc-class-instance-variables[opt] 1006 /// 1007 /// objc-category-implementation-prologue: 1008 /// @implementation identifier ( identifier ) 1009 Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( 1010 SourceLocation atLoc) { 1011 assert(Tok.isObjCAtKeyword(tok::objc_implementation) && 1012 "ParseObjCAtImplementationDeclaration(): Expected @implementation"); 1013 ConsumeToken(); // the "implementation" identifier 1014 1015 if (Tok.isNot(tok::identifier)) { 1016 Diag(Tok, diag::err_expected_ident); // missing class or category name. 1017 return DeclPtrTy(); 1018 } 1019 // We have a class or category name - consume it. 1020 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 1021 SourceLocation nameLoc = ConsumeToken(); // consume class or category name 1022 1023 if (Tok.is(tok::l_paren)) { 1024 // we have a category implementation. 1025 SourceLocation lparenLoc = ConsumeParen(); 1026 SourceLocation categoryLoc, rparenLoc; 1027 IdentifierInfo *categoryId = 0; 1028 1029 if (Tok.is(tok::identifier)) { 1030 categoryId = Tok.getIdentifierInfo(); 1031 categoryLoc = ConsumeToken(); 1032 } else { 1033 Diag(Tok, diag::err_expected_ident); // missing category name. 1034 return DeclPtrTy(); 1035 } 1036 if (Tok.isNot(tok::r_paren)) { 1037 Diag(Tok, diag::err_expected_rparen); 1038 SkipUntil(tok::r_paren, false); // don't stop at ';' 1039 return DeclPtrTy(); 1040 } 1041 rparenLoc = ConsumeParen(); 1042 DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation( 1043 atLoc, nameId, nameLoc, categoryId, 1044 categoryLoc); 1045 ObjCImpDecl = ImplCatType; 1046 return DeclPtrTy(); 1047 } 1048 // We have a class implementation 1049 SourceLocation superClassLoc; 1050 IdentifierInfo *superClassId = 0; 1051 if (Tok.is(tok::colon)) { 1052 // We have a super class 1053 ConsumeToken(); 1054 if (Tok.isNot(tok::identifier)) { 1055 Diag(Tok, diag::err_expected_ident); // missing super class name. 1056 return DeclPtrTy(); 1057 } 1058 superClassId = Tok.getIdentifierInfo(); 1059 superClassLoc = ConsumeToken(); // Consume super class name 1060 } 1061 DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation( 1062 atLoc, nameId, nameLoc, 1063 superClassId, superClassLoc); 1064 1065 if (Tok.is(tok::l_brace)) // we have ivars 1066 ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc); 1067 ObjCImpDecl = ImplClsType; 1068 1069 return DeclPtrTy(); 1070 } 1071 1072 Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) { 1073 assert(Tok.isObjCAtKeyword(tok::objc_end) && 1074 "ParseObjCAtEndDeclaration(): Expected @end"); 1075 DeclPtrTy Result = ObjCImpDecl; 1076 ConsumeToken(); // the "end" identifier 1077 if (ObjCImpDecl) { 1078 Actions.ActOnAtEnd(atLoc, ObjCImpDecl); 1079 ObjCImpDecl = DeclPtrTy(); 1080 } 1081 else 1082 Diag(atLoc, diag::warn_expected_implementation); // missing @implementation 1083 return Result; 1084 } 1085 1086 /// compatibility-alias-decl: 1087 /// @compatibility_alias alias-name class-name ';' 1088 /// 1089 Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { 1090 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) && 1091 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias"); 1092 ConsumeToken(); // consume compatibility_alias 1093 if (Tok.isNot(tok::identifier)) { 1094 Diag(Tok, diag::err_expected_ident); 1095 return DeclPtrTy(); 1096 } 1097 IdentifierInfo *aliasId = Tok.getIdentifierInfo(); 1098 SourceLocation aliasLoc = ConsumeToken(); // consume alias-name 1099 if (Tok.isNot(tok::identifier)) { 1100 Diag(Tok, diag::err_expected_ident); 1101 return DeclPtrTy(); 1102 } 1103 IdentifierInfo *classId = Tok.getIdentifierInfo(); 1104 SourceLocation classLoc = ConsumeToken(); // consume class-name; 1105 if (Tok.isNot(tok::semi)) { 1106 Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias"; 1107 return DeclPtrTy(); 1108 } 1109 return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc, 1110 classId, classLoc); 1111 } 1112 1113 /// property-synthesis: 1114 /// @synthesize property-ivar-list ';' 1115 /// 1116 /// property-ivar-list: 1117 /// property-ivar 1118 /// property-ivar-list ',' property-ivar 1119 /// 1120 /// property-ivar: 1121 /// identifier 1122 /// identifier '=' identifier 1123 /// 1124 Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { 1125 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) && 1126 "ParseObjCPropertyDynamic(): Expected '@synthesize'"); 1127 SourceLocation loc = ConsumeToken(); // consume synthesize 1128 if (Tok.isNot(tok::identifier)) { 1129 Diag(Tok, diag::err_expected_ident); 1130 return DeclPtrTy(); 1131 } 1132 1133 while (Tok.is(tok::identifier)) { 1134 IdentifierInfo *propertyIvar = 0; 1135 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1136 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1137 if (Tok.is(tok::equal)) { 1138 // property '=' ivar-name 1139 ConsumeToken(); // consume '=' 1140 if (Tok.isNot(tok::identifier)) { 1141 Diag(Tok, diag::err_expected_ident); 1142 break; 1143 } 1144 propertyIvar = Tok.getIdentifierInfo(); 1145 ConsumeToken(); // consume ivar-name 1146 } 1147 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl, 1148 propertyId, propertyIvar); 1149 if (Tok.isNot(tok::comma)) 1150 break; 1151 ConsumeToken(); // consume ',' 1152 } 1153 if (Tok.isNot(tok::semi)) 1154 Diag(Tok, diag::err_expected_semi_after) << "@synthesize"; 1155 return DeclPtrTy(); 1156 } 1157 1158 /// property-dynamic: 1159 /// @dynamic property-list 1160 /// 1161 /// property-list: 1162 /// identifier 1163 /// property-list ',' identifier 1164 /// 1165 Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { 1166 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) && 1167 "ParseObjCPropertyDynamic(): Expected '@dynamic'"); 1168 SourceLocation loc = ConsumeToken(); // consume dynamic 1169 if (Tok.isNot(tok::identifier)) { 1170 Diag(Tok, diag::err_expected_ident); 1171 return DeclPtrTy(); 1172 } 1173 while (Tok.is(tok::identifier)) { 1174 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1175 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1176 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl, 1177 propertyId, 0); 1178 1179 if (Tok.isNot(tok::comma)) 1180 break; 1181 ConsumeToken(); // consume ',' 1182 } 1183 if (Tok.isNot(tok::semi)) 1184 Diag(Tok, diag::err_expected_semi_after) << "@dynamic"; 1185 return DeclPtrTy(); 1186 } 1187 1188 /// objc-throw-statement: 1189 /// throw expression[opt]; 1190 /// 1191 Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { 1192 OwningExprResult Res(Actions); 1193 ConsumeToken(); // consume throw 1194 if (Tok.isNot(tok::semi)) { 1195 Res = ParseExpression(); 1196 if (Res.isInvalid()) { 1197 SkipUntil(tok::semi); 1198 return StmtError(); 1199 } 1200 } 1201 ConsumeToken(); // consume ';' 1202 return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope); 1203 } 1204 1205 /// objc-synchronized-statement: 1206 /// @synchronized '(' expression ')' compound-statement 1207 /// 1208 Parser::OwningStmtResult 1209 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { 1210 ConsumeToken(); // consume synchronized 1211 if (Tok.isNot(tok::l_paren)) { 1212 Diag(Tok, diag::err_expected_lparen_after) << "@synchronized"; 1213 return StmtError(); 1214 } 1215 ConsumeParen(); // '(' 1216 OwningExprResult Res(ParseExpression()); 1217 if (Res.isInvalid()) { 1218 SkipUntil(tok::semi); 1219 return StmtError(); 1220 } 1221 if (Tok.isNot(tok::r_paren)) { 1222 Diag(Tok, diag::err_expected_lbrace); 1223 return StmtError(); 1224 } 1225 ConsumeParen(); // ')' 1226 if (Tok.isNot(tok::l_brace)) { 1227 Diag(Tok, diag::err_expected_lbrace); 1228 return StmtError(); 1229 } 1230 // Enter a scope to hold everything within the compound stmt. Compound 1231 // statements can always hold declarations. 1232 ParseScope BodyScope(this, Scope::DeclScope); 1233 1234 OwningStmtResult SynchBody(ParseCompoundStatementBody()); 1235 1236 BodyScope.Exit(); 1237 if (SynchBody.isInvalid()) 1238 SynchBody = Actions.ActOnNullStmt(Tok.getLocation()); 1239 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody)); 1240 } 1241 1242 /// objc-try-catch-statement: 1243 /// @try compound-statement objc-catch-list[opt] 1244 /// @try compound-statement objc-catch-list[opt] @finally compound-statement 1245 /// 1246 /// objc-catch-list: 1247 /// @catch ( parameter-declaration ) compound-statement 1248 /// objc-catch-list @catch ( catch-parameter-declaration ) compound-statement 1249 /// catch-parameter-declaration: 1250 /// parameter-declaration 1251 /// '...' [OBJC2] 1252 /// 1253 Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { 1254 bool catch_or_finally_seen = false; 1255 1256 ConsumeToken(); // consume try 1257 if (Tok.isNot(tok::l_brace)) { 1258 Diag(Tok, diag::err_expected_lbrace); 1259 return StmtError(); 1260 } 1261 OwningStmtResult CatchStmts(Actions); 1262 OwningStmtResult FinallyStmt(Actions); 1263 ParseScope TryScope(this, Scope::DeclScope); 1264 OwningStmtResult TryBody(ParseCompoundStatementBody()); 1265 TryScope.Exit(); 1266 if (TryBody.isInvalid()) 1267 TryBody = Actions.ActOnNullStmt(Tok.getLocation()); 1268 1269 while (Tok.is(tok::at)) { 1270 // At this point, we need to lookahead to determine if this @ is the start 1271 // of an @catch or @finally. We don't want to consume the @ token if this 1272 // is an @try or @encode or something else. 1273 Token AfterAt = GetLookAheadToken(1); 1274 if (!AfterAt.isObjCAtKeyword(tok::objc_catch) && 1275 !AfterAt.isObjCAtKeyword(tok::objc_finally)) 1276 break; 1277 1278 SourceLocation AtCatchFinallyLoc = ConsumeToken(); 1279 if (Tok.isObjCAtKeyword(tok::objc_catch)) { 1280 DeclPtrTy FirstPart; 1281 ConsumeToken(); // consume catch 1282 if (Tok.is(tok::l_paren)) { 1283 ConsumeParen(); 1284 ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope); 1285 if (Tok.isNot(tok::ellipsis)) { 1286 DeclSpec DS; 1287 ParseDeclarationSpecifiers(DS); 1288 // For some odd reason, the name of the exception variable is 1289 // optional. As a result, we need to use "PrototypeContext", because 1290 // we must accept either 'declarator' or 'abstract-declarator' here. 1291 Declarator ParmDecl(DS, Declarator::PrototypeContext); 1292 ParseDeclarator(ParmDecl); 1293 1294 // Inform the actions module about the parameter declarator, so it 1295 // gets added to the current scope. 1296 FirstPart = Actions.ActOnParamDeclarator(CurScope, ParmDecl); 1297 } else 1298 ConsumeToken(); // consume '...' 1299 1300 SourceLocation RParenLoc; 1301 1302 if (Tok.is(tok::r_paren)) 1303 RParenLoc = ConsumeParen(); 1304 else // Skip over garbage, until we get to ')'. Eat the ')'. 1305 SkipUntil(tok::r_paren, true, false); 1306 1307 OwningStmtResult CatchBody(Actions, true); 1308 if (Tok.is(tok::l_brace)) 1309 CatchBody = ParseCompoundStatementBody(); 1310 else 1311 Diag(Tok, diag::err_expected_lbrace); 1312 if (CatchBody.isInvalid()) 1313 CatchBody = Actions.ActOnNullStmt(Tok.getLocation()); 1314 CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, 1315 RParenLoc, FirstPart, move(CatchBody), 1316 move(CatchStmts)); 1317 } else { 1318 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after) 1319 << "@catch clause"; 1320 return StmtError(); 1321 } 1322 catch_or_finally_seen = true; 1323 } else { 1324 assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?"); 1325 ConsumeToken(); // consume finally 1326 ParseScope FinallyScope(this, Scope::DeclScope); 1327 1328 OwningStmtResult FinallyBody(Actions, true); 1329 if (Tok.is(tok::l_brace)) 1330 FinallyBody = ParseCompoundStatementBody(); 1331 else 1332 Diag(Tok, diag::err_expected_lbrace); 1333 if (FinallyBody.isInvalid()) 1334 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation()); 1335 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, 1336 move(FinallyBody)); 1337 catch_or_finally_seen = true; 1338 break; 1339 } 1340 } 1341 if (!catch_or_finally_seen) { 1342 Diag(atLoc, diag::err_missing_catch_finally); 1343 return StmtError(); 1344 } 1345 return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), move(CatchStmts), 1346 move(FinallyStmt)); 1347 } 1348 1349 /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' 1350 /// 1351 Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() { 1352 DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl); 1353 1354 PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions, 1355 PP.getSourceManager(), 1356 "parsing Objective-C method"); 1357 1358 // parse optional ';' 1359 if (Tok.is(tok::semi)) 1360 ConsumeToken(); 1361 1362 // We should have an opening brace now. 1363 if (Tok.isNot(tok::l_brace)) { 1364 Diag(Tok, diag::err_expected_method_body); 1365 1366 // Skip over garbage, until we get to '{'. Don't eat the '{'. 1367 SkipUntil(tok::l_brace, true, true); 1368 1369 // If we didn't find the '{', bail out. 1370 if (Tok.isNot(tok::l_brace)) 1371 return DeclPtrTy(); 1372 } 1373 SourceLocation BraceLoc = Tok.getLocation(); 1374 1375 // Enter a scope for the method body. 1376 ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope); 1377 1378 // Tell the actions module that we have entered a method definition with the 1379 // specified Declarator for the method. 1380 Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl); 1381 1382 OwningStmtResult FnBody(ParseCompoundStatementBody()); 1383 1384 // If the function body could not be parsed, make a bogus compoundstmt. 1385 if (FnBody.isInvalid()) 1386 FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 1387 MultiStmtArg(Actions), false); 1388 1389 // TODO: Pass argument information. 1390 Actions.ActOnFinishFunctionBody(MDecl, move(FnBody)); 1391 1392 // Leave the function body scope. 1393 BodyScope.Exit(); 1394 1395 return MDecl; 1396 } 1397 1398 Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { 1399 if (Tok.isObjCAtKeyword(tok::objc_try)) { 1400 return ParseObjCTryStmt(AtLoc); 1401 } else if (Tok.isObjCAtKeyword(tok::objc_throw)) 1402 return ParseObjCThrowStmt(AtLoc); 1403 else if (Tok.isObjCAtKeyword(tok::objc_synchronized)) 1404 return ParseObjCSynchronizedStmt(AtLoc); 1405 OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc)); 1406 if (Res.isInvalid()) { 1407 // If the expression is invalid, skip ahead to the next semicolon. Not 1408 // doing this opens us up to the possibility of infinite loops if 1409 // ParseExpression does not consume any tokens. 1410 SkipUntil(tok::semi); 1411 return StmtError(); 1412 } 1413 // Otherwise, eat the semicolon. 1414 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); 1415 return Actions.ActOnExprStmt(Actions.FullExpr(Res)); 1416 } 1417 1418 Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { 1419 switch (Tok.getKind()) { 1420 case tok::string_literal: // primary-expression: string-literal 1421 case tok::wide_string_literal: 1422 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc)); 1423 default: 1424 if (Tok.getIdentifierInfo() == 0) 1425 return ExprError(Diag(AtLoc, diag::err_unexpected_at)); 1426 1427 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) { 1428 case tok::objc_encode: 1429 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc)); 1430 case tok::objc_protocol: 1431 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc)); 1432 case tok::objc_selector: 1433 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc)); 1434 default: 1435 return ExprError(Diag(AtLoc, diag::err_unexpected_at)); 1436 } 1437 } 1438 } 1439 1440 /// objc-message-expr: 1441 /// '[' objc-receiver objc-message-args ']' 1442 /// 1443 /// objc-receiver: 1444 /// expression 1445 /// class-name 1446 /// type-name 1447 Parser::OwningExprResult Parser::ParseObjCMessageExpression() { 1448 assert(Tok.is(tok::l_square) && "'[' expected"); 1449 SourceLocation LBracLoc = ConsumeBracket(); // consume '[' 1450 1451 // Parse receiver 1452 if (isTokObjCMessageIdentifierReceiver()) { 1453 IdentifierInfo *ReceiverName = Tok.getIdentifierInfo(); 1454 if (ReceiverName != Ident_super || GetLookAheadToken(1).isNot(tok::period)) { 1455 SourceLocation NameLoc = ConsumeToken(); 1456 return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 1457 ExprArg(Actions)); 1458 } 1459 } 1460 1461 OwningExprResult Res(ParseExpression()); 1462 if (Res.isInvalid()) { 1463 SkipUntil(tok::r_square); 1464 return move(Res); 1465 } 1466 1467 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 1468 0, move(Res)); 1469 } 1470 1471 /// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse 1472 /// the rest of a message expression. 1473 /// 1474 /// objc-message-args: 1475 /// objc-selector 1476 /// objc-keywordarg-list 1477 /// 1478 /// objc-keywordarg-list: 1479 /// objc-keywordarg 1480 /// objc-keywordarg-list objc-keywordarg 1481 /// 1482 /// objc-keywordarg: 1483 /// selector-name[opt] ':' objc-keywordexpr 1484 /// 1485 /// objc-keywordexpr: 1486 /// nonempty-expr-list 1487 /// 1488 /// nonempty-expr-list: 1489 /// assignment-expression 1490 /// nonempty-expr-list , assignment-expression 1491 /// 1492 Parser::OwningExprResult 1493 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, 1494 SourceLocation NameLoc, 1495 IdentifierInfo *ReceiverName, 1496 ExprArg ReceiverExpr) { 1497 // Parse objc-selector 1498 SourceLocation Loc; 1499 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc); 1500 1501 SourceLocation SelectorLoc = Loc; 1502 1503 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 1504 ExprVector KeyExprs(Actions); 1505 1506 if (Tok.is(tok::colon)) { 1507 while (1) { 1508 // Each iteration parses a single keyword argument. 1509 KeyIdents.push_back(selIdent); 1510 1511 if (Tok.isNot(tok::colon)) { 1512 Diag(Tok, diag::err_expected_colon); 1513 // We must manually skip to a ']', otherwise the expression skipper will 1514 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1515 // the enclosing expression. 1516 SkipUntil(tok::r_square); 1517 return ExprError(); 1518 } 1519 1520 ConsumeToken(); // Eat the ':'. 1521 /// Parse the expression after ':' 1522 OwningExprResult Res(ParseAssignmentExpression()); 1523 if (Res.isInvalid()) { 1524 // We must manually skip to a ']', otherwise the expression skipper will 1525 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1526 // the enclosing expression. 1527 SkipUntil(tok::r_square); 1528 return move(Res); 1529 } 1530 1531 // We have a valid expression. 1532 KeyExprs.push_back(Res.release()); 1533 1534 // Check for another keyword selector. 1535 selIdent = ParseObjCSelectorPiece(Loc); 1536 if (!selIdent && Tok.isNot(tok::colon)) 1537 break; 1538 // We have a selector or a colon, continue parsing. 1539 } 1540 // Parse the, optional, argument list, comma separated. 1541 while (Tok.is(tok::comma)) { 1542 ConsumeToken(); // Eat the ','. 1543 /// Parse the expression after ',' 1544 OwningExprResult Res(ParseAssignmentExpression()); 1545 if (Res.isInvalid()) { 1546 // We must manually skip to a ']', otherwise the expression skipper will 1547 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1548 // the enclosing expression. 1549 SkipUntil(tok::r_square); 1550 return move(Res); 1551 } 1552 1553 // We have a valid expression. 1554 KeyExprs.push_back(Res.release()); 1555 } 1556 } else if (!selIdent) { 1557 Diag(Tok, diag::err_expected_ident); // missing selector name. 1558 1559 // We must manually skip to a ']', otherwise the expression skipper will 1560 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1561 // the enclosing expression. 1562 SkipUntil(tok::r_square); 1563 return ExprError(); 1564 } 1565 1566 if (Tok.isNot(tok::r_square)) { 1567 Diag(Tok, diag::err_expected_rsquare); 1568 // We must manually skip to a ']', otherwise the expression skipper will 1569 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1570 // the enclosing expression. 1571 SkipUntil(tok::r_square); 1572 return ExprError(); 1573 } 1574 1575 SourceLocation RBracLoc = ConsumeBracket(); // consume ']' 1576 1577 unsigned nKeys = KeyIdents.size(); 1578 if (nKeys == 0) 1579 KeyIdents.push_back(selIdent); 1580 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]); 1581 1582 // We've just parsed a keyword message. 1583 if (ReceiverName) 1584 return Owned(Actions.ActOnClassMessage(CurScope, ReceiverName, Sel, 1585 LBracLoc, NameLoc, SelectorLoc, 1586 RBracLoc, 1587 KeyExprs.take(), KeyExprs.size())); 1588 return Owned(Actions.ActOnInstanceMessage(ReceiverExpr.release(), Sel, 1589 LBracLoc, SelectorLoc, RBracLoc, 1590 KeyExprs.take(), KeyExprs.size())); 1591 } 1592 1593 Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { 1594 OwningExprResult Res(ParseStringLiteralExpression()); 1595 if (Res.isInvalid()) return move(Res); 1596 1597 // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string 1598 // expressions. At this point, we know that the only valid thing that starts 1599 // with '@' is an @"". 1600 llvm::SmallVector<SourceLocation, 4> AtLocs; 1601 ExprVector AtStrings(Actions); 1602 AtLocs.push_back(AtLoc); 1603 AtStrings.push_back(Res.release()); 1604 1605 while (Tok.is(tok::at)) { 1606 AtLocs.push_back(ConsumeToken()); // eat the @. 1607 1608 // Invalid unless there is a string literal. 1609 if (!isTokenStringLiteral()) 1610 return ExprError(Diag(Tok, diag::err_objc_concat_string)); 1611 1612 OwningExprResult Lit(ParseStringLiteralExpression()); 1613 if (Lit.isInvalid()) 1614 return move(Lit); 1615 1616 AtStrings.push_back(Lit.release()); 1617 } 1618 1619 return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(), 1620 AtStrings.size())); 1621 } 1622 1623 /// objc-encode-expression: 1624 /// @encode ( type-name ) 1625 Parser::OwningExprResult 1626 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { 1627 assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!"); 1628 1629 SourceLocation EncLoc = ConsumeToken(); 1630 1631 if (Tok.isNot(tok::l_paren)) 1632 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode"); 1633 1634 SourceLocation LParenLoc = ConsumeParen(); 1635 1636 TypeResult Ty = ParseTypeName(); 1637 1638 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1639 1640 if (Ty.isInvalid()) 1641 return ExprError(); 1642 1643 return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc, 1644 Ty.get(), RParenLoc)); 1645 } 1646 1647 /// objc-protocol-expression 1648 /// @protocol ( protocol-name ) 1649 Parser::OwningExprResult 1650 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { 1651 SourceLocation ProtoLoc = ConsumeToken(); 1652 1653 if (Tok.isNot(tok::l_paren)) 1654 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol"); 1655 1656 SourceLocation LParenLoc = ConsumeParen(); 1657 1658 if (Tok.isNot(tok::identifier)) 1659 return ExprError(Diag(Tok, diag::err_expected_ident)); 1660 1661 IdentifierInfo *protocolId = Tok.getIdentifierInfo(); 1662 ConsumeToken(); 1663 1664 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1665 1666 return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, 1667 LParenLoc, RParenLoc)); 1668 } 1669 1670 /// objc-selector-expression 1671 /// @selector '(' objc-keyword-selector ')' 1672 Parser::OwningExprResult 1673 Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { 1674 SourceLocation SelectorLoc = ConsumeToken(); 1675 1676 if (Tok.isNot(tok::l_paren)) 1677 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector"); 1678 1679 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 1680 SourceLocation LParenLoc = ConsumeParen(); 1681 SourceLocation sLoc; 1682 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc); 1683 if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name. 1684 return ExprError(Diag(Tok, diag::err_expected_ident)); 1685 1686 KeyIdents.push_back(SelIdent); 1687 unsigned nColons = 0; 1688 if (Tok.isNot(tok::r_paren)) { 1689 while (1) { 1690 if (Tok.isNot(tok::colon)) 1691 return ExprError(Diag(Tok, diag::err_expected_colon)); 1692 1693 nColons++; 1694 ConsumeToken(); // Eat the ':'. 1695 if (Tok.is(tok::r_paren)) 1696 break; 1697 // Check for another keyword selector. 1698 SourceLocation Loc; 1699 SelIdent = ParseObjCSelectorPiece(Loc); 1700 KeyIdents.push_back(SelIdent); 1701 if (!SelIdent && Tok.isNot(tok::colon)) 1702 break; 1703 } 1704 } 1705 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1706 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]); 1707 return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, 1708 LParenLoc, RParenLoc)); 1709 } 1710