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, diag::err_expected_colon, "", 519 tok::r_paren)) 520 return; 521 } else { 522 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter); 523 DS.setGetterName(Tok.getIdentifierInfo()); 524 ConsumeToken(); // consume method name 525 } 526 } else { 527 Diag(AttrName, diag::err_objc_expected_property_attr) << II; 528 SkipUntil(tok::r_paren); 529 return; 530 } 531 532 if (Tok.isNot(tok::comma)) 533 break; 534 535 ConsumeToken(); 536 } 537 538 MatchRHSPunctuation(tok::r_paren, LHSLoc); 539 } 540 541 /// objc-method-proto: 542 /// objc-instance-method objc-method-decl objc-method-attributes[opt] 543 /// objc-class-method objc-method-decl objc-method-attributes[opt] 544 /// 545 /// objc-instance-method: '-' 546 /// objc-class-method: '+' 547 /// 548 /// objc-method-attributes: [OBJC2] 549 /// __attribute__((deprecated)) 550 /// 551 Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl, 552 tok::ObjCKeywordKind MethodImplKind) { 553 assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-"); 554 555 tok::TokenKind methodType = Tok.getKind(); 556 SourceLocation mLoc = ConsumeToken(); 557 558 DeclPtrTy MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind); 559 // Since this rule is used for both method declarations and definitions, 560 // the caller is (optionally) responsible for consuming the ';'. 561 return MDecl; 562 } 563 564 /// objc-selector: 565 /// identifier 566 /// one of 567 /// enum struct union if else while do for switch case default 568 /// break continue return goto asm sizeof typeof __alignof 569 /// unsigned long const short volatile signed restrict _Complex 570 /// in out inout bycopy byref oneway int char float double void _Bool 571 /// 572 IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) { 573 switch (Tok.getKind()) { 574 default: 575 return 0; 576 case tok::identifier: 577 case tok::kw_asm: 578 case tok::kw_auto: 579 case tok::kw_bool: 580 case tok::kw_break: 581 case tok::kw_case: 582 case tok::kw_catch: 583 case tok::kw_char: 584 case tok::kw_class: 585 case tok::kw_const: 586 case tok::kw_const_cast: 587 case tok::kw_continue: 588 case tok::kw_default: 589 case tok::kw_delete: 590 case tok::kw_do: 591 case tok::kw_double: 592 case tok::kw_dynamic_cast: 593 case tok::kw_else: 594 case tok::kw_enum: 595 case tok::kw_explicit: 596 case tok::kw_export: 597 case tok::kw_extern: 598 case tok::kw_false: 599 case tok::kw_float: 600 case tok::kw_for: 601 case tok::kw_friend: 602 case tok::kw_goto: 603 case tok::kw_if: 604 case tok::kw_inline: 605 case tok::kw_int: 606 case tok::kw_long: 607 case tok::kw_mutable: 608 case tok::kw_namespace: 609 case tok::kw_new: 610 case tok::kw_operator: 611 case tok::kw_private: 612 case tok::kw_protected: 613 case tok::kw_public: 614 case tok::kw_register: 615 case tok::kw_reinterpret_cast: 616 case tok::kw_restrict: 617 case tok::kw_return: 618 case tok::kw_short: 619 case tok::kw_signed: 620 case tok::kw_sizeof: 621 case tok::kw_static: 622 case tok::kw_static_cast: 623 case tok::kw_struct: 624 case tok::kw_switch: 625 case tok::kw_template: 626 case tok::kw_this: 627 case tok::kw_throw: 628 case tok::kw_true: 629 case tok::kw_try: 630 case tok::kw_typedef: 631 case tok::kw_typeid: 632 case tok::kw_typename: 633 case tok::kw_typeof: 634 case tok::kw_union: 635 case tok::kw_unsigned: 636 case tok::kw_using: 637 case tok::kw_virtual: 638 case tok::kw_void: 639 case tok::kw_volatile: 640 case tok::kw_wchar_t: 641 case tok::kw_while: 642 case tok::kw__Bool: 643 case tok::kw__Complex: 644 case tok::kw___alignof: 645 IdentifierInfo *II = Tok.getIdentifierInfo(); 646 SelectorLoc = ConsumeToken(); 647 return II; 648 } 649 } 650 651 /// objc-for-collection-in: 'in' 652 /// 653 bool Parser::isTokIdentifier_in() const { 654 // FIXME: May have to do additional look-ahead to only allow for 655 // valid tokens following an 'in'; such as an identifier, unary operators, 656 // '[' etc. 657 return (getLang().ObjC2 && Tok.is(tok::identifier) && 658 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]); 659 } 660 661 /// ParseObjCTypeQualifierList - This routine parses the objective-c's type 662 /// qualifier list and builds their bitmask representation in the input 663 /// argument. 664 /// 665 /// objc-type-qualifiers: 666 /// objc-type-qualifier 667 /// objc-type-qualifiers objc-type-qualifier 668 /// 669 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) { 670 while (1) { 671 if (Tok.isNot(tok::identifier)) 672 return; 673 674 const IdentifierInfo *II = Tok.getIdentifierInfo(); 675 for (unsigned i = 0; i != objc_NumQuals; ++i) { 676 if (II != ObjCTypeQuals[i]) 677 continue; 678 679 ObjCDeclSpec::ObjCDeclQualifier Qual; 680 switch (i) { 681 default: assert(0 && "Unknown decl qualifier"); 682 case objc_in: Qual = ObjCDeclSpec::DQ_In; break; 683 case objc_out: Qual = ObjCDeclSpec::DQ_Out; break; 684 case objc_inout: Qual = ObjCDeclSpec::DQ_Inout; break; 685 case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break; 686 case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break; 687 case objc_byref: Qual = ObjCDeclSpec::DQ_Byref; break; 688 } 689 DS.setObjCDeclQualifier(Qual); 690 ConsumeToken(); 691 II = 0; 692 break; 693 } 694 695 // If this wasn't a recognized qualifier, bail out. 696 if (II) return; 697 } 698 } 699 700 /// objc-type-name: 701 /// '(' objc-type-qualifiers[opt] type-name ')' 702 /// '(' objc-type-qualifiers[opt] ')' 703 /// 704 Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) { 705 assert(Tok.is(tok::l_paren) && "expected ("); 706 707 SourceLocation LParenLoc = ConsumeParen(); 708 SourceLocation TypeStartLoc = Tok.getLocation(); 709 710 // Parse type qualifiers, in, inout, etc. 711 ParseObjCTypeQualifierList(DS); 712 713 TypeTy *Ty = 0; 714 if (isTypeSpecifierQualifier()) { 715 TypeResult TypeSpec = ParseTypeName(); 716 if (!TypeSpec.isInvalid()) 717 Ty = TypeSpec.get(); 718 } 719 720 if (Tok.is(tok::r_paren)) 721 ConsumeParen(); 722 else if (Tok.getLocation() == TypeStartLoc) { 723 // If we didn't eat any tokens, then this isn't a type. 724 Diag(Tok, diag::err_expected_type); 725 SkipUntil(tok::r_paren); 726 } else { 727 // Otherwise, we found *something*, but didn't get a ')' in the right 728 // place. Emit an error then return what we have as the type. 729 MatchRHSPunctuation(tok::r_paren, LParenLoc); 730 } 731 return Ty; 732 } 733 734 /// objc-method-decl: 735 /// objc-selector 736 /// objc-keyword-selector objc-parmlist[opt] 737 /// objc-type-name objc-selector 738 /// objc-type-name objc-keyword-selector objc-parmlist[opt] 739 /// 740 /// objc-keyword-selector: 741 /// objc-keyword-decl 742 /// objc-keyword-selector objc-keyword-decl 743 /// 744 /// objc-keyword-decl: 745 /// objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier 746 /// objc-selector ':' objc-keyword-attributes[opt] identifier 747 /// ':' objc-type-name objc-keyword-attributes[opt] identifier 748 /// ':' objc-keyword-attributes[opt] identifier 749 /// 750 /// objc-parmlist: 751 /// objc-parms objc-ellipsis[opt] 752 /// 753 /// objc-parms: 754 /// objc-parms , parameter-declaration 755 /// 756 /// objc-ellipsis: 757 /// , ... 758 /// 759 /// objc-keyword-attributes: [OBJC2] 760 /// __attribute__((unused)) 761 /// 762 Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, 763 tok::TokenKind mType, 764 DeclPtrTy IDecl, 765 tok::ObjCKeywordKind MethodImplKind) { 766 ParsingDeclRAIIObject PD(*this); 767 768 // Parse the return type if present. 769 TypeTy *ReturnType = 0; 770 ObjCDeclSpec DSRet; 771 if (Tok.is(tok::l_paren)) 772 ReturnType = ParseObjCTypeName(DSRet); 773 774 SourceLocation selLoc; 775 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc); 776 777 // An unnamed colon is valid. 778 if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name. 779 Diag(Tok, diag::err_expected_selector_for_method) 780 << SourceRange(mLoc, Tok.getLocation()); 781 // Skip until we get a ; or {}. 782 SkipUntil(tok::r_brace); 783 return DeclPtrTy(); 784 } 785 786 llvm::SmallVector<Declarator, 8> CargNames; 787 if (Tok.isNot(tok::colon)) { 788 // If attributes exist after the method, parse them. 789 AttributeList *MethodAttrs = 0; 790 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 791 MethodAttrs = ParseGNUAttributes(); 792 793 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); 794 DeclPtrTy Result 795 = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), 796 mType, IDecl, DSRet, ReturnType, Sel, 797 0, CargNames, MethodAttrs, 798 MethodImplKind); 799 PD.complete(Result); 800 return Result; 801 } 802 803 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 804 llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos; 805 806 while (1) { 807 Action::ObjCArgInfo ArgInfo; 808 809 // Each iteration parses a single keyword argument. 810 if (Tok.isNot(tok::colon)) { 811 Diag(Tok, diag::err_expected_colon); 812 break; 813 } 814 ConsumeToken(); // Eat the ':'. 815 816 ArgInfo.Type = 0; 817 if (Tok.is(tok::l_paren)) // Parse the argument type if present. 818 ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec); 819 820 // If attributes exist before the argument name, parse them. 821 ArgInfo.ArgAttrs = 0; 822 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 823 ArgInfo.ArgAttrs = ParseGNUAttributes(); 824 825 if (Tok.isNot(tok::identifier)) { 826 Diag(Tok, diag::err_expected_ident); // missing argument name. 827 break; 828 } 829 830 ArgInfo.Name = Tok.getIdentifierInfo(); 831 ArgInfo.NameLoc = Tok.getLocation(); 832 ConsumeToken(); // Eat the identifier. 833 834 ArgInfos.push_back(ArgInfo); 835 KeyIdents.push_back(SelIdent); 836 837 // Check for another keyword selector. 838 SourceLocation Loc; 839 SelIdent = ParseObjCSelectorPiece(Loc); 840 if (!SelIdent && Tok.isNot(tok::colon)) 841 break; 842 // We have a selector or a colon, continue parsing. 843 } 844 845 bool isVariadic = false; 846 847 // Parse the (optional) parameter list. 848 while (Tok.is(tok::comma)) { 849 ConsumeToken(); 850 if (Tok.is(tok::ellipsis)) { 851 isVariadic = true; 852 ConsumeToken(); 853 break; 854 } 855 DeclSpec DS; 856 ParseDeclarationSpecifiers(DS); 857 // Parse the declarator. 858 Declarator ParmDecl(DS, Declarator::PrototypeContext); 859 ParseDeclarator(ParmDecl); 860 CargNames.push_back(ParmDecl); 861 } 862 863 // FIXME: Add support for optional parmameter list... 864 // If attributes exist after the method, parse them. 865 AttributeList *MethodAttrs = 0; 866 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 867 MethodAttrs = ParseGNUAttributes(); 868 869 if (KeyIdents.size() == 0) 870 return DeclPtrTy(); 871 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), 872 &KeyIdents[0]); 873 DeclPtrTy Result 874 = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), 875 mType, IDecl, DSRet, ReturnType, Sel, 876 &ArgInfos[0], CargNames, MethodAttrs, 877 MethodImplKind, isVariadic); 878 PD.complete(Result); 879 return Result; 880 } 881 882 /// objc-protocol-refs: 883 /// '<' identifier-list '>' 884 /// 885 bool Parser:: 886 ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols, 887 llvm::SmallVectorImpl<SourceLocation> &ProtocolLocs, 888 bool WarnOnDeclarations, 889 SourceLocation &LAngleLoc, SourceLocation &EndLoc) { 890 assert(Tok.is(tok::less) && "expected <"); 891 892 LAngleLoc = ConsumeToken(); // the "<" 893 894 llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents; 895 896 while (1) { 897 if (Tok.is(tok::code_completion)) { 898 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(), 899 ProtocolIdents.size()); 900 ConsumeToken(); 901 } 902 903 if (Tok.isNot(tok::identifier)) { 904 Diag(Tok, diag::err_expected_ident); 905 SkipUntil(tok::greater); 906 return true; 907 } 908 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(), 909 Tok.getLocation())); 910 ProtocolLocs.push_back(Tok.getLocation()); 911 ConsumeToken(); 912 913 if (Tok.isNot(tok::comma)) 914 break; 915 ConsumeToken(); 916 } 917 918 // Consume the '>'. 919 if (Tok.isNot(tok::greater)) { 920 Diag(Tok, diag::err_expected_greater); 921 return true; 922 } 923 924 EndLoc = ConsumeAnyToken(); 925 926 // Convert the list of protocols identifiers into a list of protocol decls. 927 Actions.FindProtocolDeclaration(WarnOnDeclarations, 928 &ProtocolIdents[0], ProtocolIdents.size(), 929 Protocols); 930 return false; 931 } 932 933 /// objc-class-instance-variables: 934 /// '{' objc-instance-variable-decl-list[opt] '}' 935 /// 936 /// objc-instance-variable-decl-list: 937 /// objc-visibility-spec 938 /// objc-instance-variable-decl ';' 939 /// ';' 940 /// objc-instance-variable-decl-list objc-visibility-spec 941 /// objc-instance-variable-decl-list objc-instance-variable-decl ';' 942 /// objc-instance-variable-decl-list ';' 943 /// 944 /// objc-visibility-spec: 945 /// @private 946 /// @protected 947 /// @public 948 /// @package [OBJC2] 949 /// 950 /// objc-instance-variable-decl: 951 /// struct-declaration 952 /// 953 void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, 954 SourceLocation atLoc) { 955 assert(Tok.is(tok::l_brace) && "expected {"); 956 llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls; 957 958 ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope); 959 960 SourceLocation LBraceLoc = ConsumeBrace(); // the "{" 961 962 tok::ObjCKeywordKind visibility = tok::objc_protected; 963 // While we still have something to read, read the instance variables. 964 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 965 // Each iteration of this loop reads one objc-instance-variable-decl. 966 967 // Check for extraneous top-level semicolon. 968 if (Tok.is(tok::semi)) { 969 Diag(Tok, diag::ext_extra_struct_semi) 970 << CodeModificationHint::CreateRemoval(Tok.getLocation()); 971 ConsumeToken(); 972 continue; 973 } 974 975 // Set the default visibility to private. 976 if (Tok.is(tok::at)) { // parse objc-visibility-spec 977 ConsumeToken(); // eat the @ sign 978 979 if (Tok.is(tok::code_completion)) { 980 Actions.CodeCompleteObjCAtVisibility(CurScope); 981 ConsumeToken(); 982 } 983 984 switch (Tok.getObjCKeywordID()) { 985 case tok::objc_private: 986 case tok::objc_public: 987 case tok::objc_protected: 988 case tok::objc_package: 989 visibility = Tok.getObjCKeywordID(); 990 ConsumeToken(); 991 continue; 992 default: 993 Diag(Tok, diag::err_objc_illegal_visibility_spec); 994 continue; 995 } 996 } 997 998 if (Tok.is(tok::code_completion)) { 999 Actions.CodeCompleteOrdinaryName(CurScope, 1000 Action::CCC_ObjCInstanceVariableList); 1001 ConsumeToken(); 1002 } 1003 1004 struct ObjCIvarCallback : FieldCallback { 1005 Parser &P; 1006 DeclPtrTy IDecl; 1007 tok::ObjCKeywordKind visibility; 1008 llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls; 1009 1010 ObjCIvarCallback(Parser &P, DeclPtrTy IDecl, tok::ObjCKeywordKind V, 1011 llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls) : 1012 P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) { 1013 } 1014 1015 DeclPtrTy invoke(FieldDeclarator &FD) { 1016 // Install the declarator into the interface decl. 1017 DeclPtrTy Field 1018 = P.Actions.ActOnIvar(P.CurScope, 1019 FD.D.getDeclSpec().getSourceRange().getBegin(), 1020 IDecl, FD.D, FD.BitfieldSize, visibility); 1021 AllIvarDecls.push_back(Field); 1022 return Field; 1023 } 1024 } Callback(*this, interfaceDecl, visibility, AllIvarDecls); 1025 1026 // Parse all the comma separated declarators. 1027 DeclSpec DS; 1028 ParseStructDeclaration(DS, Callback); 1029 1030 if (Tok.is(tok::semi)) { 1031 ConsumeToken(); 1032 } else { 1033 Diag(Tok, diag::err_expected_semi_decl_list); 1034 // Skip to end of block or statement 1035 SkipUntil(tok::r_brace, true, true); 1036 } 1037 } 1038 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); 1039 // Call ActOnFields() even if we don't have any decls. This is useful 1040 // for code rewriting tools that need to be aware of the empty list. 1041 Actions.ActOnFields(CurScope, atLoc, interfaceDecl, 1042 AllIvarDecls.data(), AllIvarDecls.size(), 1043 LBraceLoc, RBraceLoc, 0); 1044 return; 1045 } 1046 1047 /// objc-protocol-declaration: 1048 /// objc-protocol-definition 1049 /// objc-protocol-forward-reference 1050 /// 1051 /// objc-protocol-definition: 1052 /// @protocol identifier 1053 /// objc-protocol-refs[opt] 1054 /// objc-interface-decl-list 1055 /// @end 1056 /// 1057 /// objc-protocol-forward-reference: 1058 /// @protocol identifier-list ';' 1059 /// 1060 /// "@protocol identifier ;" should be resolved as "@protocol 1061 /// identifier-list ;": objc-interface-decl-list may not start with a 1062 /// semicolon in the first alternative if objc-protocol-refs are omitted. 1063 Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, 1064 AttributeList *attrList) { 1065 assert(Tok.isObjCAtKeyword(tok::objc_protocol) && 1066 "ParseObjCAtProtocolDeclaration(): Expected @protocol"); 1067 ConsumeToken(); // the "protocol" identifier 1068 1069 if (Tok.is(tok::code_completion)) { 1070 Actions.CodeCompleteObjCProtocolDecl(CurScope); 1071 ConsumeToken(); 1072 } 1073 1074 if (Tok.isNot(tok::identifier)) { 1075 Diag(Tok, diag::err_expected_ident); // missing protocol name. 1076 return DeclPtrTy(); 1077 } 1078 // Save the protocol name, then consume it. 1079 IdentifierInfo *protocolName = Tok.getIdentifierInfo(); 1080 SourceLocation nameLoc = ConsumeToken(); 1081 1082 if (Tok.is(tok::semi)) { // forward declaration of one protocol. 1083 IdentifierLocPair ProtoInfo(protocolName, nameLoc); 1084 ConsumeToken(); 1085 return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1, 1086 attrList); 1087 } 1088 1089 if (Tok.is(tok::comma)) { // list of forward declarations. 1090 llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs; 1091 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc)); 1092 1093 // Parse the list of forward declarations. 1094 while (1) { 1095 ConsumeToken(); // the ',' 1096 if (Tok.isNot(tok::identifier)) { 1097 Diag(Tok, diag::err_expected_ident); 1098 SkipUntil(tok::semi); 1099 return DeclPtrTy(); 1100 } 1101 ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(), 1102 Tok.getLocation())); 1103 ConsumeToken(); // the identifier 1104 1105 if (Tok.isNot(tok::comma)) 1106 break; 1107 } 1108 // Consume the ';'. 1109 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol")) 1110 return DeclPtrTy(); 1111 1112 return Actions.ActOnForwardProtocolDeclaration(AtLoc, 1113 &ProtocolRefs[0], 1114 ProtocolRefs.size(), 1115 attrList); 1116 } 1117 1118 // Last, and definitely not least, parse a protocol declaration. 1119 SourceLocation LAngleLoc, EndProtoLoc; 1120 1121 llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs; 1122 llvm::SmallVector<SourceLocation, 8> ProtocolLocs; 1123 if (Tok.is(tok::less) && 1124 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, 1125 LAngleLoc, EndProtoLoc)) 1126 return DeclPtrTy(); 1127 1128 DeclPtrTy ProtoType = 1129 Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, 1130 ProtocolRefs.data(), 1131 ProtocolRefs.size(), 1132 ProtocolLocs.data(), 1133 EndProtoLoc, attrList); 1134 ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol); 1135 return ProtoType; 1136 } 1137 1138 /// objc-implementation: 1139 /// objc-class-implementation-prologue 1140 /// objc-category-implementation-prologue 1141 /// 1142 /// objc-class-implementation-prologue: 1143 /// @implementation identifier objc-superclass[opt] 1144 /// objc-class-instance-variables[opt] 1145 /// 1146 /// objc-category-implementation-prologue: 1147 /// @implementation identifier ( identifier ) 1148 Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( 1149 SourceLocation atLoc) { 1150 assert(Tok.isObjCAtKeyword(tok::objc_implementation) && 1151 "ParseObjCAtImplementationDeclaration(): Expected @implementation"); 1152 ConsumeToken(); // the "implementation" identifier 1153 1154 // Code completion after '@implementation'. 1155 if (Tok.is(tok::code_completion)) { 1156 Actions.CodeCompleteObjCImplementationDecl(CurScope); 1157 ConsumeToken(); 1158 } 1159 1160 if (Tok.isNot(tok::identifier)) { 1161 Diag(Tok, diag::err_expected_ident); // missing class or category name. 1162 return DeclPtrTy(); 1163 } 1164 // We have a class or category name - consume it. 1165 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 1166 SourceLocation nameLoc = ConsumeToken(); // consume class or category name 1167 1168 if (Tok.is(tok::l_paren)) { 1169 // we have a category implementation. 1170 SourceLocation lparenLoc = ConsumeParen(); 1171 SourceLocation categoryLoc, rparenLoc; 1172 IdentifierInfo *categoryId = 0; 1173 1174 if (Tok.is(tok::code_completion)) { 1175 Actions.CodeCompleteObjCImplementationCategory(CurScope, nameId); 1176 ConsumeToken(); 1177 } 1178 1179 if (Tok.is(tok::identifier)) { 1180 categoryId = Tok.getIdentifierInfo(); 1181 categoryLoc = ConsumeToken(); 1182 } else { 1183 Diag(Tok, diag::err_expected_ident); // missing category name. 1184 return DeclPtrTy(); 1185 } 1186 if (Tok.isNot(tok::r_paren)) { 1187 Diag(Tok, diag::err_expected_rparen); 1188 SkipUntil(tok::r_paren, false); // don't stop at ';' 1189 return DeclPtrTy(); 1190 } 1191 rparenLoc = ConsumeParen(); 1192 DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation( 1193 atLoc, nameId, nameLoc, categoryId, 1194 categoryLoc); 1195 ObjCImpDecl = ImplCatType; 1196 PendingObjCImpDecl.push_back(ObjCImpDecl); 1197 return DeclPtrTy(); 1198 } 1199 // We have a class implementation 1200 SourceLocation superClassLoc; 1201 IdentifierInfo *superClassId = 0; 1202 if (Tok.is(tok::colon)) { 1203 // We have a super class 1204 ConsumeToken(); 1205 if (Tok.isNot(tok::identifier)) { 1206 Diag(Tok, diag::err_expected_ident); // missing super class name. 1207 return DeclPtrTy(); 1208 } 1209 superClassId = Tok.getIdentifierInfo(); 1210 superClassLoc = ConsumeToken(); // Consume super class name 1211 } 1212 DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation( 1213 atLoc, nameId, nameLoc, 1214 superClassId, superClassLoc); 1215 1216 if (Tok.is(tok::l_brace)) // we have ivars 1217 ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc); 1218 ObjCImpDecl = ImplClsType; 1219 PendingObjCImpDecl.push_back(ObjCImpDecl); 1220 1221 return DeclPtrTy(); 1222 } 1223 1224 Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) { 1225 assert(Tok.isObjCAtKeyword(tok::objc_end) && 1226 "ParseObjCAtEndDeclaration(): Expected @end"); 1227 DeclPtrTy Result = ObjCImpDecl; 1228 ConsumeToken(); // the "end" identifier 1229 if (ObjCImpDecl) { 1230 Actions.ActOnAtEnd(atEnd, ObjCImpDecl); 1231 ObjCImpDecl = DeclPtrTy(); 1232 PendingObjCImpDecl.pop_back(); 1233 } 1234 else { 1235 // missing @implementation 1236 Diag(atEnd.getBegin(), diag::warn_expected_implementation); 1237 } 1238 return Result; 1239 } 1240 1241 Parser::DeclGroupPtrTy Parser::RetrievePendingObjCImpDecl() { 1242 if (PendingObjCImpDecl.empty()) 1243 return Actions.ConvertDeclToDeclGroup(DeclPtrTy()); 1244 DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val(); 1245 Actions.ActOnAtEnd(SourceRange(), ImpDecl); 1246 return Actions.ConvertDeclToDeclGroup(ImpDecl); 1247 } 1248 1249 /// compatibility-alias-decl: 1250 /// @compatibility_alias alias-name class-name ';' 1251 /// 1252 Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { 1253 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) && 1254 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias"); 1255 ConsumeToken(); // consume compatibility_alias 1256 if (Tok.isNot(tok::identifier)) { 1257 Diag(Tok, diag::err_expected_ident); 1258 return DeclPtrTy(); 1259 } 1260 IdentifierInfo *aliasId = Tok.getIdentifierInfo(); 1261 SourceLocation aliasLoc = ConsumeToken(); // consume alias-name 1262 if (Tok.isNot(tok::identifier)) { 1263 Diag(Tok, diag::err_expected_ident); 1264 return DeclPtrTy(); 1265 } 1266 IdentifierInfo *classId = Tok.getIdentifierInfo(); 1267 SourceLocation classLoc = ConsumeToken(); // consume class-name; 1268 if (Tok.isNot(tok::semi)) { 1269 Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias"; 1270 return DeclPtrTy(); 1271 } 1272 return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc, 1273 classId, classLoc); 1274 } 1275 1276 /// property-synthesis: 1277 /// @synthesize property-ivar-list ';' 1278 /// 1279 /// property-ivar-list: 1280 /// property-ivar 1281 /// property-ivar-list ',' property-ivar 1282 /// 1283 /// property-ivar: 1284 /// identifier 1285 /// identifier '=' identifier 1286 /// 1287 Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { 1288 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) && 1289 "ParseObjCPropertyDynamic(): Expected '@synthesize'"); 1290 SourceLocation loc = ConsumeToken(); // consume synthesize 1291 1292 while (true) { 1293 if (Tok.is(tok::code_completion)) { 1294 Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl); 1295 ConsumeToken(); 1296 } 1297 1298 if (Tok.isNot(tok::identifier)) { 1299 Diag(Tok, diag::err_synthesized_property_name); 1300 SkipUntil(tok::semi); 1301 return DeclPtrTy(); 1302 } 1303 1304 IdentifierInfo *propertyIvar = 0; 1305 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1306 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1307 if (Tok.is(tok::equal)) { 1308 // property '=' ivar-name 1309 ConsumeToken(); // consume '=' 1310 1311 if (Tok.is(tok::code_completion)) { 1312 Actions.CodeCompleteObjCPropertySynthesizeIvar(CurScope, propertyId, 1313 ObjCImpDecl); 1314 ConsumeToken(); 1315 } 1316 1317 if (Tok.isNot(tok::identifier)) { 1318 Diag(Tok, diag::err_expected_ident); 1319 break; 1320 } 1321 propertyIvar = Tok.getIdentifierInfo(); 1322 ConsumeToken(); // consume ivar-name 1323 } 1324 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl, 1325 propertyId, propertyIvar); 1326 if (Tok.isNot(tok::comma)) 1327 break; 1328 ConsumeToken(); // consume ',' 1329 } 1330 if (Tok.isNot(tok::semi)) { 1331 Diag(Tok, diag::err_expected_semi_after) << "@synthesize"; 1332 SkipUntil(tok::semi); 1333 } 1334 else 1335 ConsumeToken(); // consume ';' 1336 return DeclPtrTy(); 1337 } 1338 1339 /// property-dynamic: 1340 /// @dynamic property-list 1341 /// 1342 /// property-list: 1343 /// identifier 1344 /// property-list ',' identifier 1345 /// 1346 Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { 1347 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) && 1348 "ParseObjCPropertyDynamic(): Expected '@dynamic'"); 1349 SourceLocation loc = ConsumeToken(); // consume dynamic 1350 while (true) { 1351 if (Tok.is(tok::code_completion)) { 1352 Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl); 1353 ConsumeToken(); 1354 } 1355 1356 if (Tok.isNot(tok::identifier)) { 1357 Diag(Tok, diag::err_expected_ident); 1358 SkipUntil(tok::semi); 1359 return DeclPtrTy(); 1360 } 1361 1362 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1363 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1364 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl, 1365 propertyId, 0); 1366 1367 if (Tok.isNot(tok::comma)) 1368 break; 1369 ConsumeToken(); // consume ',' 1370 } 1371 if (Tok.isNot(tok::semi)) 1372 Diag(Tok, diag::err_expected_semi_after) << "@dynamic"; 1373 return DeclPtrTy(); 1374 } 1375 1376 /// objc-throw-statement: 1377 /// throw expression[opt]; 1378 /// 1379 Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { 1380 OwningExprResult Res(Actions); 1381 ConsumeToken(); // consume throw 1382 if (Tok.isNot(tok::semi)) { 1383 Res = ParseExpression(); 1384 if (Res.isInvalid()) { 1385 SkipUntil(tok::semi); 1386 return StmtError(); 1387 } 1388 } 1389 ConsumeToken(); // consume ';' 1390 return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope); 1391 } 1392 1393 /// objc-synchronized-statement: 1394 /// @synchronized '(' expression ')' compound-statement 1395 /// 1396 Parser::OwningStmtResult 1397 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { 1398 ConsumeToken(); // consume synchronized 1399 if (Tok.isNot(tok::l_paren)) { 1400 Diag(Tok, diag::err_expected_lparen_after) << "@synchronized"; 1401 return StmtError(); 1402 } 1403 ConsumeParen(); // '(' 1404 OwningExprResult Res(ParseExpression()); 1405 if (Res.isInvalid()) { 1406 SkipUntil(tok::semi); 1407 return StmtError(); 1408 } 1409 if (Tok.isNot(tok::r_paren)) { 1410 Diag(Tok, diag::err_expected_lbrace); 1411 return StmtError(); 1412 } 1413 ConsumeParen(); // ')' 1414 if (Tok.isNot(tok::l_brace)) { 1415 Diag(Tok, diag::err_expected_lbrace); 1416 return StmtError(); 1417 } 1418 // Enter a scope to hold everything within the compound stmt. Compound 1419 // statements can always hold declarations. 1420 ParseScope BodyScope(this, Scope::DeclScope); 1421 1422 OwningStmtResult SynchBody(ParseCompoundStatementBody()); 1423 1424 BodyScope.Exit(); 1425 if (SynchBody.isInvalid()) 1426 SynchBody = Actions.ActOnNullStmt(Tok.getLocation()); 1427 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody)); 1428 } 1429 1430 /// objc-try-catch-statement: 1431 /// @try compound-statement objc-catch-list[opt] 1432 /// @try compound-statement objc-catch-list[opt] @finally compound-statement 1433 /// 1434 /// objc-catch-list: 1435 /// @catch ( parameter-declaration ) compound-statement 1436 /// objc-catch-list @catch ( catch-parameter-declaration ) compound-statement 1437 /// catch-parameter-declaration: 1438 /// parameter-declaration 1439 /// '...' [OBJC2] 1440 /// 1441 Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { 1442 bool catch_or_finally_seen = false; 1443 1444 ConsumeToken(); // consume try 1445 if (Tok.isNot(tok::l_brace)) { 1446 Diag(Tok, diag::err_expected_lbrace); 1447 return StmtError(); 1448 } 1449 OwningStmtResult CatchStmts(Actions); 1450 OwningStmtResult FinallyStmt(Actions); 1451 ParseScope TryScope(this, Scope::DeclScope); 1452 OwningStmtResult TryBody(ParseCompoundStatementBody()); 1453 TryScope.Exit(); 1454 if (TryBody.isInvalid()) 1455 TryBody = Actions.ActOnNullStmt(Tok.getLocation()); 1456 1457 while (Tok.is(tok::at)) { 1458 // At this point, we need to lookahead to determine if this @ is the start 1459 // of an @catch or @finally. We don't want to consume the @ token if this 1460 // is an @try or @encode or something else. 1461 Token AfterAt = GetLookAheadToken(1); 1462 if (!AfterAt.isObjCAtKeyword(tok::objc_catch) && 1463 !AfterAt.isObjCAtKeyword(tok::objc_finally)) 1464 break; 1465 1466 SourceLocation AtCatchFinallyLoc = ConsumeToken(); 1467 if (Tok.isObjCAtKeyword(tok::objc_catch)) { 1468 DeclPtrTy FirstPart; 1469 ConsumeToken(); // consume catch 1470 if (Tok.is(tok::l_paren)) { 1471 ConsumeParen(); 1472 ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope); 1473 if (Tok.isNot(tok::ellipsis)) { 1474 DeclSpec DS; 1475 ParseDeclarationSpecifiers(DS); 1476 // For some odd reason, the name of the exception variable is 1477 // optional. As a result, we need to use "PrototypeContext", because 1478 // we must accept either 'declarator' or 'abstract-declarator' here. 1479 Declarator ParmDecl(DS, Declarator::PrototypeContext); 1480 ParseDeclarator(ParmDecl); 1481 1482 // Inform the actions module about the parameter declarator, so it 1483 // gets added to the current scope. 1484 FirstPart = Actions.ActOnParamDeclarator(CurScope, ParmDecl); 1485 Actions.ActOnObjCCatchParam(FirstPart); 1486 } else 1487 ConsumeToken(); // consume '...' 1488 1489 SourceLocation RParenLoc; 1490 1491 if (Tok.is(tok::r_paren)) 1492 RParenLoc = ConsumeParen(); 1493 else // Skip over garbage, until we get to ')'. Eat the ')'. 1494 SkipUntil(tok::r_paren, true, false); 1495 1496 OwningStmtResult CatchBody(Actions, true); 1497 if (Tok.is(tok::l_brace)) 1498 CatchBody = ParseCompoundStatementBody(); 1499 else 1500 Diag(Tok, diag::err_expected_lbrace); 1501 if (CatchBody.isInvalid()) 1502 CatchBody = Actions.ActOnNullStmt(Tok.getLocation()); 1503 CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, 1504 RParenLoc, FirstPart, move(CatchBody), 1505 move(CatchStmts)); 1506 } else { 1507 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after) 1508 << "@catch clause"; 1509 return StmtError(); 1510 } 1511 catch_or_finally_seen = true; 1512 } else { 1513 assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?"); 1514 ConsumeToken(); // consume finally 1515 ParseScope FinallyScope(this, Scope::DeclScope); 1516 1517 OwningStmtResult FinallyBody(Actions, true); 1518 if (Tok.is(tok::l_brace)) 1519 FinallyBody = ParseCompoundStatementBody(); 1520 else 1521 Diag(Tok, diag::err_expected_lbrace); 1522 if (FinallyBody.isInvalid()) 1523 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation()); 1524 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, 1525 move(FinallyBody)); 1526 catch_or_finally_seen = true; 1527 break; 1528 } 1529 } 1530 if (!catch_or_finally_seen) { 1531 Diag(atLoc, diag::err_missing_catch_finally); 1532 return StmtError(); 1533 } 1534 return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), move(CatchStmts), 1535 move(FinallyStmt)); 1536 } 1537 1538 /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' 1539 /// 1540 Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() { 1541 DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl); 1542 1543 PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions, 1544 PP.getSourceManager(), 1545 "parsing Objective-C method"); 1546 1547 // parse optional ';' 1548 if (Tok.is(tok::semi)) { 1549 if (ObjCImpDecl) { 1550 Diag(Tok, diag::warn_semicolon_before_method_body) 1551 << CodeModificationHint::CreateRemoval(Tok.getLocation()); 1552 } 1553 ConsumeToken(); 1554 } 1555 1556 // We should have an opening brace now. 1557 if (Tok.isNot(tok::l_brace)) { 1558 Diag(Tok, diag::err_expected_method_body); 1559 1560 // Skip over garbage, until we get to '{'. Don't eat the '{'. 1561 SkipUntil(tok::l_brace, true, true); 1562 1563 // If we didn't find the '{', bail out. 1564 if (Tok.isNot(tok::l_brace)) 1565 return DeclPtrTy(); 1566 } 1567 SourceLocation BraceLoc = Tok.getLocation(); 1568 1569 // Enter a scope for the method body. 1570 ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope); 1571 1572 // Tell the actions module that we have entered a method definition with the 1573 // specified Declarator for the method. 1574 Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl); 1575 1576 OwningStmtResult FnBody(ParseCompoundStatementBody()); 1577 1578 // If the function body could not be parsed, make a bogus compoundstmt. 1579 if (FnBody.isInvalid()) 1580 FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 1581 MultiStmtArg(Actions), false); 1582 1583 // TODO: Pass argument information. 1584 Actions.ActOnFinishFunctionBody(MDecl, move(FnBody)); 1585 1586 // Leave the function body scope. 1587 BodyScope.Exit(); 1588 1589 return MDecl; 1590 } 1591 1592 Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { 1593 if (Tok.is(tok::code_completion)) { 1594 Actions.CodeCompleteObjCAtStatement(CurScope); 1595 ConsumeToken(); 1596 return StmtError(); 1597 } 1598 1599 if (Tok.isObjCAtKeyword(tok::objc_try)) 1600 return ParseObjCTryStmt(AtLoc); 1601 1602 if (Tok.isObjCAtKeyword(tok::objc_throw)) 1603 return ParseObjCThrowStmt(AtLoc); 1604 1605 if (Tok.isObjCAtKeyword(tok::objc_synchronized)) 1606 return ParseObjCSynchronizedStmt(AtLoc); 1607 1608 OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc)); 1609 if (Res.isInvalid()) { 1610 // If the expression is invalid, skip ahead to the next semicolon. Not 1611 // doing this opens us up to the possibility of infinite loops if 1612 // ParseExpression does not consume any tokens. 1613 SkipUntil(tok::semi); 1614 return StmtError(); 1615 } 1616 1617 // Otherwise, eat the semicolon. 1618 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); 1619 return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res)); 1620 } 1621 1622 Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { 1623 switch (Tok.getKind()) { 1624 case tok::code_completion: 1625 Actions.CodeCompleteObjCAtExpression(CurScope); 1626 ConsumeToken(); 1627 return ExprError(); 1628 1629 case tok::string_literal: // primary-expression: string-literal 1630 case tok::wide_string_literal: 1631 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc)); 1632 default: 1633 if (Tok.getIdentifierInfo() == 0) 1634 return ExprError(Diag(AtLoc, diag::err_unexpected_at)); 1635 1636 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) { 1637 case tok::objc_encode: 1638 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc)); 1639 case tok::objc_protocol: 1640 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc)); 1641 case tok::objc_selector: 1642 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc)); 1643 default: 1644 return ExprError(Diag(AtLoc, diag::err_unexpected_at)); 1645 } 1646 } 1647 } 1648 1649 /// objc-message-expr: 1650 /// '[' objc-receiver objc-message-args ']' 1651 /// 1652 /// objc-receiver: 1653 /// expression 1654 /// class-name 1655 /// type-name 1656 Parser::OwningExprResult Parser::ParseObjCMessageExpression() { 1657 assert(Tok.is(tok::l_square) && "'[' expected"); 1658 SourceLocation LBracLoc = ConsumeBracket(); // consume '[' 1659 1660 // Parse receiver 1661 if (isTokObjCMessageIdentifierReceiver()) { 1662 IdentifierInfo *ReceiverName = Tok.getIdentifierInfo(); 1663 if (ReceiverName != Ident_super || GetLookAheadToken(1).isNot(tok::period)) { 1664 SourceLocation NameLoc = ConsumeToken(); 1665 return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 1666 ExprArg(Actions)); 1667 } 1668 } 1669 1670 OwningExprResult Res(ParseExpression()); 1671 if (Res.isInvalid()) { 1672 SkipUntil(tok::r_square); 1673 return move(Res); 1674 } 1675 1676 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 1677 0, move(Res)); 1678 } 1679 1680 /// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse 1681 /// the rest of a message expression. 1682 /// 1683 /// objc-message-args: 1684 /// objc-selector 1685 /// objc-keywordarg-list 1686 /// 1687 /// objc-keywordarg-list: 1688 /// objc-keywordarg 1689 /// objc-keywordarg-list objc-keywordarg 1690 /// 1691 /// objc-keywordarg: 1692 /// selector-name[opt] ':' objc-keywordexpr 1693 /// 1694 /// objc-keywordexpr: 1695 /// nonempty-expr-list 1696 /// 1697 /// nonempty-expr-list: 1698 /// assignment-expression 1699 /// nonempty-expr-list , assignment-expression 1700 /// 1701 Parser::OwningExprResult 1702 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, 1703 SourceLocation NameLoc, 1704 IdentifierInfo *ReceiverName, 1705 ExprArg ReceiverExpr) { 1706 if (Tok.is(tok::code_completion)) { 1707 if (ReceiverName) 1708 Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc, 1709 0, 0); 1710 else 1711 Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(), 1712 0, 0); 1713 ConsumeToken(); 1714 } 1715 1716 // Parse objc-selector 1717 SourceLocation Loc; 1718 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc); 1719 1720 SourceLocation SelectorLoc = Loc; 1721 1722 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 1723 ExprVector KeyExprs(Actions); 1724 1725 if (Tok.is(tok::colon)) { 1726 while (1) { 1727 // Each iteration parses a single keyword argument. 1728 KeyIdents.push_back(selIdent); 1729 1730 if (Tok.isNot(tok::colon)) { 1731 Diag(Tok, diag::err_expected_colon); 1732 // We must manually skip to a ']', otherwise the expression skipper will 1733 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1734 // the enclosing expression. 1735 SkipUntil(tok::r_square); 1736 return ExprError(); 1737 } 1738 1739 ConsumeToken(); // Eat the ':'. 1740 /// Parse the expression after ':' 1741 OwningExprResult Res(ParseAssignmentExpression()); 1742 if (Res.isInvalid()) { 1743 // We must manually skip to a ']', otherwise the expression skipper will 1744 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1745 // the enclosing expression. 1746 SkipUntil(tok::r_square); 1747 return move(Res); 1748 } 1749 1750 // We have a valid expression. 1751 KeyExprs.push_back(Res.release()); 1752 1753 // Code completion after each argument. 1754 if (Tok.is(tok::code_completion)) { 1755 if (ReceiverName) 1756 Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc, 1757 KeyIdents.data(), 1758 KeyIdents.size()); 1759 else 1760 Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(), 1761 KeyIdents.data(), 1762 KeyIdents.size()); 1763 ConsumeToken(); 1764 } 1765 1766 // Check for another keyword selector. 1767 selIdent = ParseObjCSelectorPiece(Loc); 1768 if (!selIdent && Tok.isNot(tok::colon)) 1769 break; 1770 // We have a selector or a colon, continue parsing. 1771 } 1772 // Parse the, optional, argument list, comma separated. 1773 while (Tok.is(tok::comma)) { 1774 ConsumeToken(); // Eat the ','. 1775 /// Parse the expression after ',' 1776 OwningExprResult Res(ParseAssignmentExpression()); 1777 if (Res.isInvalid()) { 1778 // We must manually skip to a ']', otherwise the expression skipper will 1779 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1780 // the enclosing expression. 1781 SkipUntil(tok::r_square); 1782 return move(Res); 1783 } 1784 1785 // We have a valid expression. 1786 KeyExprs.push_back(Res.release()); 1787 } 1788 } else if (!selIdent) { 1789 Diag(Tok, diag::err_expected_ident); // missing selector name. 1790 1791 // We must manually skip to a ']', otherwise the expression skipper will 1792 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1793 // the enclosing expression. 1794 SkipUntil(tok::r_square); 1795 return ExprError(); 1796 } 1797 1798 if (Tok.isNot(tok::r_square)) { 1799 Diag(Tok, diag::err_expected_rsquare); 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 SourceLocation RBracLoc = ConsumeBracket(); // consume ']' 1808 1809 unsigned nKeys = KeyIdents.size(); 1810 if (nKeys == 0) 1811 KeyIdents.push_back(selIdent); 1812 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]); 1813 1814 // We've just parsed a keyword message. 1815 if (ReceiverName) 1816 return Owned(Actions.ActOnClassMessage(CurScope, ReceiverName, Sel, 1817 LBracLoc, NameLoc, SelectorLoc, 1818 RBracLoc, 1819 KeyExprs.take(), KeyExprs.size())); 1820 return Owned(Actions.ActOnInstanceMessage(ReceiverExpr.release(), Sel, 1821 LBracLoc, SelectorLoc, RBracLoc, 1822 KeyExprs.take(), KeyExprs.size())); 1823 } 1824 1825 Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { 1826 OwningExprResult Res(ParseStringLiteralExpression()); 1827 if (Res.isInvalid()) return move(Res); 1828 1829 // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string 1830 // expressions. At this point, we know that the only valid thing that starts 1831 // with '@' is an @"". 1832 llvm::SmallVector<SourceLocation, 4> AtLocs; 1833 ExprVector AtStrings(Actions); 1834 AtLocs.push_back(AtLoc); 1835 AtStrings.push_back(Res.release()); 1836 1837 while (Tok.is(tok::at)) { 1838 AtLocs.push_back(ConsumeToken()); // eat the @. 1839 1840 // Invalid unless there is a string literal. 1841 if (!isTokenStringLiteral()) 1842 return ExprError(Diag(Tok, diag::err_objc_concat_string)); 1843 1844 OwningExprResult Lit(ParseStringLiteralExpression()); 1845 if (Lit.isInvalid()) 1846 return move(Lit); 1847 1848 AtStrings.push_back(Lit.release()); 1849 } 1850 1851 return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(), 1852 AtStrings.size())); 1853 } 1854 1855 /// objc-encode-expression: 1856 /// @encode ( type-name ) 1857 Parser::OwningExprResult 1858 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { 1859 assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!"); 1860 1861 SourceLocation EncLoc = ConsumeToken(); 1862 1863 if (Tok.isNot(tok::l_paren)) 1864 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode"); 1865 1866 SourceLocation LParenLoc = ConsumeParen(); 1867 1868 TypeResult Ty = ParseTypeName(); 1869 1870 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1871 1872 if (Ty.isInvalid()) 1873 return ExprError(); 1874 1875 return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc, 1876 Ty.get(), RParenLoc)); 1877 } 1878 1879 /// objc-protocol-expression 1880 /// @protocol ( protocol-name ) 1881 Parser::OwningExprResult 1882 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { 1883 SourceLocation ProtoLoc = ConsumeToken(); 1884 1885 if (Tok.isNot(tok::l_paren)) 1886 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol"); 1887 1888 SourceLocation LParenLoc = ConsumeParen(); 1889 1890 if (Tok.isNot(tok::identifier)) 1891 return ExprError(Diag(Tok, diag::err_expected_ident)); 1892 1893 IdentifierInfo *protocolId = Tok.getIdentifierInfo(); 1894 ConsumeToken(); 1895 1896 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1897 1898 return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, 1899 LParenLoc, RParenLoc)); 1900 } 1901 1902 /// objc-selector-expression 1903 /// @selector '(' objc-keyword-selector ')' 1904 Parser::OwningExprResult 1905 Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { 1906 SourceLocation SelectorLoc = ConsumeToken(); 1907 1908 if (Tok.isNot(tok::l_paren)) 1909 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector"); 1910 1911 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 1912 SourceLocation LParenLoc = ConsumeParen(); 1913 SourceLocation sLoc; 1914 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc); 1915 if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name. 1916 return ExprError(Diag(Tok, diag::err_expected_ident)); 1917 1918 KeyIdents.push_back(SelIdent); 1919 unsigned nColons = 0; 1920 if (Tok.isNot(tok::r_paren)) { 1921 while (1) { 1922 if (Tok.isNot(tok::colon)) 1923 return ExprError(Diag(Tok, diag::err_expected_colon)); 1924 1925 nColons++; 1926 ConsumeToken(); // Eat the ':'. 1927 if (Tok.is(tok::r_paren)) 1928 break; 1929 // Check for another keyword selector. 1930 SourceLocation Loc; 1931 SelIdent = ParseObjCSelectorPiece(Loc); 1932 KeyIdents.push_back(SelIdent); 1933 if (!SelIdent && Tok.isNot(tok::colon)) 1934 break; 1935 } 1936 } 1937 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1938 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]); 1939 return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, 1940 LParenLoc, RParenLoc)); 1941 } 1942