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