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