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