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