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