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