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