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