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 "RAIIObjectsForParser.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/Basic/CharInfo.h" 18 #include "clang/Parse/ParseDiagnostic.h" 19 #include "clang/Sema/DeclSpec.h" 20 #include "clang/Sema/PrettyDeclStackTrace.h" 21 #include "clang/Sema/Scope.h" 22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/StringExtras.h" 24 using namespace clang; 25 26 /// Skips attributes after an Objective-C @ directive. Emits a diagnostic. 27 void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) { 28 ParsedAttributes attrs(AttrFactory); 29 if (Tok.is(tok::kw___attribute)) { 30 if (Kind == tok::objc_interface || Kind == tok::objc_protocol) 31 Diag(Tok, diag::err_objc_postfix_attribute_hint) 32 << (Kind == tok::objc_protocol); 33 else 34 Diag(Tok, diag::err_objc_postfix_attribute); 35 ParseGNUAttributes(attrs); 36 } 37 } 38 39 /// ParseObjCAtDirectives - Handle parts of the external-declaration production: 40 /// external-declaration: [C99 6.9] 41 /// [OBJC] objc-class-definition 42 /// [OBJC] objc-class-declaration 43 /// [OBJC] objc-alias-declaration 44 /// [OBJC] objc-protocol-definition 45 /// [OBJC] objc-method-definition 46 /// [OBJC] '@' 'end' 47 Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() { 48 SourceLocation AtLoc = ConsumeToken(); // the "@" 49 50 if (Tok.is(tok::code_completion)) { 51 Actions.CodeCompleteObjCAtDirective(getCurScope()); 52 cutOffParsing(); 53 return DeclGroupPtrTy(); 54 } 55 56 Decl *SingleDecl = nullptr; 57 switch (Tok.getObjCKeywordID()) { 58 case tok::objc_class: 59 return ParseObjCAtClassDeclaration(AtLoc); 60 case tok::objc_interface: { 61 ParsedAttributes attrs(AttrFactory); 62 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs); 63 break; 64 } 65 case tok::objc_protocol: { 66 ParsedAttributes attrs(AttrFactory); 67 return ParseObjCAtProtocolDeclaration(AtLoc, attrs); 68 } 69 case tok::objc_implementation: 70 return ParseObjCAtImplementationDeclaration(AtLoc); 71 case tok::objc_end: 72 return ParseObjCAtEndDeclaration(AtLoc); 73 case tok::objc_compatibility_alias: 74 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc); 75 break; 76 case tok::objc_synthesize: 77 SingleDecl = ParseObjCPropertySynthesize(AtLoc); 78 break; 79 case tok::objc_dynamic: 80 SingleDecl = ParseObjCPropertyDynamic(AtLoc); 81 break; 82 case tok::objc_import: 83 if (getLangOpts().Modules || getLangOpts().DebuggerSupport) 84 return ParseModuleImport(AtLoc); 85 Diag(AtLoc, diag::err_atimport); 86 SkipUntil(tok::semi); 87 return Actions.ConvertDeclToDeclGroup(nullptr); 88 default: 89 Diag(AtLoc, diag::err_unexpected_at); 90 SkipUntil(tok::semi); 91 SingleDecl = nullptr; 92 break; 93 } 94 return Actions.ConvertDeclToDeclGroup(SingleDecl); 95 } 96 97 /// 98 /// objc-class-declaration: 99 /// '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';' 100 /// 101 /// objc-class-forward-decl: 102 /// identifier objc-type-parameter-list[opt] 103 /// 104 Parser::DeclGroupPtrTy 105 Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { 106 ConsumeToken(); // the identifier "class" 107 SmallVector<IdentifierInfo *, 8> ClassNames; 108 SmallVector<SourceLocation, 8> ClassLocs; 109 SmallVector<ObjCTypeParamList *, 8> ClassTypeParams; 110 111 while (1) { 112 MaybeSkipAttributes(tok::objc_class); 113 if (Tok.isNot(tok::identifier)) { 114 Diag(Tok, diag::err_expected) << tok::identifier; 115 SkipUntil(tok::semi); 116 return Actions.ConvertDeclToDeclGroup(nullptr); 117 } 118 ClassNames.push_back(Tok.getIdentifierInfo()); 119 ClassLocs.push_back(Tok.getLocation()); 120 ConsumeToken(); 121 122 // Parse the optional objc-type-parameter-list. 123 ObjCTypeParamList *TypeParams = nullptr; 124 if (Tok.is(tok::less)) { 125 TypeParams = parseObjCTypeParamList(); 126 if (TypeParams) 127 Actions.popObjCTypeParamList(getCurScope(), TypeParams); 128 } 129 ClassTypeParams.push_back(TypeParams); 130 if (!TryConsumeToken(tok::comma)) 131 break; 132 } 133 134 // Consume the ';'. 135 if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class")) 136 return Actions.ConvertDeclToDeclGroup(nullptr); 137 138 return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(), 139 ClassLocs.data(), 140 ClassTypeParams, 141 ClassNames.size()); 142 } 143 144 void Parser::CheckNestedObjCContexts(SourceLocation AtLoc) 145 { 146 Sema::ObjCContainerKind ock = Actions.getObjCContainerKind(); 147 if (ock == Sema::OCK_None) 148 return; 149 150 Decl *Decl = Actions.getObjCDeclContext(); 151 if (CurParsedObjCImpl) { 152 CurParsedObjCImpl->finish(AtLoc); 153 } else { 154 Actions.ActOnAtEnd(getCurScope(), AtLoc); 155 } 156 Diag(AtLoc, diag::err_objc_missing_end) 157 << FixItHint::CreateInsertion(AtLoc, "@end\n"); 158 if (Decl) 159 Diag(Decl->getLocStart(), diag::note_objc_container_start) 160 << (int) ock; 161 } 162 163 /// 164 /// objc-interface: 165 /// objc-class-interface-attributes[opt] objc-class-interface 166 /// objc-category-interface 167 /// 168 /// objc-class-interface: 169 /// '@' 'interface' identifier objc-type-parameter-list[opt] 170 /// objc-superclass[opt] objc-protocol-refs[opt] 171 /// objc-class-instance-variables[opt] 172 /// objc-interface-decl-list 173 /// @end 174 /// 175 /// objc-category-interface: 176 /// '@' 'interface' identifier objc-type-parameter-list[opt] 177 /// '(' identifier[opt] ')' objc-protocol-refs[opt] 178 /// objc-interface-decl-list 179 /// @end 180 /// 181 /// objc-superclass: 182 /// ':' identifier objc-type-arguments[opt] 183 /// 184 /// objc-class-interface-attributes: 185 /// __attribute__((visibility("default"))) 186 /// __attribute__((visibility("hidden"))) 187 /// __attribute__((deprecated)) 188 /// __attribute__((unavailable)) 189 /// __attribute__((objc_exception)) - used by NSException on 64-bit 190 /// __attribute__((objc_root_class)) 191 /// 192 Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, 193 ParsedAttributes &attrs) { 194 assert(Tok.isObjCAtKeyword(tok::objc_interface) && 195 "ParseObjCAtInterfaceDeclaration(): Expected @interface"); 196 CheckNestedObjCContexts(AtLoc); 197 ConsumeToken(); // the "interface" identifier 198 199 // Code completion after '@interface'. 200 if (Tok.is(tok::code_completion)) { 201 Actions.CodeCompleteObjCInterfaceDecl(getCurScope()); 202 cutOffParsing(); 203 return nullptr; 204 } 205 206 MaybeSkipAttributes(tok::objc_interface); 207 208 if (Tok.isNot(tok::identifier)) { 209 Diag(Tok, diag::err_expected) 210 << tok::identifier; // missing class or category name. 211 return nullptr; 212 } 213 214 // We have a class or category name - consume it. 215 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 216 SourceLocation nameLoc = ConsumeToken(); 217 218 // Parse the objc-type-parameter-list or objc-protocol-refs. For the latter 219 // case, LAngleLoc will be valid and ProtocolIdents will capture the 220 // protocol references (that have not yet been resolved). 221 SourceLocation LAngleLoc, EndProtoLoc; 222 SmallVector<IdentifierLocPair, 8> ProtocolIdents; 223 ObjCTypeParamList *typeParameterList = nullptr; 224 if (Tok.is(tok::less)) { 225 typeParameterList = parseObjCTypeParamListOrProtocolRefs(LAngleLoc, 226 ProtocolIdents, 227 EndProtoLoc); 228 } 229 230 if (Tok.is(tok::l_paren) && 231 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { // we have a category. 232 233 BalancedDelimiterTracker T(*this, tok::l_paren); 234 T.consumeOpen(); 235 236 SourceLocation categoryLoc; 237 IdentifierInfo *categoryId = nullptr; 238 if (Tok.is(tok::code_completion)) { 239 Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc); 240 cutOffParsing(); 241 return nullptr; 242 } 243 244 // For ObjC2, the category name is optional (not an error). 245 if (Tok.is(tok::identifier)) { 246 categoryId = Tok.getIdentifierInfo(); 247 categoryLoc = ConsumeToken(); 248 } 249 else if (!getLangOpts().ObjC2) { 250 Diag(Tok, diag::err_expected) 251 << tok::identifier; // missing category name. 252 return nullptr; 253 } 254 255 T.consumeClose(); 256 if (T.getCloseLocation().isInvalid()) 257 return nullptr; 258 259 if (!attrs.empty()) { // categories don't support attributes. 260 Diag(nameLoc, diag::err_objc_no_attributes_on_category); 261 attrs.clear(); 262 } 263 264 // Next, we need to check for any protocol references. 265 assert(LAngleLoc.isInvalid() && "Cannot have already parsed protocols"); 266 SmallVector<Decl *, 8> ProtocolRefs; 267 SmallVector<SourceLocation, 8> ProtocolLocs; 268 if (Tok.is(tok::less) && 269 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, true, 270 LAngleLoc, EndProtoLoc, 271 /*consumeLastToken=*/true)) 272 return nullptr; 273 274 Decl *CategoryType = 275 Actions.ActOnStartCategoryInterface(AtLoc, 276 nameId, nameLoc, 277 typeParameterList, 278 categoryId, categoryLoc, 279 ProtocolRefs.data(), 280 ProtocolRefs.size(), 281 ProtocolLocs.data(), 282 EndProtoLoc); 283 284 if (Tok.is(tok::l_brace)) 285 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc); 286 287 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType); 288 289 if (typeParameterList) 290 Actions.popObjCTypeParamList(getCurScope(), typeParameterList); 291 292 return CategoryType; 293 } 294 // Parse a class interface. 295 IdentifierInfo *superClassId = nullptr; 296 SourceLocation superClassLoc; 297 SourceLocation typeArgsLAngleLoc; 298 SmallVector<ParsedType, 4> typeArgs; 299 SourceLocation typeArgsRAngleLoc; 300 SmallVector<Decl *, 4> protocols; 301 SmallVector<SourceLocation, 4> protocolLocs; 302 if (Tok.is(tok::colon)) { // a super class is specified. 303 ConsumeToken(); 304 305 // Code completion of superclass names. 306 if (Tok.is(tok::code_completion)) { 307 Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc); 308 cutOffParsing(); 309 return nullptr; 310 } 311 312 if (Tok.isNot(tok::identifier)) { 313 Diag(Tok, diag::err_expected) 314 << tok::identifier; // missing super class name. 315 return nullptr; 316 } 317 superClassId = Tok.getIdentifierInfo(); 318 superClassLoc = ConsumeToken(); 319 320 // Type arguments for the superclass or protocol conformances. 321 if (Tok.is(tok::less)) { 322 parseObjCTypeArgsOrProtocolQualifiers(typeArgsLAngleLoc, 323 typeArgs, 324 typeArgsRAngleLoc, 325 LAngleLoc, 326 protocols, 327 protocolLocs, 328 EndProtoLoc, 329 /*consumeLastToken=*/true, 330 /*warnOnIncompleteProtocols=*/true); 331 } 332 } 333 334 // Next, we need to check for any protocol references. 335 if (LAngleLoc.isValid()) { 336 if (!ProtocolIdents.empty()) { 337 // We already parsed the protocols named when we thought we had a 338 // type parameter list. Translate them into actual protocol references. 339 for (const auto &pair : ProtocolIdents) { 340 protocolLocs.push_back(pair.second); 341 } 342 Actions.FindProtocolDeclaration(/*WarnOnDeclarations=*/true, 343 /*ForObjCContainer=*/true, 344 &ProtocolIdents[0], ProtocolIdents.size(), 345 protocols); 346 } 347 } else if (protocols.empty() && Tok.is(tok::less) && 348 ParseObjCProtocolReferences(protocols, protocolLocs, true, true, 349 LAngleLoc, EndProtoLoc, 350 /*consumeLastToken=*/true)) { 351 return nullptr; 352 } 353 354 if (Tok.isNot(tok::less)) 355 Actions.ActOnTypedefedProtocols(protocols, superClassId, superClassLoc); 356 357 Decl *ClsType = 358 Actions.ActOnStartClassInterface(getCurScope(), AtLoc, nameId, nameLoc, 359 typeParameterList, superClassId, 360 superClassLoc, 361 typeArgs, 362 SourceRange(typeArgsLAngleLoc, 363 typeArgsRAngleLoc), 364 protocols.data(), protocols.size(), 365 protocolLocs.data(), 366 EndProtoLoc, attrs.getList()); 367 368 if (Tok.is(tok::l_brace)) 369 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc); 370 371 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType); 372 373 if (typeParameterList) 374 Actions.popObjCTypeParamList(getCurScope(), typeParameterList); 375 376 return ClsType; 377 } 378 379 /// Add an attribute for a context-sensitive type nullability to the given 380 /// declarator. 381 static void addContextSensitiveTypeNullability(Parser &P, 382 Declarator &D, 383 NullabilityKind nullability, 384 SourceLocation nullabilityLoc, 385 bool &addedToDeclSpec) { 386 // Create the attribute. 387 auto getNullabilityAttr = [&]() -> AttributeList * { 388 return D.getAttributePool().create( 389 P.getNullabilityKeyword(nullability), 390 SourceRange(nullabilityLoc), 391 nullptr, SourceLocation(), 392 nullptr, 0, 393 AttributeList::AS_ContextSensitiveKeyword); 394 }; 395 396 if (D.getNumTypeObjects() > 0) { 397 // Add the attribute to the declarator chunk nearest the declarator. 398 auto nullabilityAttr = getNullabilityAttr(); 399 DeclaratorChunk &chunk = D.getTypeObject(0); 400 nullabilityAttr->setNext(chunk.getAttrListRef()); 401 chunk.getAttrListRef() = nullabilityAttr; 402 } else if (!addedToDeclSpec) { 403 // Otherwise, just put it on the declaration specifiers (if one 404 // isn't there already). 405 D.getMutableDeclSpec().addAttributes(getNullabilityAttr()); 406 addedToDeclSpec = true; 407 } 408 } 409 410 /// Parse an Objective-C type parameter list, if present, or capture 411 /// the locations of the protocol identifiers for a list of protocol 412 /// references. 413 /// 414 /// objc-type-parameter-list: 415 /// '<' objc-type-parameter (',' objc-type-parameter)* '>' 416 /// 417 /// objc-type-parameter: 418 /// identifier objc-type-parameter-bound[opt] 419 /// 420 /// objc-type-parameter-bound: 421 /// ':' type-name 422 /// 423 /// \param lAngleLoc The location of the starting '<'. 424 /// 425 /// \param protocolIdents Will capture the list of identifiers, if the 426 /// angle brackets contain a list of protocol references rather than a 427 /// type parameter list. 428 /// 429 /// \param rAngleLoc The location of the ending '>'. 430 ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs( 431 SourceLocation &lAngleLoc, 432 SmallVectorImpl<IdentifierLocPair> &protocolIdents, 433 SourceLocation &rAngleLoc, 434 bool mayBeProtocolList) { 435 assert(Tok.is(tok::less) && "Not at the beginning of a type parameter list"); 436 437 // Within the type parameter list, don't treat '>' as an operator. 438 GreaterThanIsOperatorScope G(GreaterThanIsOperator, false); 439 440 // Local function to "flush" the protocol identifiers, turning them into 441 // type parameters. 442 SmallVector<Decl *, 4> typeParams; 443 auto makeProtocolIdentsIntoTypeParameters = [&]() { 444 unsigned index = 0; 445 for (const auto &pair : protocolIdents) { 446 DeclResult typeParam = Actions.actOnObjCTypeParam(getCurScope(), 447 index++, 448 pair.first, 449 pair.second, 450 SourceLocation(), 451 ParsedType()); 452 if (typeParam.isUsable()) 453 typeParams.push_back(typeParam.get()); 454 } 455 456 protocolIdents.clear(); 457 mayBeProtocolList = false; 458 }; 459 460 bool invalid = false; 461 lAngleLoc = ConsumeToken(); 462 do { 463 // Parse the identifier. 464 if (!Tok.is(tok::identifier)) { 465 // Code completion. 466 if (Tok.is(tok::code_completion)) { 467 // FIXME: If these aren't protocol references, we'll need different 468 // completions. 469 Actions.CodeCompleteObjCProtocolReferences(protocolIdents.data(), 470 protocolIdents.size()); 471 cutOffParsing(); 472 473 // FIXME: Better recovery here?. 474 return nullptr; 475 } 476 477 Diag(Tok, diag::err_objc_expected_type_parameter); 478 invalid = true; 479 break; 480 } 481 482 IdentifierInfo *paramName = Tok.getIdentifierInfo(); 483 SourceLocation paramLoc = ConsumeToken(); 484 485 // If there is a bound, parse it. 486 SourceLocation colonLoc; 487 TypeResult boundType; 488 if (TryConsumeToken(tok::colon, colonLoc)) { 489 // Once we've seen a bound, we know this is not a list of protocol 490 // references. 491 if (mayBeProtocolList) { 492 // Up until now, we have been queuing up parameters because they 493 // might be protocol references. Turn them into parameters now. 494 makeProtocolIdentsIntoTypeParameters(); 495 } 496 497 // type-name 498 boundType = ParseTypeName(); 499 if (boundType.isInvalid()) 500 invalid = true; 501 } else if (mayBeProtocolList) { 502 // If this could still be a protocol list, just capture the identifier. 503 // We don't want to turn it into a parameter. 504 protocolIdents.push_back(std::make_pair(paramName, paramLoc)); 505 continue; 506 } 507 508 // Create the type parameter. 509 DeclResult typeParam = Actions.actOnObjCTypeParam(getCurScope(), 510 typeParams.size(), 511 paramName, 512 paramLoc, 513 colonLoc, 514 boundType.isUsable() 515 ? boundType.get() 516 : ParsedType()); 517 if (typeParam.isUsable()) 518 typeParams.push_back(typeParam.get()); 519 } while (TryConsumeToken(tok::comma)); 520 521 // Parse the '>'. 522 if (invalid) { 523 SkipUntil(tok::greater, tok::at, StopBeforeMatch); 524 if (Tok.is(tok::greater)) 525 ConsumeToken(); 526 } else if (ParseGreaterThanInTemplateList(rAngleLoc, 527 /*ConsumeLastToken=*/true, 528 /*ObjCGenericList=*/true)) { 529 Diag(lAngleLoc, diag::note_matching) << "'<'"; 530 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus, 531 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace, 532 tok::comma, tok::semi }, 533 StopBeforeMatch); 534 if (Tok.is(tok::greater)) 535 ConsumeToken(); 536 } 537 538 if (mayBeProtocolList) { 539 // A type parameter list must be followed by either a ':' (indicating the 540 // presence of a superclass) or a '(' (indicating that this is a category 541 // or extension). This disambiguates between an objc-type-parameter-list 542 // and a objc-protocol-refs. 543 if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_paren)) { 544 // Returning null indicates that we don't have a type parameter list. 545 // The results the caller needs to handle the protocol references are 546 // captured in the reference parameters already. 547 return nullptr; 548 } 549 550 // We have a type parameter list that looks like a list of protocol 551 // references. Turn that parameter list into type parameters. 552 makeProtocolIdentsIntoTypeParameters(); 553 } 554 555 // Form the type parameter list. 556 ObjCTypeParamList *list = Actions.actOnObjCTypeParamList( 557 getCurScope(), 558 lAngleLoc, 559 typeParams, 560 rAngleLoc); 561 562 // Clear out the angle locations; they're used by the caller to indicate 563 // whether there are any protocol references. 564 lAngleLoc = SourceLocation(); 565 rAngleLoc = SourceLocation(); 566 return list; 567 } 568 569 /// Parse an objc-type-parameter-list. 570 ObjCTypeParamList *Parser::parseObjCTypeParamList() { 571 SourceLocation lAngleLoc; 572 SmallVector<IdentifierLocPair, 1> protocolIdents; 573 SourceLocation rAngleLoc; 574 return parseObjCTypeParamListOrProtocolRefs(lAngleLoc, protocolIdents, 575 rAngleLoc, 576 /*mayBeProtocolList=*/false); 577 } 578 579 /// objc-interface-decl-list: 580 /// empty 581 /// objc-interface-decl-list objc-property-decl [OBJC2] 582 /// objc-interface-decl-list objc-method-requirement [OBJC2] 583 /// objc-interface-decl-list objc-method-proto ';' 584 /// objc-interface-decl-list declaration 585 /// objc-interface-decl-list ';' 586 /// 587 /// objc-method-requirement: [OBJC2] 588 /// @required 589 /// @optional 590 /// 591 void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, 592 Decl *CDecl) { 593 SmallVector<Decl *, 32> allMethods; 594 SmallVector<Decl *, 16> allProperties; 595 SmallVector<DeclGroupPtrTy, 8> allTUVariables; 596 tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword; 597 598 SourceRange AtEnd; 599 600 while (1) { 601 // If this is a method prototype, parse it. 602 if (Tok.isOneOf(tok::minus, tok::plus)) { 603 if (Decl *methodPrototype = 604 ParseObjCMethodPrototype(MethodImplKind, false)) 605 allMethods.push_back(methodPrototype); 606 // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for 607 // method definitions. 608 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) { 609 // We didn't find a semi and we error'ed out. Skip until a ';' or '@'. 610 SkipUntil(tok::at, StopAtSemi | StopBeforeMatch); 611 if (Tok.is(tok::semi)) 612 ConsumeToken(); 613 } 614 continue; 615 } 616 if (Tok.is(tok::l_paren)) { 617 Diag(Tok, diag::err_expected_minus_or_plus); 618 ParseObjCMethodDecl(Tok.getLocation(), 619 tok::minus, 620 MethodImplKind, false); 621 continue; 622 } 623 // Ignore excess semicolons. 624 if (Tok.is(tok::semi)) { 625 ConsumeToken(); 626 continue; 627 } 628 629 // If we got to the end of the file, exit the loop. 630 if (isEofOrEom()) 631 break; 632 633 // Code completion within an Objective-C interface. 634 if (Tok.is(tok::code_completion)) { 635 Actions.CodeCompleteOrdinaryName(getCurScope(), 636 CurParsedObjCImpl? Sema::PCC_ObjCImplementation 637 : Sema::PCC_ObjCInterface); 638 return cutOffParsing(); 639 } 640 641 // If we don't have an @ directive, parse it as a function definition. 642 if (Tok.isNot(tok::at)) { 643 // The code below does not consume '}'s because it is afraid of eating the 644 // end of a namespace. Because of the way this code is structured, an 645 // erroneous r_brace would cause an infinite loop if not handled here. 646 if (Tok.is(tok::r_brace)) 647 break; 648 ParsedAttributesWithRange attrs(AttrFactory); 649 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs)); 650 continue; 651 } 652 653 // Otherwise, we have an @ directive, eat the @. 654 SourceLocation AtLoc = ConsumeToken(); // the "@" 655 if (Tok.is(tok::code_completion)) { 656 Actions.CodeCompleteObjCAtDirective(getCurScope()); 657 return cutOffParsing(); 658 } 659 660 tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID(); 661 662 if (DirectiveKind == tok::objc_end) { // @end -> terminate list 663 AtEnd.setBegin(AtLoc); 664 AtEnd.setEnd(Tok.getLocation()); 665 break; 666 } else if (DirectiveKind == tok::objc_not_keyword) { 667 Diag(Tok, diag::err_objc_unknown_at); 668 SkipUntil(tok::semi); 669 continue; 670 } 671 672 // Eat the identifier. 673 ConsumeToken(); 674 675 switch (DirectiveKind) { 676 default: 677 // FIXME: If someone forgets an @end on a protocol, this loop will 678 // continue to eat up tons of stuff and spew lots of nonsense errors. It 679 // would probably be better to bail out if we saw an @class or @interface 680 // or something like that. 681 Diag(AtLoc, diag::err_objc_illegal_interface_qual); 682 // Skip until we see an '@' or '}' or ';'. 683 SkipUntil(tok::r_brace, tok::at, StopAtSemi); 684 break; 685 686 case tok::objc_implementation: 687 case tok::objc_interface: 688 Diag(AtLoc, diag::err_objc_missing_end) 689 << FixItHint::CreateInsertion(AtLoc, "@end\n"); 690 Diag(CDecl->getLocStart(), diag::note_objc_container_start) 691 << (int) Actions.getObjCContainerKind(); 692 ConsumeToken(); 693 break; 694 695 case tok::objc_required: 696 case tok::objc_optional: 697 // This is only valid on protocols. 698 // FIXME: Should this check for ObjC2 being enabled? 699 if (contextKey != tok::objc_protocol) 700 Diag(AtLoc, diag::err_objc_directive_only_in_protocol); 701 else 702 MethodImplKind = DirectiveKind; 703 break; 704 705 case tok::objc_property: 706 if (!getLangOpts().ObjC2) 707 Diag(AtLoc, diag::err_objc_properties_require_objc2); 708 709 ObjCDeclSpec OCDS; 710 SourceLocation LParenLoc; 711 // Parse property attribute list, if any. 712 if (Tok.is(tok::l_paren)) { 713 LParenLoc = Tok.getLocation(); 714 ParseObjCPropertyAttribute(OCDS); 715 } 716 717 bool addedToDeclSpec = false; 718 auto ObjCPropertyCallback = [&](ParsingFieldDeclarator &FD) { 719 if (FD.D.getIdentifier() == nullptr) { 720 Diag(AtLoc, diag::err_objc_property_requires_field_name) 721 << FD.D.getSourceRange(); 722 return; 723 } 724 if (FD.BitfieldSize) { 725 Diag(AtLoc, diag::err_objc_property_bitfield) 726 << FD.D.getSourceRange(); 727 return; 728 } 729 730 // Map a nullability property attribute to a context-sensitive keyword 731 // attribute. 732 if (OCDS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability) 733 addContextSensitiveTypeNullability(*this, FD.D, OCDS.getNullability(), 734 OCDS.getNullabilityLoc(), 735 addedToDeclSpec); 736 737 // Install the property declarator into interfaceDecl. 738 IdentifierInfo *SelName = 739 OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier(); 740 741 Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName); 742 IdentifierInfo *SetterName = OCDS.getSetterName(); 743 Selector SetterSel; 744 if (SetterName) 745 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName); 746 else 747 SetterSel = SelectorTable::constructSetterSelector( 748 PP.getIdentifierTable(), PP.getSelectorTable(), 749 FD.D.getIdentifier()); 750 bool isOverridingProperty = false; 751 Decl *Property = Actions.ActOnProperty( 752 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel, 753 &isOverridingProperty, MethodImplKind); 754 if (!isOverridingProperty) 755 allProperties.push_back(Property); 756 757 FD.complete(Property); 758 }; 759 760 // Parse all the comma separated declarators. 761 ParsingDeclSpec DS(*this); 762 ParseStructDeclaration(DS, ObjCPropertyCallback); 763 764 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); 765 break; 766 } 767 } 768 769 // We break out of the big loop in two cases: when we see @end or when we see 770 // EOF. In the former case, eat the @end. In the later case, emit an error. 771 if (Tok.is(tok::code_completion)) { 772 Actions.CodeCompleteObjCAtDirective(getCurScope()); 773 return cutOffParsing(); 774 } else if (Tok.isObjCAtKeyword(tok::objc_end)) { 775 ConsumeToken(); // the "end" identifier 776 } else { 777 Diag(Tok, diag::err_objc_missing_end) 778 << FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n"); 779 Diag(CDecl->getLocStart(), diag::note_objc_container_start) 780 << (int) Actions.getObjCContainerKind(); 781 AtEnd.setBegin(Tok.getLocation()); 782 AtEnd.setEnd(Tok.getLocation()); 783 } 784 785 // Insert collected methods declarations into the @interface object. 786 // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit. 787 Actions.ActOnAtEnd(getCurScope(), AtEnd, allMethods, allTUVariables); 788 } 789 790 /// Diagnose redundant or conflicting nullability information. 791 static void diagnoseRedundantPropertyNullability(Parser &P, 792 ObjCDeclSpec &DS, 793 NullabilityKind nullability, 794 SourceLocation nullabilityLoc){ 795 if (DS.getNullability() == nullability) { 796 P.Diag(nullabilityLoc, diag::warn_nullability_duplicate) 797 << DiagNullabilityKind(nullability, true) 798 << SourceRange(DS.getNullabilityLoc()); 799 return; 800 } 801 802 P.Diag(nullabilityLoc, diag::err_nullability_conflicting) 803 << DiagNullabilityKind(nullability, true) 804 << DiagNullabilityKind(DS.getNullability(), true) 805 << SourceRange(DS.getNullabilityLoc()); 806 } 807 808 /// Parse property attribute declarations. 809 /// 810 /// property-attr-decl: '(' property-attrlist ')' 811 /// property-attrlist: 812 /// property-attribute 813 /// property-attrlist ',' property-attribute 814 /// property-attribute: 815 /// getter '=' identifier 816 /// setter '=' identifier ':' 817 /// readonly 818 /// readwrite 819 /// assign 820 /// retain 821 /// copy 822 /// nonatomic 823 /// atomic 824 /// strong 825 /// weak 826 /// unsafe_unretained 827 /// nonnull 828 /// nullable 829 /// null_unspecified 830 /// null_resettable 831 /// 832 void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { 833 assert(Tok.getKind() == tok::l_paren); 834 BalancedDelimiterTracker T(*this, tok::l_paren); 835 T.consumeOpen(); 836 837 while (1) { 838 if (Tok.is(tok::code_completion)) { 839 Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS); 840 return cutOffParsing(); 841 } 842 const IdentifierInfo *II = Tok.getIdentifierInfo(); 843 844 // If this is not an identifier at all, bail out early. 845 if (!II) { 846 T.consumeClose(); 847 return; 848 } 849 850 SourceLocation AttrName = ConsumeToken(); // consume last attribute name 851 852 if (II->isStr("readonly")) 853 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly); 854 else if (II->isStr("assign")) 855 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign); 856 else if (II->isStr("unsafe_unretained")) 857 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_unsafe_unretained); 858 else if (II->isStr("readwrite")) 859 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite); 860 else if (II->isStr("retain")) 861 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain); 862 else if (II->isStr("strong")) 863 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_strong); 864 else if (II->isStr("copy")) 865 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy); 866 else if (II->isStr("nonatomic")) 867 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic); 868 else if (II->isStr("atomic")) 869 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_atomic); 870 else if (II->isStr("weak")) 871 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_weak); 872 else if (II->isStr("getter") || II->isStr("setter")) { 873 bool IsSetter = II->getNameStart()[0] == 's'; 874 875 // getter/setter require extra treatment. 876 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter : 877 diag::err_objc_expected_equal_for_getter; 878 879 if (ExpectAndConsume(tok::equal, DiagID)) { 880 SkipUntil(tok::r_paren, StopAtSemi); 881 return; 882 } 883 884 if (Tok.is(tok::code_completion)) { 885 if (IsSetter) 886 Actions.CodeCompleteObjCPropertySetter(getCurScope()); 887 else 888 Actions.CodeCompleteObjCPropertyGetter(getCurScope()); 889 return cutOffParsing(); 890 } 891 892 893 SourceLocation SelLoc; 894 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc); 895 896 if (!SelIdent) { 897 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter) 898 << IsSetter; 899 SkipUntil(tok::r_paren, StopAtSemi); 900 return; 901 } 902 903 if (IsSetter) { 904 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter); 905 DS.setSetterName(SelIdent); 906 907 if (ExpectAndConsume(tok::colon, 908 diag::err_expected_colon_after_setter_name)) { 909 SkipUntil(tok::r_paren, StopAtSemi); 910 return; 911 } 912 } else { 913 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter); 914 DS.setGetterName(SelIdent); 915 } 916 } else if (II->isStr("nonnull")) { 917 if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability) 918 diagnoseRedundantPropertyNullability(*this, DS, 919 NullabilityKind::NonNull, 920 Tok.getLocation()); 921 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability); 922 DS.setNullability(Tok.getLocation(), NullabilityKind::NonNull); 923 } else if (II->isStr("nullable")) { 924 if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability) 925 diagnoseRedundantPropertyNullability(*this, DS, 926 NullabilityKind::Nullable, 927 Tok.getLocation()); 928 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability); 929 DS.setNullability(Tok.getLocation(), NullabilityKind::Nullable); 930 } else if (II->isStr("null_unspecified")) { 931 if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability) 932 diagnoseRedundantPropertyNullability(*this, DS, 933 NullabilityKind::Unspecified, 934 Tok.getLocation()); 935 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability); 936 DS.setNullability(Tok.getLocation(), NullabilityKind::Unspecified); 937 } else if (II->isStr("null_resettable")) { 938 if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability) 939 diagnoseRedundantPropertyNullability(*this, DS, 940 NullabilityKind::Unspecified, 941 Tok.getLocation()); 942 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability); 943 DS.setNullability(Tok.getLocation(), NullabilityKind::Unspecified); 944 945 // Also set the null_resettable bit. 946 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_null_resettable); 947 } else { 948 Diag(AttrName, diag::err_objc_expected_property_attr) << II; 949 SkipUntil(tok::r_paren, StopAtSemi); 950 return; 951 } 952 953 if (Tok.isNot(tok::comma)) 954 break; 955 956 ConsumeToken(); 957 } 958 959 T.consumeClose(); 960 } 961 962 /// objc-method-proto: 963 /// objc-instance-method objc-method-decl objc-method-attributes[opt] 964 /// objc-class-method objc-method-decl objc-method-attributes[opt] 965 /// 966 /// objc-instance-method: '-' 967 /// objc-class-method: '+' 968 /// 969 /// objc-method-attributes: [OBJC2] 970 /// __attribute__((deprecated)) 971 /// 972 Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind, 973 bool MethodDefinition) { 974 assert(Tok.isOneOf(tok::minus, tok::plus) && "expected +/-"); 975 976 tok::TokenKind methodType = Tok.getKind(); 977 SourceLocation mLoc = ConsumeToken(); 978 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind, 979 MethodDefinition); 980 // Since this rule is used for both method declarations and definitions, 981 // the caller is (optionally) responsible for consuming the ';'. 982 return MDecl; 983 } 984 985 /// objc-selector: 986 /// identifier 987 /// one of 988 /// enum struct union if else while do for switch case default 989 /// break continue return goto asm sizeof typeof __alignof 990 /// unsigned long const short volatile signed restrict _Complex 991 /// in out inout bycopy byref oneway int char float double void _Bool 992 /// 993 IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) { 994 995 switch (Tok.getKind()) { 996 default: 997 return nullptr; 998 case tok::ampamp: 999 case tok::ampequal: 1000 case tok::amp: 1001 case tok::pipe: 1002 case tok::tilde: 1003 case tok::exclaim: 1004 case tok::exclaimequal: 1005 case tok::pipepipe: 1006 case tok::pipeequal: 1007 case tok::caret: 1008 case tok::caretequal: { 1009 std::string ThisTok(PP.getSpelling(Tok)); 1010 if (isLetter(ThisTok[0])) { 1011 IdentifierInfo *II = &PP.getIdentifierTable().get(ThisTok.data()); 1012 Tok.setKind(tok::identifier); 1013 SelectorLoc = ConsumeToken(); 1014 return II; 1015 } 1016 return nullptr; 1017 } 1018 1019 case tok::identifier: 1020 case tok::kw_asm: 1021 case tok::kw_auto: 1022 case tok::kw_bool: 1023 case tok::kw_break: 1024 case tok::kw_case: 1025 case tok::kw_catch: 1026 case tok::kw_char: 1027 case tok::kw_class: 1028 case tok::kw_const: 1029 case tok::kw_const_cast: 1030 case tok::kw_continue: 1031 case tok::kw_default: 1032 case tok::kw_delete: 1033 case tok::kw_do: 1034 case tok::kw_double: 1035 case tok::kw_dynamic_cast: 1036 case tok::kw_else: 1037 case tok::kw_enum: 1038 case tok::kw_explicit: 1039 case tok::kw_export: 1040 case tok::kw_extern: 1041 case tok::kw_false: 1042 case tok::kw_float: 1043 case tok::kw_for: 1044 case tok::kw_friend: 1045 case tok::kw_goto: 1046 case tok::kw_if: 1047 case tok::kw_inline: 1048 case tok::kw_int: 1049 case tok::kw_long: 1050 case tok::kw_mutable: 1051 case tok::kw_namespace: 1052 case tok::kw_new: 1053 case tok::kw_operator: 1054 case tok::kw_private: 1055 case tok::kw_protected: 1056 case tok::kw_public: 1057 case tok::kw_register: 1058 case tok::kw_reinterpret_cast: 1059 case tok::kw_restrict: 1060 case tok::kw_return: 1061 case tok::kw_short: 1062 case tok::kw_signed: 1063 case tok::kw_sizeof: 1064 case tok::kw_static: 1065 case tok::kw_static_cast: 1066 case tok::kw_struct: 1067 case tok::kw_switch: 1068 case tok::kw_template: 1069 case tok::kw_this: 1070 case tok::kw_throw: 1071 case tok::kw_true: 1072 case tok::kw_try: 1073 case tok::kw_typedef: 1074 case tok::kw_typeid: 1075 case tok::kw_typename: 1076 case tok::kw_typeof: 1077 case tok::kw_union: 1078 case tok::kw_unsigned: 1079 case tok::kw_using: 1080 case tok::kw_virtual: 1081 case tok::kw_void: 1082 case tok::kw_volatile: 1083 case tok::kw_wchar_t: 1084 case tok::kw_while: 1085 case tok::kw__Bool: 1086 case tok::kw__Complex: 1087 case tok::kw___alignof: 1088 IdentifierInfo *II = Tok.getIdentifierInfo(); 1089 SelectorLoc = ConsumeToken(); 1090 return II; 1091 } 1092 } 1093 1094 /// objc-for-collection-in: 'in' 1095 /// 1096 bool Parser::isTokIdentifier_in() const { 1097 // FIXME: May have to do additional look-ahead to only allow for 1098 // valid tokens following an 'in'; such as an identifier, unary operators, 1099 // '[' etc. 1100 return (getLangOpts().ObjC2 && Tok.is(tok::identifier) && 1101 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]); 1102 } 1103 1104 /// ParseObjCTypeQualifierList - This routine parses the objective-c's type 1105 /// qualifier list and builds their bitmask representation in the input 1106 /// argument. 1107 /// 1108 /// objc-type-qualifiers: 1109 /// objc-type-qualifier 1110 /// objc-type-qualifiers objc-type-qualifier 1111 /// 1112 /// objc-type-qualifier: 1113 /// 'in' 1114 /// 'out' 1115 /// 'inout' 1116 /// 'oneway' 1117 /// 'bycopy' 1118 /// 'byref' 1119 /// 'nonnull' 1120 /// 'nullable' 1121 /// 'null_unspecified' 1122 /// 1123 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, 1124 Declarator::TheContext Context) { 1125 assert(Context == Declarator::ObjCParameterContext || 1126 Context == Declarator::ObjCResultContext); 1127 1128 while (1) { 1129 if (Tok.is(tok::code_completion)) { 1130 Actions.CodeCompleteObjCPassingType(getCurScope(), DS, 1131 Context == Declarator::ObjCParameterContext); 1132 return cutOffParsing(); 1133 } 1134 1135 if (Tok.isNot(tok::identifier)) 1136 return; 1137 1138 const IdentifierInfo *II = Tok.getIdentifierInfo(); 1139 for (unsigned i = 0; i != objc_NumQuals; ++i) { 1140 if (II != ObjCTypeQuals[i] || 1141 NextToken().is(tok::less) || 1142 NextToken().is(tok::coloncolon)) 1143 continue; 1144 1145 ObjCDeclSpec::ObjCDeclQualifier Qual; 1146 NullabilityKind Nullability; 1147 switch (i) { 1148 default: llvm_unreachable("Unknown decl qualifier"); 1149 case objc_in: Qual = ObjCDeclSpec::DQ_In; break; 1150 case objc_out: Qual = ObjCDeclSpec::DQ_Out; break; 1151 case objc_inout: Qual = ObjCDeclSpec::DQ_Inout; break; 1152 case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break; 1153 case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break; 1154 case objc_byref: Qual = ObjCDeclSpec::DQ_Byref; break; 1155 1156 case objc_nonnull: 1157 Qual = ObjCDeclSpec::DQ_CSNullability; 1158 Nullability = NullabilityKind::NonNull; 1159 break; 1160 1161 case objc_nullable: 1162 Qual = ObjCDeclSpec::DQ_CSNullability; 1163 Nullability = NullabilityKind::Nullable; 1164 break; 1165 1166 case objc_null_unspecified: 1167 Qual = ObjCDeclSpec::DQ_CSNullability; 1168 Nullability = NullabilityKind::Unspecified; 1169 break; 1170 } 1171 1172 // FIXME: Diagnose redundant specifiers. 1173 DS.setObjCDeclQualifier(Qual); 1174 if (Qual == ObjCDeclSpec::DQ_CSNullability) 1175 DS.setNullability(Tok.getLocation(), Nullability); 1176 1177 ConsumeToken(); 1178 II = nullptr; 1179 break; 1180 } 1181 1182 // If this wasn't a recognized qualifier, bail out. 1183 if (II) return; 1184 } 1185 } 1186 1187 /// Take all the decl attributes out of the given list and add 1188 /// them to the given attribute set. 1189 static void takeDeclAttributes(ParsedAttributes &attrs, 1190 AttributeList *list) { 1191 while (list) { 1192 AttributeList *cur = list; 1193 list = cur->getNext(); 1194 1195 if (!cur->isUsedAsTypeAttr()) { 1196 // Clear out the next pointer. We're really completely 1197 // destroying the internal invariants of the declarator here, 1198 // but it doesn't matter because we're done with it. 1199 cur->setNext(nullptr); 1200 attrs.add(cur); 1201 } 1202 } 1203 } 1204 1205 /// takeDeclAttributes - Take all the decl attributes from the given 1206 /// declarator and add them to the given list. 1207 static void takeDeclAttributes(ParsedAttributes &attrs, 1208 Declarator &D) { 1209 // First, take ownership of all attributes. 1210 attrs.getPool().takeAllFrom(D.getAttributePool()); 1211 attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool()); 1212 1213 // Now actually move the attributes over. 1214 takeDeclAttributes(attrs, D.getDeclSpec().getAttributes().getList()); 1215 takeDeclAttributes(attrs, D.getAttributes()); 1216 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 1217 takeDeclAttributes(attrs, 1218 const_cast<AttributeList*>(D.getTypeObject(i).getAttrs())); 1219 } 1220 1221 /// objc-type-name: 1222 /// '(' objc-type-qualifiers[opt] type-name ')' 1223 /// '(' objc-type-qualifiers[opt] ')' 1224 /// 1225 ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, 1226 Declarator::TheContext context, 1227 ParsedAttributes *paramAttrs) { 1228 assert(context == Declarator::ObjCParameterContext || 1229 context == Declarator::ObjCResultContext); 1230 assert((paramAttrs != nullptr) == 1231 (context == Declarator::ObjCParameterContext)); 1232 1233 assert(Tok.is(tok::l_paren) && "expected ("); 1234 1235 BalancedDelimiterTracker T(*this, tok::l_paren); 1236 T.consumeOpen(); 1237 1238 SourceLocation TypeStartLoc = Tok.getLocation(); 1239 ObjCDeclContextSwitch ObjCDC(*this); 1240 1241 // Parse type qualifiers, in, inout, etc. 1242 ParseObjCTypeQualifierList(DS, context); 1243 1244 ParsedType Ty; 1245 if (isTypeSpecifierQualifier() || isObjCInstancetype()) { 1246 // Parse an abstract declarator. 1247 DeclSpec declSpec(AttrFactory); 1248 declSpec.setObjCQualifiers(&DS); 1249 DeclSpecContext dsContext = DSC_normal; 1250 if (context == Declarator::ObjCResultContext) 1251 dsContext = DSC_objc_method_result; 1252 ParseSpecifierQualifierList(declSpec, AS_none, dsContext); 1253 declSpec.SetRangeEnd(Tok.getLocation()); 1254 Declarator declarator(declSpec, context); 1255 ParseDeclarator(declarator); 1256 1257 // If that's not invalid, extract a type. 1258 if (!declarator.isInvalidType()) { 1259 // Map a nullability specifier to a context-sensitive keyword attribute. 1260 bool addedToDeclSpec = false; 1261 if (DS.getObjCDeclQualifier() & ObjCDeclSpec::DQ_CSNullability) 1262 addContextSensitiveTypeNullability(*this, declarator, 1263 DS.getNullability(), 1264 DS.getNullabilityLoc(), 1265 addedToDeclSpec); 1266 1267 TypeResult type = Actions.ActOnTypeName(getCurScope(), declarator); 1268 if (!type.isInvalid()) 1269 Ty = type.get(); 1270 1271 // If we're parsing a parameter, steal all the decl attributes 1272 // and add them to the decl spec. 1273 if (context == Declarator::ObjCParameterContext) 1274 takeDeclAttributes(*paramAttrs, declarator); 1275 } 1276 } 1277 1278 if (Tok.is(tok::r_paren)) 1279 T.consumeClose(); 1280 else if (Tok.getLocation() == TypeStartLoc) { 1281 // If we didn't eat any tokens, then this isn't a type. 1282 Diag(Tok, diag::err_expected_type); 1283 SkipUntil(tok::r_paren, StopAtSemi); 1284 } else { 1285 // Otherwise, we found *something*, but didn't get a ')' in the right 1286 // place. Emit an error then return what we have as the type. 1287 T.consumeClose(); 1288 } 1289 return Ty; 1290 } 1291 1292 /// objc-method-decl: 1293 /// objc-selector 1294 /// objc-keyword-selector objc-parmlist[opt] 1295 /// objc-type-name objc-selector 1296 /// objc-type-name objc-keyword-selector objc-parmlist[opt] 1297 /// 1298 /// objc-keyword-selector: 1299 /// objc-keyword-decl 1300 /// objc-keyword-selector objc-keyword-decl 1301 /// 1302 /// objc-keyword-decl: 1303 /// objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier 1304 /// objc-selector ':' objc-keyword-attributes[opt] identifier 1305 /// ':' objc-type-name objc-keyword-attributes[opt] identifier 1306 /// ':' objc-keyword-attributes[opt] identifier 1307 /// 1308 /// objc-parmlist: 1309 /// objc-parms objc-ellipsis[opt] 1310 /// 1311 /// objc-parms: 1312 /// objc-parms , parameter-declaration 1313 /// 1314 /// objc-ellipsis: 1315 /// , ... 1316 /// 1317 /// objc-keyword-attributes: [OBJC2] 1318 /// __attribute__((unused)) 1319 /// 1320 Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, 1321 tok::TokenKind mType, 1322 tok::ObjCKeywordKind MethodImplKind, 1323 bool MethodDefinition) { 1324 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent); 1325 1326 if (Tok.is(tok::code_completion)) { 1327 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 1328 /*ReturnType=*/ ParsedType()); 1329 cutOffParsing(); 1330 return nullptr; 1331 } 1332 1333 // Parse the return type if present. 1334 ParsedType ReturnType; 1335 ObjCDeclSpec DSRet; 1336 if (Tok.is(tok::l_paren)) 1337 ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext, 1338 nullptr); 1339 1340 // If attributes exist before the method, parse them. 1341 ParsedAttributes methodAttrs(AttrFactory); 1342 if (getLangOpts().ObjC2) 1343 MaybeParseGNUAttributes(methodAttrs); 1344 1345 if (Tok.is(tok::code_completion)) { 1346 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 1347 ReturnType); 1348 cutOffParsing(); 1349 return nullptr; 1350 } 1351 1352 // Now parse the selector. 1353 SourceLocation selLoc; 1354 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc); 1355 1356 // An unnamed colon is valid. 1357 if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name. 1358 Diag(Tok, diag::err_expected_selector_for_method) 1359 << SourceRange(mLoc, Tok.getLocation()); 1360 // Skip until we get a ; or @. 1361 SkipUntil(tok::at, StopAtSemi | StopBeforeMatch); 1362 return nullptr; 1363 } 1364 1365 SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo; 1366 if (Tok.isNot(tok::colon)) { 1367 // If attributes exist after the method, parse them. 1368 if (getLangOpts().ObjC2) 1369 MaybeParseGNUAttributes(methodAttrs); 1370 1371 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); 1372 Decl *Result 1373 = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(), 1374 mType, DSRet, ReturnType, 1375 selLoc, Sel, nullptr, 1376 CParamInfo.data(), CParamInfo.size(), 1377 methodAttrs.getList(), MethodImplKind, 1378 false, MethodDefinition); 1379 PD.complete(Result); 1380 return Result; 1381 } 1382 1383 SmallVector<IdentifierInfo *, 12> KeyIdents; 1384 SmallVector<SourceLocation, 12> KeyLocs; 1385 SmallVector<Sema::ObjCArgInfo, 12> ArgInfos; 1386 ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | 1387 Scope::FunctionDeclarationScope | Scope::DeclScope); 1388 1389 AttributePool allParamAttrs(AttrFactory); 1390 while (1) { 1391 ParsedAttributes paramAttrs(AttrFactory); 1392 Sema::ObjCArgInfo ArgInfo; 1393 1394 // Each iteration parses a single keyword argument. 1395 if (ExpectAndConsume(tok::colon)) 1396 break; 1397 1398 ArgInfo.Type = ParsedType(); 1399 if (Tok.is(tok::l_paren)) // Parse the argument type if present. 1400 ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec, 1401 Declarator::ObjCParameterContext, 1402 ¶mAttrs); 1403 1404 // If attributes exist before the argument name, parse them. 1405 // Regardless, collect all the attributes we've parsed so far. 1406 ArgInfo.ArgAttrs = nullptr; 1407 if (getLangOpts().ObjC2) { 1408 MaybeParseGNUAttributes(paramAttrs); 1409 ArgInfo.ArgAttrs = paramAttrs.getList(); 1410 } 1411 1412 // Code completion for the next piece of the selector. 1413 if (Tok.is(tok::code_completion)) { 1414 KeyIdents.push_back(SelIdent); 1415 Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), 1416 mType == tok::minus, 1417 /*AtParameterName=*/true, 1418 ReturnType, KeyIdents); 1419 cutOffParsing(); 1420 return nullptr; 1421 } 1422 1423 if (Tok.isNot(tok::identifier)) { 1424 Diag(Tok, diag::err_expected) 1425 << tok::identifier; // missing argument name. 1426 break; 1427 } 1428 1429 ArgInfo.Name = Tok.getIdentifierInfo(); 1430 ArgInfo.NameLoc = Tok.getLocation(); 1431 ConsumeToken(); // Eat the identifier. 1432 1433 ArgInfos.push_back(ArgInfo); 1434 KeyIdents.push_back(SelIdent); 1435 KeyLocs.push_back(selLoc); 1436 1437 // Make sure the attributes persist. 1438 allParamAttrs.takeAllFrom(paramAttrs.getPool()); 1439 1440 // Code completion for the next piece of the selector. 1441 if (Tok.is(tok::code_completion)) { 1442 Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), 1443 mType == tok::minus, 1444 /*AtParameterName=*/false, 1445 ReturnType, KeyIdents); 1446 cutOffParsing(); 1447 return nullptr; 1448 } 1449 1450 // Check for another keyword selector. 1451 SelIdent = ParseObjCSelectorPiece(selLoc); 1452 if (!SelIdent && Tok.isNot(tok::colon)) 1453 break; 1454 if (!SelIdent) { 1455 SourceLocation ColonLoc = Tok.getLocation(); 1456 if (PP.getLocForEndOfToken(ArgInfo.NameLoc) == ColonLoc) { 1457 Diag(ArgInfo.NameLoc, diag::warn_missing_selector_name) << ArgInfo.Name; 1458 Diag(ArgInfo.NameLoc, diag::note_missing_selector_name) << ArgInfo.Name; 1459 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.Name; 1460 } 1461 } 1462 // We have a selector or a colon, continue parsing. 1463 } 1464 1465 bool isVariadic = false; 1466 bool cStyleParamWarned = false; 1467 // Parse the (optional) parameter list. 1468 while (Tok.is(tok::comma)) { 1469 ConsumeToken(); 1470 if (Tok.is(tok::ellipsis)) { 1471 isVariadic = true; 1472 ConsumeToken(); 1473 break; 1474 } 1475 if (!cStyleParamWarned) { 1476 Diag(Tok, diag::warn_cstyle_param); 1477 cStyleParamWarned = true; 1478 } 1479 DeclSpec DS(AttrFactory); 1480 ParseDeclarationSpecifiers(DS); 1481 // Parse the declarator. 1482 Declarator ParmDecl(DS, Declarator::PrototypeContext); 1483 ParseDeclarator(ParmDecl); 1484 IdentifierInfo *ParmII = ParmDecl.getIdentifier(); 1485 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); 1486 CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 1487 ParmDecl.getIdentifierLoc(), 1488 Param, 1489 nullptr)); 1490 } 1491 1492 // FIXME: Add support for optional parameter list... 1493 // If attributes exist after the method, parse them. 1494 if (getLangOpts().ObjC2) 1495 MaybeParseGNUAttributes(methodAttrs); 1496 1497 if (KeyIdents.size() == 0) 1498 return nullptr; 1499 1500 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), 1501 &KeyIdents[0]); 1502 Decl *Result 1503 = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(), 1504 mType, DSRet, ReturnType, 1505 KeyLocs, Sel, &ArgInfos[0], 1506 CParamInfo.data(), CParamInfo.size(), 1507 methodAttrs.getList(), 1508 MethodImplKind, isVariadic, MethodDefinition); 1509 1510 PD.complete(Result); 1511 return Result; 1512 } 1513 1514 /// objc-protocol-refs: 1515 /// '<' identifier-list '>' 1516 /// 1517 bool Parser:: 1518 ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols, 1519 SmallVectorImpl<SourceLocation> &ProtocolLocs, 1520 bool WarnOnDeclarations, bool ForObjCContainer, 1521 SourceLocation &LAngleLoc, SourceLocation &EndLoc, 1522 bool consumeLastToken) { 1523 assert(Tok.is(tok::less) && "expected <"); 1524 1525 LAngleLoc = ConsumeToken(); // the "<" 1526 1527 SmallVector<IdentifierLocPair, 8> ProtocolIdents; 1528 1529 while (1) { 1530 if (Tok.is(tok::code_completion)) { 1531 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(), 1532 ProtocolIdents.size()); 1533 cutOffParsing(); 1534 return true; 1535 } 1536 1537 if (Tok.isNot(tok::identifier)) { 1538 Diag(Tok, diag::err_expected) << tok::identifier; 1539 SkipUntil(tok::greater, StopAtSemi); 1540 return true; 1541 } 1542 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(), 1543 Tok.getLocation())); 1544 ProtocolLocs.push_back(Tok.getLocation()); 1545 ConsumeToken(); 1546 1547 if (!TryConsumeToken(tok::comma)) 1548 break; 1549 } 1550 1551 // Consume the '>'. 1552 if (ParseGreaterThanInTemplateList(EndLoc, consumeLastToken, 1553 /*ObjCGenericList=*/false)) 1554 return true; 1555 1556 // Convert the list of protocols identifiers into a list of protocol decls. 1557 Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer, 1558 &ProtocolIdents[0], ProtocolIdents.size(), 1559 Protocols); 1560 return false; 1561 } 1562 1563 TypeResult Parser::parseObjCProtocolQualifierType(SourceLocation &rAngleLoc) { 1564 assert(Tok.is(tok::less) && "Protocol qualifiers start with '<'"); 1565 assert(getLangOpts().ObjC1 && "Protocol qualifiers only exist in Objective-C"); 1566 1567 SourceLocation lAngleLoc; 1568 SmallVector<Decl *, 8> protocols; 1569 SmallVector<SourceLocation, 8> protocolLocs; 1570 (void)ParseObjCProtocolReferences(protocols, protocolLocs, false, false, 1571 lAngleLoc, rAngleLoc, 1572 /*consumeLastToken=*/true); 1573 TypeResult result = Actions.actOnObjCProtocolQualifierType(lAngleLoc, 1574 protocols, 1575 protocolLocs, 1576 rAngleLoc); 1577 if (result.isUsable()) { 1578 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id) 1579 << FixItHint::CreateInsertion(lAngleLoc, "id") 1580 << SourceRange(lAngleLoc, rAngleLoc); 1581 } 1582 1583 return result; 1584 } 1585 1586 /// Parse Objective-C type arguments or protocol qualifiers. 1587 /// 1588 /// objc-type-arguments: 1589 /// '<' type-name '...'[opt] (',' type-name '...'[opt])* '>' 1590 /// 1591 void Parser::parseObjCTypeArgsOrProtocolQualifiers( 1592 SourceLocation &typeArgsLAngleLoc, 1593 SmallVectorImpl<ParsedType> &typeArgs, 1594 SourceLocation &typeArgsRAngleLoc, 1595 SourceLocation &protocolLAngleLoc, 1596 SmallVectorImpl<Decl *> &protocols, 1597 SmallVectorImpl<SourceLocation> &protocolLocs, 1598 SourceLocation &protocolRAngleLoc, 1599 bool consumeLastToken, 1600 bool warnOnIncompleteProtocols) { 1601 assert(Tok.is(tok::less) && "Not at the start of type args or protocols"); 1602 SourceLocation lAngleLoc = ConsumeToken(); 1603 1604 // Whether all of the elements we've parsed thus far are single 1605 // identifiers, which might be types or might be protocols. 1606 bool allSingleIdentifiers = true; 1607 SmallVector<IdentifierInfo *, 4> identifiers; 1608 SmallVectorImpl<SourceLocation> &identifierLocs = protocolLocs; 1609 1610 // Parse a list of comma-separated identifiers, bailing out if we 1611 // see something different. 1612 do { 1613 // Parse a single identifier. 1614 if (Tok.is(tok::identifier) && 1615 (NextToken().is(tok::comma) || 1616 NextToken().is(tok::greater) || 1617 NextToken().is(tok::greatergreater))) { 1618 identifiers.push_back(Tok.getIdentifierInfo()); 1619 identifierLocs.push_back(ConsumeToken()); 1620 continue; 1621 } 1622 1623 if (Tok.is(tok::code_completion)) { 1624 // FIXME: Also include types here. 1625 SmallVector<IdentifierLocPair, 4> identifierLocPairs; 1626 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { 1627 identifierLocPairs.push_back(IdentifierLocPair(identifiers[i], 1628 identifierLocs[i])); 1629 } 1630 1631 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs.data(), 1632 identifierLocPairs.size()); 1633 cutOffParsing(); 1634 return; 1635 } 1636 1637 allSingleIdentifiers = false; 1638 break; 1639 } while (TryConsumeToken(tok::comma)); 1640 1641 // If we parsed an identifier list, semantic analysis sorts out 1642 // whether it refers to protocols or to type arguments. 1643 if (allSingleIdentifiers) { 1644 // Parse the closing '>'. 1645 SourceLocation rAngleLoc; 1646 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken, 1647 /*ObjCGenericList=*/true); 1648 1649 // Let Sema figure out what we parsed. 1650 Actions.actOnObjCTypeArgsOrProtocolQualifiers(getCurScope(), 1651 lAngleLoc, 1652 identifiers, 1653 identifierLocs, 1654 rAngleLoc, 1655 typeArgsLAngleLoc, 1656 typeArgs, 1657 typeArgsRAngleLoc, 1658 protocolLAngleLoc, 1659 protocols, 1660 protocolRAngleLoc, 1661 warnOnIncompleteProtocols); 1662 return; 1663 } 1664 1665 // We syntactically matched a type argument, so commit to parsing 1666 // type arguments. 1667 1668 // Convert the identifiers into type arguments. 1669 bool invalid = false; 1670 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) { 1671 ParsedType typeArg 1672 = Actions.getTypeName(*identifiers[i], identifierLocs[i], getCurScope()); 1673 if (typeArg) { 1674 DeclSpec DS(AttrFactory); 1675 const char *prevSpec = nullptr; 1676 unsigned diagID; 1677 DS.SetTypeSpecType(TST_typename, identifierLocs[i], prevSpec, diagID, 1678 typeArg, Actions.getASTContext().getPrintingPolicy()); 1679 1680 // Form a declarator to turn this into a type. 1681 Declarator D(DS, Declarator::TypeNameContext); 1682 TypeResult fullTypeArg = Actions.ActOnTypeName(getCurScope(), D); 1683 if (fullTypeArg.isUsable()) 1684 typeArgs.push_back(fullTypeArg.get()); 1685 else 1686 invalid = true; 1687 } else { 1688 invalid = true; 1689 } 1690 } 1691 1692 // Continue parsing type-names. 1693 do { 1694 TypeResult typeArg = ParseTypeName(); 1695 1696 // Consume the '...' for a pack expansion. 1697 SourceLocation ellipsisLoc; 1698 TryConsumeToken(tok::ellipsis, ellipsisLoc); 1699 if (typeArg.isUsable() && ellipsisLoc.isValid()) { 1700 typeArg = Actions.ActOnPackExpansion(typeArg.get(), ellipsisLoc); 1701 } 1702 1703 if (typeArg.isUsable()) { 1704 typeArgs.push_back(typeArg.get()); 1705 } else { 1706 invalid = true; 1707 } 1708 } while (TryConsumeToken(tok::comma)); 1709 1710 // Parse the closing '>'. 1711 SourceLocation rAngleLoc; 1712 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken, 1713 /*ObjCGenericList=*/true); 1714 1715 if (invalid) { 1716 typeArgs.clear(); 1717 return; 1718 } 1719 1720 // Record left/right angle locations. 1721 typeArgsLAngleLoc = lAngleLoc; 1722 typeArgsRAngleLoc = rAngleLoc; 1723 } 1724 1725 void Parser::parseObjCTypeArgsAndProtocolQualifiers( 1726 SourceLocation &typeArgsLAngleLoc, 1727 SmallVectorImpl<ParsedType> &typeArgs, 1728 SourceLocation &typeArgsRAngleLoc, 1729 SourceLocation &protocolLAngleLoc, 1730 SmallVectorImpl<Decl *> &protocols, 1731 SmallVectorImpl<SourceLocation> &protocolLocs, 1732 SourceLocation &protocolRAngleLoc, 1733 bool consumeLastToken) { 1734 assert(Tok.is(tok::less)); 1735 1736 // Parse the first angle-bracket-delimited clause. 1737 parseObjCTypeArgsOrProtocolQualifiers(typeArgsLAngleLoc, 1738 typeArgs, 1739 typeArgsRAngleLoc, 1740 protocolLAngleLoc, 1741 protocols, 1742 protocolLocs, 1743 protocolRAngleLoc, 1744 consumeLastToken, 1745 /*warnOnIncompleteProtocols=*/false); 1746 1747 // An Objective-C object pointer followed by type arguments 1748 // can then be followed again by a set of protocol references, e.g., 1749 // \c NSArray<NSView><NSTextDelegate> 1750 if ((consumeLastToken && Tok.is(tok::less)) || 1751 (!consumeLastToken && NextToken().is(tok::less))) { 1752 // If we aren't consuming the last token, the prior '>' is still hanging 1753 // there. Consume it before we parse the protocol qualifiers. 1754 if (!consumeLastToken) 1755 ConsumeToken(); 1756 1757 if (!protocols.empty()) { 1758 SkipUntilFlags skipFlags = SkipUntilFlags(); 1759 if (!consumeLastToken) 1760 skipFlags = skipFlags | StopBeforeMatch; 1761 Diag(Tok, diag::err_objc_type_args_after_protocols) 1762 << SourceRange(protocolLAngleLoc, protocolRAngleLoc); 1763 SkipUntil(tok::greater, tok::greatergreater, skipFlags); 1764 } else { 1765 ParseObjCProtocolReferences(protocols, protocolLocs, 1766 /*WarnOnDeclarations=*/false, 1767 /*ForObjCContainer=*/false, 1768 protocolLAngleLoc, protocolRAngleLoc, 1769 consumeLastToken); 1770 } 1771 } 1772 } 1773 1774 TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers( 1775 SourceLocation loc, 1776 ParsedType type, 1777 bool consumeLastToken, 1778 SourceLocation &endLoc) { 1779 assert(Tok.is(tok::less)); 1780 SourceLocation typeArgsLAngleLoc; 1781 SmallVector<ParsedType, 4> typeArgs; 1782 SourceLocation typeArgsRAngleLoc; 1783 SourceLocation protocolLAngleLoc; 1784 SmallVector<Decl *, 4> protocols; 1785 SmallVector<SourceLocation, 4> protocolLocs; 1786 SourceLocation protocolRAngleLoc; 1787 1788 // Parse type arguments and protocol qualifiers. 1789 parseObjCTypeArgsAndProtocolQualifiers(typeArgsLAngleLoc, typeArgs, 1790 typeArgsRAngleLoc, protocolLAngleLoc, 1791 protocols, protocolLocs, 1792 protocolRAngleLoc, consumeLastToken); 1793 1794 // Compute the location of the last token. 1795 if (consumeLastToken) 1796 endLoc = PrevTokLocation; 1797 else 1798 endLoc = Tok.getLocation(); 1799 1800 return Actions.actOnObjCTypeArgsAndProtocolQualifiers( 1801 getCurScope(), 1802 loc, 1803 type, 1804 typeArgsLAngleLoc, 1805 typeArgs, 1806 typeArgsRAngleLoc, 1807 protocolLAngleLoc, 1808 protocols, 1809 protocolLocs, 1810 protocolRAngleLoc); 1811 } 1812 1813 void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc, 1814 BalancedDelimiterTracker &T, 1815 SmallVectorImpl<Decl *> &AllIvarDecls, 1816 bool RBraceMissing) { 1817 if (!RBraceMissing) 1818 T.consumeClose(); 1819 1820 Actions.ActOnObjCContainerStartDefinition(interfaceDecl); 1821 Actions.ActOnLastBitfield(T.getCloseLocation(), AllIvarDecls); 1822 Actions.ActOnObjCContainerFinishDefinition(); 1823 // Call ActOnFields() even if we don't have any decls. This is useful 1824 // for code rewriting tools that need to be aware of the empty list. 1825 Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, 1826 AllIvarDecls, 1827 T.getOpenLocation(), T.getCloseLocation(), nullptr); 1828 } 1829 1830 /// objc-class-instance-variables: 1831 /// '{' objc-instance-variable-decl-list[opt] '}' 1832 /// 1833 /// objc-instance-variable-decl-list: 1834 /// objc-visibility-spec 1835 /// objc-instance-variable-decl ';' 1836 /// ';' 1837 /// objc-instance-variable-decl-list objc-visibility-spec 1838 /// objc-instance-variable-decl-list objc-instance-variable-decl ';' 1839 /// objc-instance-variable-decl-list ';' 1840 /// 1841 /// objc-visibility-spec: 1842 /// @private 1843 /// @protected 1844 /// @public 1845 /// @package [OBJC2] 1846 /// 1847 /// objc-instance-variable-decl: 1848 /// struct-declaration 1849 /// 1850 void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl, 1851 tok::ObjCKeywordKind visibility, 1852 SourceLocation atLoc) { 1853 assert(Tok.is(tok::l_brace) && "expected {"); 1854 SmallVector<Decl *, 32> AllIvarDecls; 1855 1856 ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope); 1857 ObjCDeclContextSwitch ObjCDC(*this); 1858 1859 BalancedDelimiterTracker T(*this, tok::l_brace); 1860 T.consumeOpen(); 1861 // While we still have something to read, read the instance variables. 1862 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { 1863 // Each iteration of this loop reads one objc-instance-variable-decl. 1864 1865 // Check for extraneous top-level semicolon. 1866 if (Tok.is(tok::semi)) { 1867 ConsumeExtraSemi(InstanceVariableList); 1868 continue; 1869 } 1870 1871 // Set the default visibility to private. 1872 if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec 1873 if (Tok.is(tok::code_completion)) { 1874 Actions.CodeCompleteObjCAtVisibility(getCurScope()); 1875 return cutOffParsing(); 1876 } 1877 1878 switch (Tok.getObjCKeywordID()) { 1879 case tok::objc_private: 1880 case tok::objc_public: 1881 case tok::objc_protected: 1882 case tok::objc_package: 1883 visibility = Tok.getObjCKeywordID(); 1884 ConsumeToken(); 1885 continue; 1886 1887 case tok::objc_end: 1888 Diag(Tok, diag::err_objc_unexpected_atend); 1889 Tok.setLocation(Tok.getLocation().getLocWithOffset(-1)); 1890 Tok.setKind(tok::at); 1891 Tok.setLength(1); 1892 PP.EnterToken(Tok); 1893 HelperActionsForIvarDeclarations(interfaceDecl, atLoc, 1894 T, AllIvarDecls, true); 1895 return; 1896 1897 default: 1898 Diag(Tok, diag::err_objc_illegal_visibility_spec); 1899 continue; 1900 } 1901 } 1902 1903 if (Tok.is(tok::code_completion)) { 1904 Actions.CodeCompleteOrdinaryName(getCurScope(), 1905 Sema::PCC_ObjCInstanceVariableList); 1906 return cutOffParsing(); 1907 } 1908 1909 auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) { 1910 Actions.ActOnObjCContainerStartDefinition(interfaceDecl); 1911 // Install the declarator into the interface decl. 1912 FD.D.setObjCIvar(true); 1913 Decl *Field = Actions.ActOnIvar( 1914 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D, 1915 FD.BitfieldSize, visibility); 1916 Actions.ActOnObjCContainerFinishDefinition(); 1917 if (Field) 1918 AllIvarDecls.push_back(Field); 1919 FD.complete(Field); 1920 }; 1921 1922 // Parse all the comma separated declarators. 1923 ParsingDeclSpec DS(*this); 1924 ParseStructDeclaration(DS, ObjCIvarCallback); 1925 1926 if (Tok.is(tok::semi)) { 1927 ConsumeToken(); 1928 } else { 1929 Diag(Tok, diag::err_expected_semi_decl_list); 1930 // Skip to end of block or statement 1931 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); 1932 } 1933 } 1934 HelperActionsForIvarDeclarations(interfaceDecl, atLoc, 1935 T, AllIvarDecls, false); 1936 return; 1937 } 1938 1939 /// objc-protocol-declaration: 1940 /// objc-protocol-definition 1941 /// objc-protocol-forward-reference 1942 /// 1943 /// objc-protocol-definition: 1944 /// \@protocol identifier 1945 /// objc-protocol-refs[opt] 1946 /// objc-interface-decl-list 1947 /// \@end 1948 /// 1949 /// objc-protocol-forward-reference: 1950 /// \@protocol identifier-list ';' 1951 /// 1952 /// "\@protocol identifier ;" should be resolved as "\@protocol 1953 /// identifier-list ;": objc-interface-decl-list may not start with a 1954 /// semicolon in the first alternative if objc-protocol-refs are omitted. 1955 Parser::DeclGroupPtrTy 1956 Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, 1957 ParsedAttributes &attrs) { 1958 assert(Tok.isObjCAtKeyword(tok::objc_protocol) && 1959 "ParseObjCAtProtocolDeclaration(): Expected @protocol"); 1960 ConsumeToken(); // the "protocol" identifier 1961 1962 if (Tok.is(tok::code_completion)) { 1963 Actions.CodeCompleteObjCProtocolDecl(getCurScope()); 1964 cutOffParsing(); 1965 return DeclGroupPtrTy(); 1966 } 1967 1968 MaybeSkipAttributes(tok::objc_protocol); 1969 1970 if (Tok.isNot(tok::identifier)) { 1971 Diag(Tok, diag::err_expected) << tok::identifier; // missing protocol name. 1972 return DeclGroupPtrTy(); 1973 } 1974 // Save the protocol name, then consume it. 1975 IdentifierInfo *protocolName = Tok.getIdentifierInfo(); 1976 SourceLocation nameLoc = ConsumeToken(); 1977 1978 if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol. 1979 IdentifierLocPair ProtoInfo(protocolName, nameLoc); 1980 return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1, 1981 attrs.getList()); 1982 } 1983 1984 CheckNestedObjCContexts(AtLoc); 1985 1986 if (Tok.is(tok::comma)) { // list of forward declarations. 1987 SmallVector<IdentifierLocPair, 8> ProtocolRefs; 1988 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc)); 1989 1990 // Parse the list of forward declarations. 1991 while (1) { 1992 ConsumeToken(); // the ',' 1993 if (Tok.isNot(tok::identifier)) { 1994 Diag(Tok, diag::err_expected) << tok::identifier; 1995 SkipUntil(tok::semi); 1996 return DeclGroupPtrTy(); 1997 } 1998 ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(), 1999 Tok.getLocation())); 2000 ConsumeToken(); // the identifier 2001 2002 if (Tok.isNot(tok::comma)) 2003 break; 2004 } 2005 // Consume the ';'. 2006 if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol")) 2007 return DeclGroupPtrTy(); 2008 2009 return Actions.ActOnForwardProtocolDeclaration(AtLoc, 2010 &ProtocolRefs[0], 2011 ProtocolRefs.size(), 2012 attrs.getList()); 2013 } 2014 2015 // Last, and definitely not least, parse a protocol declaration. 2016 SourceLocation LAngleLoc, EndProtoLoc; 2017 2018 SmallVector<Decl *, 8> ProtocolRefs; 2019 SmallVector<SourceLocation, 8> ProtocolLocs; 2020 if (Tok.is(tok::less) && 2021 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, true, 2022 LAngleLoc, EndProtoLoc, 2023 /*consumeLastToken=*/true)) 2024 return DeclGroupPtrTy(); 2025 2026 Decl *ProtoType = 2027 Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, 2028 ProtocolRefs.data(), 2029 ProtocolRefs.size(), 2030 ProtocolLocs.data(), 2031 EndProtoLoc, attrs.getList()); 2032 2033 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType); 2034 return Actions.ConvertDeclToDeclGroup(ProtoType); 2035 } 2036 2037 /// objc-implementation: 2038 /// objc-class-implementation-prologue 2039 /// objc-category-implementation-prologue 2040 /// 2041 /// objc-class-implementation-prologue: 2042 /// @implementation identifier objc-superclass[opt] 2043 /// objc-class-instance-variables[opt] 2044 /// 2045 /// objc-category-implementation-prologue: 2046 /// @implementation identifier ( identifier ) 2047 Parser::DeclGroupPtrTy 2048 Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) { 2049 assert(Tok.isObjCAtKeyword(tok::objc_implementation) && 2050 "ParseObjCAtImplementationDeclaration(): Expected @implementation"); 2051 CheckNestedObjCContexts(AtLoc); 2052 ConsumeToken(); // the "implementation" identifier 2053 2054 // Code completion after '@implementation'. 2055 if (Tok.is(tok::code_completion)) { 2056 Actions.CodeCompleteObjCImplementationDecl(getCurScope()); 2057 cutOffParsing(); 2058 return DeclGroupPtrTy(); 2059 } 2060 2061 MaybeSkipAttributes(tok::objc_implementation); 2062 2063 if (Tok.isNot(tok::identifier)) { 2064 Diag(Tok, diag::err_expected) 2065 << tok::identifier; // missing class or category name. 2066 return DeclGroupPtrTy(); 2067 } 2068 // We have a class or category name - consume it. 2069 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 2070 SourceLocation nameLoc = ConsumeToken(); // consume class or category name 2071 Decl *ObjCImpDecl = nullptr; 2072 2073 // Neither a type parameter list nor a list of protocol references is 2074 // permitted here. Parse and diagnose them. 2075 if (Tok.is(tok::less)) { 2076 SourceLocation lAngleLoc, rAngleLoc; 2077 SmallVector<IdentifierLocPair, 8> protocolIdents; 2078 SourceLocation diagLoc = Tok.getLocation(); 2079 if (parseObjCTypeParamListOrProtocolRefs(lAngleLoc, protocolIdents, 2080 rAngleLoc)) { 2081 Diag(diagLoc, diag::err_objc_parameterized_implementation) 2082 << SourceRange(diagLoc, PrevTokLocation); 2083 } else if (lAngleLoc.isValid()) { 2084 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier) 2085 << FixItHint::CreateRemoval(SourceRange(lAngleLoc, rAngleLoc)); 2086 } 2087 } 2088 2089 if (Tok.is(tok::l_paren)) { 2090 // we have a category implementation. 2091 ConsumeParen(); 2092 SourceLocation categoryLoc, rparenLoc; 2093 IdentifierInfo *categoryId = nullptr; 2094 2095 if (Tok.is(tok::code_completion)) { 2096 Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc); 2097 cutOffParsing(); 2098 return DeclGroupPtrTy(); 2099 } 2100 2101 if (Tok.is(tok::identifier)) { 2102 categoryId = Tok.getIdentifierInfo(); 2103 categoryLoc = ConsumeToken(); 2104 } else { 2105 Diag(Tok, diag::err_expected) 2106 << tok::identifier; // missing category name. 2107 return DeclGroupPtrTy(); 2108 } 2109 if (Tok.isNot(tok::r_paren)) { 2110 Diag(Tok, diag::err_expected) << tok::r_paren; 2111 SkipUntil(tok::r_paren); // don't stop at ';' 2112 return DeclGroupPtrTy(); 2113 } 2114 rparenLoc = ConsumeParen(); 2115 if (Tok.is(tok::less)) { // we have illegal '<' try to recover 2116 Diag(Tok, diag::err_unexpected_protocol_qualifier); 2117 SourceLocation protocolLAngleLoc, protocolRAngleLoc; 2118 SmallVector<Decl *, 4> protocols; 2119 SmallVector<SourceLocation, 4> protocolLocs; 2120 (void)ParseObjCProtocolReferences(protocols, protocolLocs, 2121 /*warnOnIncompleteProtocols=*/false, 2122 /*ForObjCContainer=*/false, 2123 protocolLAngleLoc, protocolRAngleLoc, 2124 /*consumeLastToken=*/true); 2125 } 2126 ObjCImpDecl = Actions.ActOnStartCategoryImplementation( 2127 AtLoc, nameId, nameLoc, categoryId, 2128 categoryLoc); 2129 2130 } else { 2131 // We have a class implementation 2132 SourceLocation superClassLoc; 2133 IdentifierInfo *superClassId = nullptr; 2134 if (TryConsumeToken(tok::colon)) { 2135 // We have a super class 2136 if (Tok.isNot(tok::identifier)) { 2137 Diag(Tok, diag::err_expected) 2138 << tok::identifier; // missing super class name. 2139 return DeclGroupPtrTy(); 2140 } 2141 superClassId = Tok.getIdentifierInfo(); 2142 superClassLoc = ConsumeToken(); // Consume super class name 2143 } 2144 ObjCImpDecl = Actions.ActOnStartClassImplementation( 2145 AtLoc, nameId, nameLoc, 2146 superClassId, superClassLoc); 2147 2148 if (Tok.is(tok::l_brace)) // we have ivars 2149 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc); 2150 else if (Tok.is(tok::less)) { // we have illegal '<' try to recover 2151 Diag(Tok, diag::err_unexpected_protocol_qualifier); 2152 2153 SourceLocation protocolLAngleLoc, protocolRAngleLoc; 2154 SmallVector<Decl *, 4> protocols; 2155 SmallVector<SourceLocation, 4> protocolLocs; 2156 (void)ParseObjCProtocolReferences(protocols, protocolLocs, 2157 /*warnOnIncompleteProtocols=*/false, 2158 /*ForObjCContainer=*/false, 2159 protocolLAngleLoc, protocolRAngleLoc, 2160 /*consumeLastToken=*/true); 2161 } 2162 } 2163 assert(ObjCImpDecl); 2164 2165 SmallVector<Decl *, 8> DeclsInGroup; 2166 2167 { 2168 ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl); 2169 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) { 2170 ParsedAttributesWithRange attrs(AttrFactory); 2171 MaybeParseCXX11Attributes(attrs); 2172 MaybeParseMicrosoftAttributes(attrs); 2173 if (DeclGroupPtrTy DGP = ParseExternalDeclaration(attrs)) { 2174 DeclGroupRef DG = DGP.get(); 2175 DeclsInGroup.append(DG.begin(), DG.end()); 2176 } 2177 } 2178 } 2179 2180 return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup); 2181 } 2182 2183 Parser::DeclGroupPtrTy 2184 Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) { 2185 assert(Tok.isObjCAtKeyword(tok::objc_end) && 2186 "ParseObjCAtEndDeclaration(): Expected @end"); 2187 ConsumeToken(); // the "end" identifier 2188 if (CurParsedObjCImpl) 2189 CurParsedObjCImpl->finish(atEnd); 2190 else 2191 // missing @implementation 2192 Diag(atEnd.getBegin(), diag::err_expected_objc_container); 2193 return DeclGroupPtrTy(); 2194 } 2195 2196 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() { 2197 if (!Finished) { 2198 finish(P.Tok.getLocation()); 2199 if (P.isEofOrEom()) { 2200 P.Diag(P.Tok, diag::err_objc_missing_end) 2201 << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n@end\n"); 2202 P.Diag(Dcl->getLocStart(), diag::note_objc_container_start) 2203 << Sema::OCK_Implementation; 2204 } 2205 } 2206 P.CurParsedObjCImpl = nullptr; 2207 assert(LateParsedObjCMethods.empty()); 2208 } 2209 2210 void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) { 2211 assert(!Finished); 2212 P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl); 2213 for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i) 2214 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], 2215 true/*Methods*/); 2216 2217 P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd); 2218 2219 if (HasCFunction) 2220 for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i) 2221 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], 2222 false/*c-functions*/); 2223 2224 /// \brief Clear and free the cached objc methods. 2225 for (LateParsedObjCMethodContainer::iterator 2226 I = LateParsedObjCMethods.begin(), 2227 E = LateParsedObjCMethods.end(); I != E; ++I) 2228 delete *I; 2229 LateParsedObjCMethods.clear(); 2230 2231 Finished = true; 2232 } 2233 2234 /// compatibility-alias-decl: 2235 /// @compatibility_alias alias-name class-name ';' 2236 /// 2237 Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { 2238 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) && 2239 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias"); 2240 ConsumeToken(); // consume compatibility_alias 2241 if (Tok.isNot(tok::identifier)) { 2242 Diag(Tok, diag::err_expected) << tok::identifier; 2243 return nullptr; 2244 } 2245 IdentifierInfo *aliasId = Tok.getIdentifierInfo(); 2246 SourceLocation aliasLoc = ConsumeToken(); // consume alias-name 2247 if (Tok.isNot(tok::identifier)) { 2248 Diag(Tok, diag::err_expected) << tok::identifier; 2249 return nullptr; 2250 } 2251 IdentifierInfo *classId = Tok.getIdentifierInfo(); 2252 SourceLocation classLoc = ConsumeToken(); // consume class-name; 2253 ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias"); 2254 return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc, 2255 classId, classLoc); 2256 } 2257 2258 /// property-synthesis: 2259 /// @synthesize property-ivar-list ';' 2260 /// 2261 /// property-ivar-list: 2262 /// property-ivar 2263 /// property-ivar-list ',' property-ivar 2264 /// 2265 /// property-ivar: 2266 /// identifier 2267 /// identifier '=' identifier 2268 /// 2269 Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { 2270 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) && 2271 "ParseObjCPropertySynthesize(): Expected '@synthesize'"); 2272 ConsumeToken(); // consume synthesize 2273 2274 while (true) { 2275 if (Tok.is(tok::code_completion)) { 2276 Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); 2277 cutOffParsing(); 2278 return nullptr; 2279 } 2280 2281 if (Tok.isNot(tok::identifier)) { 2282 Diag(Tok, diag::err_synthesized_property_name); 2283 SkipUntil(tok::semi); 2284 return nullptr; 2285 } 2286 2287 IdentifierInfo *propertyIvar = nullptr; 2288 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 2289 SourceLocation propertyLoc = ConsumeToken(); // consume property name 2290 SourceLocation propertyIvarLoc; 2291 if (TryConsumeToken(tok::equal)) { 2292 // property '=' ivar-name 2293 if (Tok.is(tok::code_completion)) { 2294 Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId); 2295 cutOffParsing(); 2296 return nullptr; 2297 } 2298 2299 if (Tok.isNot(tok::identifier)) { 2300 Diag(Tok, diag::err_expected) << tok::identifier; 2301 break; 2302 } 2303 propertyIvar = Tok.getIdentifierInfo(); 2304 propertyIvarLoc = ConsumeToken(); // consume ivar-name 2305 } 2306 Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, 2307 propertyId, propertyIvar, propertyIvarLoc); 2308 if (Tok.isNot(tok::comma)) 2309 break; 2310 ConsumeToken(); // consume ',' 2311 } 2312 ExpectAndConsume(tok::semi, diag::err_expected_after, "@synthesize"); 2313 return nullptr; 2314 } 2315 2316 /// property-dynamic: 2317 /// @dynamic property-list 2318 /// 2319 /// property-list: 2320 /// identifier 2321 /// property-list ',' identifier 2322 /// 2323 Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { 2324 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) && 2325 "ParseObjCPropertyDynamic(): Expected '@dynamic'"); 2326 ConsumeToken(); // consume dynamic 2327 while (true) { 2328 if (Tok.is(tok::code_completion)) { 2329 Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); 2330 cutOffParsing(); 2331 return nullptr; 2332 } 2333 2334 if (Tok.isNot(tok::identifier)) { 2335 Diag(Tok, diag::err_expected) << tok::identifier; 2336 SkipUntil(tok::semi); 2337 return nullptr; 2338 } 2339 2340 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 2341 SourceLocation propertyLoc = ConsumeToken(); // consume property name 2342 Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, 2343 propertyId, nullptr, SourceLocation()); 2344 2345 if (Tok.isNot(tok::comma)) 2346 break; 2347 ConsumeToken(); // consume ',' 2348 } 2349 ExpectAndConsume(tok::semi, diag::err_expected_after, "@dynamic"); 2350 return nullptr; 2351 } 2352 2353 /// objc-throw-statement: 2354 /// throw expression[opt]; 2355 /// 2356 StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { 2357 ExprResult Res; 2358 ConsumeToken(); // consume throw 2359 if (Tok.isNot(tok::semi)) { 2360 Res = ParseExpression(); 2361 if (Res.isInvalid()) { 2362 SkipUntil(tok::semi); 2363 return StmtError(); 2364 } 2365 } 2366 // consume ';' 2367 ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw"); 2368 return Actions.ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope()); 2369 } 2370 2371 /// objc-synchronized-statement: 2372 /// @synchronized '(' expression ')' compound-statement 2373 /// 2374 StmtResult 2375 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { 2376 ConsumeToken(); // consume synchronized 2377 if (Tok.isNot(tok::l_paren)) { 2378 Diag(Tok, diag::err_expected_lparen_after) << "@synchronized"; 2379 return StmtError(); 2380 } 2381 2382 // The operand is surrounded with parentheses. 2383 ConsumeParen(); // '(' 2384 ExprResult operand(ParseExpression()); 2385 2386 if (Tok.is(tok::r_paren)) { 2387 ConsumeParen(); // ')' 2388 } else { 2389 if (!operand.isInvalid()) 2390 Diag(Tok, diag::err_expected) << tok::r_paren; 2391 2392 // Skip forward until we see a left brace, but don't consume it. 2393 SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch); 2394 } 2395 2396 // Require a compound statement. 2397 if (Tok.isNot(tok::l_brace)) { 2398 if (!operand.isInvalid()) 2399 Diag(Tok, diag::err_expected) << tok::l_brace; 2400 return StmtError(); 2401 } 2402 2403 // Check the @synchronized operand now. 2404 if (!operand.isInvalid()) 2405 operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.get()); 2406 2407 // Parse the compound statement within a new scope. 2408 ParseScope bodyScope(this, Scope::DeclScope); 2409 StmtResult body(ParseCompoundStatementBody()); 2410 bodyScope.Exit(); 2411 2412 // If there was a semantic or parse error earlier with the 2413 // operand, fail now. 2414 if (operand.isInvalid()) 2415 return StmtError(); 2416 2417 if (body.isInvalid()) 2418 body = Actions.ActOnNullStmt(Tok.getLocation()); 2419 2420 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get()); 2421 } 2422 2423 /// objc-try-catch-statement: 2424 /// @try compound-statement objc-catch-list[opt] 2425 /// @try compound-statement objc-catch-list[opt] @finally compound-statement 2426 /// 2427 /// objc-catch-list: 2428 /// @catch ( parameter-declaration ) compound-statement 2429 /// objc-catch-list @catch ( catch-parameter-declaration ) compound-statement 2430 /// catch-parameter-declaration: 2431 /// parameter-declaration 2432 /// '...' [OBJC2] 2433 /// 2434 StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { 2435 bool catch_or_finally_seen = false; 2436 2437 ConsumeToken(); // consume try 2438 if (Tok.isNot(tok::l_brace)) { 2439 Diag(Tok, diag::err_expected) << tok::l_brace; 2440 return StmtError(); 2441 } 2442 StmtVector CatchStmts; 2443 StmtResult FinallyStmt; 2444 ParseScope TryScope(this, Scope::DeclScope); 2445 StmtResult TryBody(ParseCompoundStatementBody()); 2446 TryScope.Exit(); 2447 if (TryBody.isInvalid()) 2448 TryBody = Actions.ActOnNullStmt(Tok.getLocation()); 2449 2450 while (Tok.is(tok::at)) { 2451 // At this point, we need to lookahead to determine if this @ is the start 2452 // of an @catch or @finally. We don't want to consume the @ token if this 2453 // is an @try or @encode or something else. 2454 Token AfterAt = GetLookAheadToken(1); 2455 if (!AfterAt.isObjCAtKeyword(tok::objc_catch) && 2456 !AfterAt.isObjCAtKeyword(tok::objc_finally)) 2457 break; 2458 2459 SourceLocation AtCatchFinallyLoc = ConsumeToken(); 2460 if (Tok.isObjCAtKeyword(tok::objc_catch)) { 2461 Decl *FirstPart = nullptr; 2462 ConsumeToken(); // consume catch 2463 if (Tok.is(tok::l_paren)) { 2464 ConsumeParen(); 2465 ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope); 2466 if (Tok.isNot(tok::ellipsis)) { 2467 DeclSpec DS(AttrFactory); 2468 ParseDeclarationSpecifiers(DS); 2469 Declarator ParmDecl(DS, Declarator::ObjCCatchContext); 2470 ParseDeclarator(ParmDecl); 2471 2472 // Inform the actions module about the declarator, so it 2473 // gets added to the current scope. 2474 FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl); 2475 } else 2476 ConsumeToken(); // consume '...' 2477 2478 SourceLocation RParenLoc; 2479 2480 if (Tok.is(tok::r_paren)) 2481 RParenLoc = ConsumeParen(); 2482 else // Skip over garbage, until we get to ')'. Eat the ')'. 2483 SkipUntil(tok::r_paren, StopAtSemi); 2484 2485 StmtResult CatchBody(true); 2486 if (Tok.is(tok::l_brace)) 2487 CatchBody = ParseCompoundStatementBody(); 2488 else 2489 Diag(Tok, diag::err_expected) << tok::l_brace; 2490 if (CatchBody.isInvalid()) 2491 CatchBody = Actions.ActOnNullStmt(Tok.getLocation()); 2492 2493 StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, 2494 RParenLoc, 2495 FirstPart, 2496 CatchBody.get()); 2497 if (!Catch.isInvalid()) 2498 CatchStmts.push_back(Catch.get()); 2499 2500 } else { 2501 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after) 2502 << "@catch clause"; 2503 return StmtError(); 2504 } 2505 catch_or_finally_seen = true; 2506 } else { 2507 assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?"); 2508 ConsumeToken(); // consume finally 2509 ParseScope FinallyScope(this, Scope::DeclScope); 2510 2511 StmtResult FinallyBody(true); 2512 if (Tok.is(tok::l_brace)) 2513 FinallyBody = ParseCompoundStatementBody(); 2514 else 2515 Diag(Tok, diag::err_expected) << tok::l_brace; 2516 if (FinallyBody.isInvalid()) 2517 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation()); 2518 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, 2519 FinallyBody.get()); 2520 catch_or_finally_seen = true; 2521 break; 2522 } 2523 } 2524 if (!catch_or_finally_seen) { 2525 Diag(atLoc, diag::err_missing_catch_finally); 2526 return StmtError(); 2527 } 2528 2529 return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(), 2530 CatchStmts, 2531 FinallyStmt.get()); 2532 } 2533 2534 /// objc-autoreleasepool-statement: 2535 /// @autoreleasepool compound-statement 2536 /// 2537 StmtResult 2538 Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) { 2539 ConsumeToken(); // consume autoreleasepool 2540 if (Tok.isNot(tok::l_brace)) { 2541 Diag(Tok, diag::err_expected) << tok::l_brace; 2542 return StmtError(); 2543 } 2544 // Enter a scope to hold everything within the compound stmt. Compound 2545 // statements can always hold declarations. 2546 ParseScope BodyScope(this, Scope::DeclScope); 2547 2548 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody()); 2549 2550 BodyScope.Exit(); 2551 if (AutoreleasePoolBody.isInvalid()) 2552 AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation()); 2553 return Actions.ActOnObjCAutoreleasePoolStmt(atLoc, 2554 AutoreleasePoolBody.get()); 2555 } 2556 2557 /// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them 2558 /// for later parsing. 2559 void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) { 2560 LexedMethod* LM = new LexedMethod(this, MDecl); 2561 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM); 2562 CachedTokens &Toks = LM->Toks; 2563 // Begin by storing the '{' or 'try' or ':' token. 2564 Toks.push_back(Tok); 2565 if (Tok.is(tok::kw_try)) { 2566 ConsumeToken(); 2567 if (Tok.is(tok::colon)) { 2568 Toks.push_back(Tok); 2569 ConsumeToken(); 2570 while (Tok.isNot(tok::l_brace)) { 2571 ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false); 2572 ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); 2573 } 2574 } 2575 Toks.push_back(Tok); // also store '{' 2576 } 2577 else if (Tok.is(tok::colon)) { 2578 ConsumeToken(); 2579 while (Tok.isNot(tok::l_brace)) { 2580 ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false); 2581 ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); 2582 } 2583 Toks.push_back(Tok); // also store '{' 2584 } 2585 ConsumeBrace(); 2586 // Consume everything up to (and including) the matching right brace. 2587 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 2588 while (Tok.is(tok::kw_catch)) { 2589 ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false); 2590 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 2591 } 2592 } 2593 2594 /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' 2595 /// 2596 Decl *Parser::ParseObjCMethodDefinition() { 2597 Decl *MDecl = ParseObjCMethodPrototype(); 2598 2599 PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(), 2600 "parsing Objective-C method"); 2601 2602 // parse optional ';' 2603 if (Tok.is(tok::semi)) { 2604 if (CurParsedObjCImpl) { 2605 Diag(Tok, diag::warn_semicolon_before_method_body) 2606 << FixItHint::CreateRemoval(Tok.getLocation()); 2607 } 2608 ConsumeToken(); 2609 } 2610 2611 // We should have an opening brace now. 2612 if (Tok.isNot(tok::l_brace)) { 2613 Diag(Tok, diag::err_expected_method_body); 2614 2615 // Skip over garbage, until we get to '{'. Don't eat the '{'. 2616 SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch); 2617 2618 // If we didn't find the '{', bail out. 2619 if (Tok.isNot(tok::l_brace)) 2620 return nullptr; 2621 } 2622 2623 if (!MDecl) { 2624 ConsumeBrace(); 2625 SkipUntil(tok::r_brace); 2626 return nullptr; 2627 } 2628 2629 // Allow the rest of sema to find private method decl implementations. 2630 Actions.AddAnyMethodToGlobalPool(MDecl); 2631 assert (CurParsedObjCImpl 2632 && "ParseObjCMethodDefinition - Method out of @implementation"); 2633 // Consume the tokens and store them for later parsing. 2634 StashAwayMethodOrFunctionBodyTokens(MDecl); 2635 return MDecl; 2636 } 2637 2638 StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { 2639 if (Tok.is(tok::code_completion)) { 2640 Actions.CodeCompleteObjCAtStatement(getCurScope()); 2641 cutOffParsing(); 2642 return StmtError(); 2643 } 2644 2645 if (Tok.isObjCAtKeyword(tok::objc_try)) 2646 return ParseObjCTryStmt(AtLoc); 2647 2648 if (Tok.isObjCAtKeyword(tok::objc_throw)) 2649 return ParseObjCThrowStmt(AtLoc); 2650 2651 if (Tok.isObjCAtKeyword(tok::objc_synchronized)) 2652 return ParseObjCSynchronizedStmt(AtLoc); 2653 2654 if (Tok.isObjCAtKeyword(tok::objc_autoreleasepool)) 2655 return ParseObjCAutoreleasePoolStmt(AtLoc); 2656 2657 if (Tok.isObjCAtKeyword(tok::objc_import) && 2658 getLangOpts().DebuggerSupport) { 2659 SkipUntil(tok::semi); 2660 return Actions.ActOnNullStmt(Tok.getLocation()); 2661 } 2662 2663 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc)); 2664 if (Res.isInvalid()) { 2665 // If the expression is invalid, skip ahead to the next semicolon. Not 2666 // doing this opens us up to the possibility of infinite loops if 2667 // ParseExpression does not consume any tokens. 2668 SkipUntil(tok::semi); 2669 return StmtError(); 2670 } 2671 2672 // Otherwise, eat the semicolon. 2673 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); 2674 return Actions.ActOnExprStmt(Res); 2675 } 2676 2677 ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { 2678 switch (Tok.getKind()) { 2679 case tok::code_completion: 2680 Actions.CodeCompleteObjCAtExpression(getCurScope()); 2681 cutOffParsing(); 2682 return ExprError(); 2683 2684 case tok::minus: 2685 case tok::plus: { 2686 tok::TokenKind Kind = Tok.getKind(); 2687 SourceLocation OpLoc = ConsumeToken(); 2688 2689 if (!Tok.is(tok::numeric_constant)) { 2690 const char *Symbol = nullptr; 2691 switch (Kind) { 2692 case tok::minus: Symbol = "-"; break; 2693 case tok::plus: Symbol = "+"; break; 2694 default: llvm_unreachable("missing unary operator case"); 2695 } 2696 Diag(Tok, diag::err_nsnumber_nonliteral_unary) 2697 << Symbol; 2698 return ExprError(); 2699 } 2700 2701 ExprResult Lit(Actions.ActOnNumericConstant(Tok)); 2702 if (Lit.isInvalid()) { 2703 return Lit; 2704 } 2705 ConsumeToken(); // Consume the literal token. 2706 2707 Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.get()); 2708 if (Lit.isInvalid()) 2709 return Lit; 2710 2711 return ParsePostfixExpressionSuffix( 2712 Actions.BuildObjCNumericLiteral(AtLoc, Lit.get())); 2713 } 2714 2715 case tok::string_literal: // primary-expression: string-literal 2716 case tok::wide_string_literal: 2717 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc)); 2718 2719 case tok::char_constant: 2720 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc)); 2721 2722 case tok::numeric_constant: 2723 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc)); 2724 2725 case tok::kw_true: // Objective-C++, etc. 2726 case tok::kw___objc_yes: // c/c++/objc/objc++ __objc_yes 2727 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, true)); 2728 case tok::kw_false: // Objective-C++, etc. 2729 case tok::kw___objc_no: // c/c++/objc/objc++ __objc_no 2730 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, false)); 2731 2732 case tok::l_square: 2733 // Objective-C array literal 2734 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc)); 2735 2736 case tok::l_brace: 2737 // Objective-C dictionary literal 2738 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc)); 2739 2740 case tok::l_paren: 2741 // Objective-C boxed expression 2742 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc)); 2743 2744 default: 2745 if (Tok.getIdentifierInfo() == nullptr) 2746 return ExprError(Diag(AtLoc, diag::err_unexpected_at)); 2747 2748 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) { 2749 case tok::objc_encode: 2750 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc)); 2751 case tok::objc_protocol: 2752 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc)); 2753 case tok::objc_selector: 2754 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc)); 2755 default: { 2756 const char *str = nullptr; 2757 if (GetLookAheadToken(1).is(tok::l_brace)) { 2758 char ch = Tok.getIdentifierInfo()->getNameStart()[0]; 2759 str = 2760 ch == 't' ? "try" 2761 : (ch == 'f' ? "finally" 2762 : (ch == 'a' ? "autoreleasepool" : nullptr)); 2763 } 2764 if (str) { 2765 SourceLocation kwLoc = Tok.getLocation(); 2766 return ExprError(Diag(AtLoc, diag::err_unexpected_at) << 2767 FixItHint::CreateReplacement(kwLoc, str)); 2768 } 2769 else 2770 return ExprError(Diag(AtLoc, diag::err_unexpected_at)); 2771 } 2772 } 2773 } 2774 } 2775 2776 /// \brief Parse the receiver of an Objective-C++ message send. 2777 /// 2778 /// This routine parses the receiver of a message send in 2779 /// Objective-C++ either as a type or as an expression. Note that this 2780 /// routine must not be called to parse a send to 'super', since it 2781 /// has no way to return such a result. 2782 /// 2783 /// \param IsExpr Whether the receiver was parsed as an expression. 2784 /// 2785 /// \param TypeOrExpr If the receiver was parsed as an expression (\c 2786 /// IsExpr is true), the parsed expression. If the receiver was parsed 2787 /// as a type (\c IsExpr is false), the parsed type. 2788 /// 2789 /// \returns True if an error occurred during parsing or semantic 2790 /// analysis, in which case the arguments do not have valid 2791 /// values. Otherwise, returns false for a successful parse. 2792 /// 2793 /// objc-receiver: [C++] 2794 /// 'super' [not parsed here] 2795 /// expression 2796 /// simple-type-specifier 2797 /// typename-specifier 2798 bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) { 2799 InMessageExpressionRAIIObject InMessage(*this, true); 2800 2801 if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename, 2802 tok::annot_cxxscope)) 2803 TryAnnotateTypeOrScopeToken(); 2804 2805 if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) { 2806 // objc-receiver: 2807 // expression 2808 // Make sure any typos in the receiver are corrected or diagnosed, so that 2809 // proper recovery can happen. FIXME: Perhaps filter the corrected expr to 2810 // only the things that are valid ObjC receivers? 2811 ExprResult Receiver = Actions.CorrectDelayedTyposInExpr(ParseExpression()); 2812 if (Receiver.isInvalid()) 2813 return true; 2814 2815 IsExpr = true; 2816 TypeOrExpr = Receiver.get(); 2817 return false; 2818 } 2819 2820 // objc-receiver: 2821 // typename-specifier 2822 // simple-type-specifier 2823 // expression (that starts with one of the above) 2824 DeclSpec DS(AttrFactory); 2825 ParseCXXSimpleTypeSpecifier(DS); 2826 2827 if (Tok.is(tok::l_paren)) { 2828 // If we see an opening parentheses at this point, we are 2829 // actually parsing an expression that starts with a 2830 // function-style cast, e.g., 2831 // 2832 // postfix-expression: 2833 // simple-type-specifier ( expression-list [opt] ) 2834 // typename-specifier ( expression-list [opt] ) 2835 // 2836 // Parse the remainder of this case, then the (optional) 2837 // postfix-expression suffix, followed by the (optional) 2838 // right-hand side of the binary expression. We have an 2839 // instance method. 2840 ExprResult Receiver = ParseCXXTypeConstructExpression(DS); 2841 if (!Receiver.isInvalid()) 2842 Receiver = ParsePostfixExpressionSuffix(Receiver.get()); 2843 if (!Receiver.isInvalid()) 2844 Receiver = ParseRHSOfBinaryExpression(Receiver.get(), prec::Comma); 2845 if (Receiver.isInvalid()) 2846 return true; 2847 2848 IsExpr = true; 2849 TypeOrExpr = Receiver.get(); 2850 return false; 2851 } 2852 2853 // We have a class message. Turn the simple-type-specifier or 2854 // typename-specifier we parsed into a type and parse the 2855 // remainder of the class message. 2856 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 2857 TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 2858 if (Type.isInvalid()) 2859 return true; 2860 2861 IsExpr = false; 2862 TypeOrExpr = Type.get().getAsOpaquePtr(); 2863 return false; 2864 } 2865 2866 /// \brief Determine whether the parser is currently referring to a an 2867 /// Objective-C message send, using a simplified heuristic to avoid overhead. 2868 /// 2869 /// This routine will only return true for a subset of valid message-send 2870 /// expressions. 2871 bool Parser::isSimpleObjCMessageExpression() { 2872 assert(Tok.is(tok::l_square) && getLangOpts().ObjC1 && 2873 "Incorrect start for isSimpleObjCMessageExpression"); 2874 return GetLookAheadToken(1).is(tok::identifier) && 2875 GetLookAheadToken(2).is(tok::identifier); 2876 } 2877 2878 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() { 2879 if (!getLangOpts().ObjC1 || !NextToken().is(tok::identifier) || 2880 InMessageExpression) 2881 return false; 2882 2883 2884 ParsedType Type; 2885 2886 if (Tok.is(tok::annot_typename)) 2887 Type = getTypeAnnotation(Tok); 2888 else if (Tok.is(tok::identifier)) 2889 Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(), 2890 getCurScope()); 2891 else 2892 return false; 2893 2894 if (!Type.get().isNull() && Type.get()->isObjCObjectOrInterfaceType()) { 2895 const Token &AfterNext = GetLookAheadToken(2); 2896 if (AfterNext.isOneOf(tok::colon, tok::r_square)) { 2897 if (Tok.is(tok::identifier)) 2898 TryAnnotateTypeOrScopeToken(); 2899 2900 return Tok.is(tok::annot_typename); 2901 } 2902 } 2903 2904 return false; 2905 } 2906 2907 /// objc-message-expr: 2908 /// '[' objc-receiver objc-message-args ']' 2909 /// 2910 /// objc-receiver: [C] 2911 /// 'super' 2912 /// expression 2913 /// class-name 2914 /// type-name 2915 /// 2916 ExprResult Parser::ParseObjCMessageExpression() { 2917 assert(Tok.is(tok::l_square) && "'[' expected"); 2918 SourceLocation LBracLoc = ConsumeBracket(); // consume '[' 2919 2920 if (Tok.is(tok::code_completion)) { 2921 Actions.CodeCompleteObjCMessageReceiver(getCurScope()); 2922 cutOffParsing(); 2923 return ExprError(); 2924 } 2925 2926 InMessageExpressionRAIIObject InMessage(*this, true); 2927 2928 if (getLangOpts().CPlusPlus) { 2929 // We completely separate the C and C++ cases because C++ requires 2930 // more complicated (read: slower) parsing. 2931 2932 // Handle send to super. 2933 // FIXME: This doesn't benefit from the same typo-correction we 2934 // get in Objective-C. 2935 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super && 2936 NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope()) 2937 return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 2938 ParsedType(), nullptr); 2939 2940 // Parse the receiver, which is either a type or an expression. 2941 bool IsExpr; 2942 void *TypeOrExpr = nullptr; 2943 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) { 2944 SkipUntil(tok::r_square, StopAtSemi); 2945 return ExprError(); 2946 } 2947 2948 if (IsExpr) 2949 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 2950 ParsedType(), 2951 static_cast<Expr*>(TypeOrExpr)); 2952 2953 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 2954 ParsedType::getFromOpaquePtr(TypeOrExpr), 2955 nullptr); 2956 } 2957 2958 if (Tok.is(tok::identifier)) { 2959 IdentifierInfo *Name = Tok.getIdentifierInfo(); 2960 SourceLocation NameLoc = Tok.getLocation(); 2961 ParsedType ReceiverType; 2962 switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc, 2963 Name == Ident_super, 2964 NextToken().is(tok::period), 2965 ReceiverType)) { 2966 case Sema::ObjCSuperMessage: 2967 return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 2968 ParsedType(), nullptr); 2969 2970 case Sema::ObjCClassMessage: 2971 if (!ReceiverType) { 2972 SkipUntil(tok::r_square, StopAtSemi); 2973 return ExprError(); 2974 } 2975 2976 ConsumeToken(); // the type name 2977 2978 // Parse type arguments and protocol qualifiers. 2979 if (Tok.is(tok::less)) { 2980 SourceLocation NewEndLoc; 2981 TypeResult NewReceiverType 2982 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType, 2983 /*consumeLastToken=*/true, 2984 NewEndLoc); 2985 if (!NewReceiverType.isUsable()) { 2986 SkipUntil(tok::r_square, StopAtSemi); 2987 return ExprError(); 2988 } 2989 2990 ReceiverType = NewReceiverType.get(); 2991 } 2992 2993 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 2994 ReceiverType, nullptr); 2995 2996 case Sema::ObjCInstanceMessage: 2997 // Fall through to parse an expression. 2998 break; 2999 } 3000 } 3001 3002 // Otherwise, an arbitrary expression can be the receiver of a send. 3003 ExprResult Res = Actions.CorrectDelayedTyposInExpr(ParseExpression()); 3004 if (Res.isInvalid()) { 3005 SkipUntil(tok::r_square, StopAtSemi); 3006 return Res; 3007 } 3008 3009 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 3010 ParsedType(), Res.get()); 3011 } 3012 3013 /// \brief Parse the remainder of an Objective-C message following the 3014 /// '[' objc-receiver. 3015 /// 3016 /// This routine handles sends to super, class messages (sent to a 3017 /// class name), and instance messages (sent to an object), and the 3018 /// target is represented by \p SuperLoc, \p ReceiverType, or \p 3019 /// ReceiverExpr, respectively. Only one of these parameters may have 3020 /// a valid value. 3021 /// 3022 /// \param LBracLoc The location of the opening '['. 3023 /// 3024 /// \param SuperLoc If this is a send to 'super', the location of the 3025 /// 'super' keyword that indicates a send to the superclass. 3026 /// 3027 /// \param ReceiverType If this is a class message, the type of the 3028 /// class we are sending a message to. 3029 /// 3030 /// \param ReceiverExpr If this is an instance message, the expression 3031 /// used to compute the receiver object. 3032 /// 3033 /// objc-message-args: 3034 /// objc-selector 3035 /// objc-keywordarg-list 3036 /// 3037 /// objc-keywordarg-list: 3038 /// objc-keywordarg 3039 /// objc-keywordarg-list objc-keywordarg 3040 /// 3041 /// objc-keywordarg: 3042 /// selector-name[opt] ':' objc-keywordexpr 3043 /// 3044 /// objc-keywordexpr: 3045 /// nonempty-expr-list 3046 /// 3047 /// nonempty-expr-list: 3048 /// assignment-expression 3049 /// nonempty-expr-list , assignment-expression 3050 /// 3051 ExprResult 3052 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, 3053 SourceLocation SuperLoc, 3054 ParsedType ReceiverType, 3055 Expr *ReceiverExpr) { 3056 InMessageExpressionRAIIObject InMessage(*this, true); 3057 3058 if (Tok.is(tok::code_completion)) { 3059 if (SuperLoc.isValid()) 3060 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None, 3061 false); 3062 else if (ReceiverType) 3063 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, None, 3064 false); 3065 else 3066 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, 3067 None, false); 3068 cutOffParsing(); 3069 return ExprError(); 3070 } 3071 3072 // Parse objc-selector 3073 SourceLocation Loc; 3074 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc); 3075 3076 SmallVector<IdentifierInfo *, 12> KeyIdents; 3077 SmallVector<SourceLocation, 12> KeyLocs; 3078 ExprVector KeyExprs; 3079 3080 if (Tok.is(tok::colon)) { 3081 while (1) { 3082 // Each iteration parses a single keyword argument. 3083 KeyIdents.push_back(selIdent); 3084 KeyLocs.push_back(Loc); 3085 3086 if (ExpectAndConsume(tok::colon)) { 3087 // We must manually skip to a ']', otherwise the expression skipper will 3088 // stop at the ']' when it skips to the ';'. We want it to skip beyond 3089 // the enclosing expression. 3090 SkipUntil(tok::r_square, StopAtSemi); 3091 return ExprError(); 3092 } 3093 3094 /// Parse the expression after ':' 3095 3096 if (Tok.is(tok::code_completion)) { 3097 if (SuperLoc.isValid()) 3098 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, 3099 KeyIdents, 3100 /*AtArgumentEpression=*/true); 3101 else if (ReceiverType) 3102 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, 3103 KeyIdents, 3104 /*AtArgumentEpression=*/true); 3105 else 3106 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, 3107 KeyIdents, 3108 /*AtArgumentEpression=*/true); 3109 3110 cutOffParsing(); 3111 return ExprError(); 3112 } 3113 3114 ExprResult Expr; 3115 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 3116 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 3117 Expr = ParseBraceInitializer(); 3118 } else 3119 Expr = ParseAssignmentExpression(); 3120 3121 ExprResult Res(Expr); 3122 if (Res.isInvalid()) { 3123 // We must manually skip to a ']', otherwise the expression skipper will 3124 // stop at the ']' when it skips to the ';'. We want it to skip beyond 3125 // the enclosing expression. 3126 SkipUntil(tok::r_square, StopAtSemi); 3127 return Res; 3128 } 3129 3130 // We have a valid expression. 3131 KeyExprs.push_back(Res.get()); 3132 3133 // Code completion after each argument. 3134 if (Tok.is(tok::code_completion)) { 3135 if (SuperLoc.isValid()) 3136 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, 3137 KeyIdents, 3138 /*AtArgumentEpression=*/false); 3139 else if (ReceiverType) 3140 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, 3141 KeyIdents, 3142 /*AtArgumentEpression=*/false); 3143 else 3144 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, 3145 KeyIdents, 3146 /*AtArgumentEpression=*/false); 3147 cutOffParsing(); 3148 return ExprError(); 3149 } 3150 3151 // Check for another keyword selector. 3152 selIdent = ParseObjCSelectorPiece(Loc); 3153 if (!selIdent && Tok.isNot(tok::colon)) 3154 break; 3155 // We have a selector or a colon, continue parsing. 3156 } 3157 // Parse the, optional, argument list, comma separated. 3158 while (Tok.is(tok::comma)) { 3159 SourceLocation commaLoc = ConsumeToken(); // Eat the ','. 3160 /// Parse the expression after ',' 3161 ExprResult Res(ParseAssignmentExpression()); 3162 if (Tok.is(tok::colon)) 3163 Res = Actions.CorrectDelayedTyposInExpr(Res); 3164 if (Res.isInvalid()) { 3165 if (Tok.is(tok::colon)) { 3166 Diag(commaLoc, diag::note_extra_comma_message_arg) << 3167 FixItHint::CreateRemoval(commaLoc); 3168 } 3169 // We must manually skip to a ']', otherwise the expression skipper will 3170 // stop at the ']' when it skips to the ';'. We want it to skip beyond 3171 // the enclosing expression. 3172 SkipUntil(tok::r_square, StopAtSemi); 3173 return Res; 3174 } 3175 3176 // We have a valid expression. 3177 KeyExprs.push_back(Res.get()); 3178 } 3179 } else if (!selIdent) { 3180 Diag(Tok, diag::err_expected) << tok::identifier; // missing selector name. 3181 3182 // We must manually skip to a ']', otherwise the expression skipper will 3183 // stop at the ']' when it skips to the ';'. We want it to skip beyond 3184 // the enclosing expression. 3185 SkipUntil(tok::r_square, StopAtSemi); 3186 return ExprError(); 3187 } 3188 3189 if (Tok.isNot(tok::r_square)) { 3190 Diag(Tok, diag::err_expected) 3191 << (Tok.is(tok::identifier) ? tok::colon : tok::r_square); 3192 // We must manually skip to a ']', otherwise the expression skipper will 3193 // stop at the ']' when it skips to the ';'. We want it to skip beyond 3194 // the enclosing expression. 3195 SkipUntil(tok::r_square, StopAtSemi); 3196 return ExprError(); 3197 } 3198 3199 SourceLocation RBracLoc = ConsumeBracket(); // consume ']' 3200 3201 unsigned nKeys = KeyIdents.size(); 3202 if (nKeys == 0) { 3203 KeyIdents.push_back(selIdent); 3204 KeyLocs.push_back(Loc); 3205 } 3206 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]); 3207 3208 if (SuperLoc.isValid()) 3209 return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel, 3210 LBracLoc, KeyLocs, RBracLoc, KeyExprs); 3211 else if (ReceiverType) 3212 return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel, 3213 LBracLoc, KeyLocs, RBracLoc, KeyExprs); 3214 return Actions.ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel, 3215 LBracLoc, KeyLocs, RBracLoc, KeyExprs); 3216 } 3217 3218 ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { 3219 ExprResult Res(ParseStringLiteralExpression()); 3220 if (Res.isInvalid()) return Res; 3221 3222 // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string 3223 // expressions. At this point, we know that the only valid thing that starts 3224 // with '@' is an @"". 3225 SmallVector<SourceLocation, 4> AtLocs; 3226 ExprVector AtStrings; 3227 AtLocs.push_back(AtLoc); 3228 AtStrings.push_back(Res.get()); 3229 3230 while (Tok.is(tok::at)) { 3231 AtLocs.push_back(ConsumeToken()); // eat the @. 3232 3233 // Invalid unless there is a string literal. 3234 if (!isTokenStringLiteral()) 3235 return ExprError(Diag(Tok, diag::err_objc_concat_string)); 3236 3237 ExprResult Lit(ParseStringLiteralExpression()); 3238 if (Lit.isInvalid()) 3239 return Lit; 3240 3241 AtStrings.push_back(Lit.get()); 3242 } 3243 3244 return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.data(), 3245 AtStrings.size()); 3246 } 3247 3248 /// ParseObjCBooleanLiteral - 3249 /// objc-scalar-literal : '@' boolean-keyword 3250 /// ; 3251 /// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no' 3252 /// ; 3253 ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc, 3254 bool ArgValue) { 3255 SourceLocation EndLoc = ConsumeToken(); // consume the keyword. 3256 return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue); 3257 } 3258 3259 /// ParseObjCCharacterLiteral - 3260 /// objc-scalar-literal : '@' character-literal 3261 /// ; 3262 ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) { 3263 ExprResult Lit(Actions.ActOnCharacterConstant(Tok)); 3264 if (Lit.isInvalid()) { 3265 return Lit; 3266 } 3267 ConsumeToken(); // Consume the literal token. 3268 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()); 3269 } 3270 3271 /// ParseObjCNumericLiteral - 3272 /// objc-scalar-literal : '@' scalar-literal 3273 /// ; 3274 /// scalar-literal : | numeric-constant /* any numeric constant. */ 3275 /// ; 3276 ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) { 3277 ExprResult Lit(Actions.ActOnNumericConstant(Tok)); 3278 if (Lit.isInvalid()) { 3279 return Lit; 3280 } 3281 ConsumeToken(); // Consume the literal token. 3282 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()); 3283 } 3284 3285 /// ParseObjCBoxedExpr - 3286 /// objc-box-expression: 3287 /// @( assignment-expression ) 3288 ExprResult 3289 Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) { 3290 if (Tok.isNot(tok::l_paren)) 3291 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@"); 3292 3293 BalancedDelimiterTracker T(*this, tok::l_paren); 3294 T.consumeOpen(); 3295 ExprResult ValueExpr(ParseAssignmentExpression()); 3296 if (T.consumeClose()) 3297 return ExprError(); 3298 3299 if (ValueExpr.isInvalid()) 3300 return ExprError(); 3301 3302 // Wrap the sub-expression in a parenthesized expression, to distinguish 3303 // a boxed expression from a literal. 3304 SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation(); 3305 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get()); 3306 return Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc), 3307 ValueExpr.get()); 3308 } 3309 3310 ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) { 3311 ExprVector ElementExprs; // array elements. 3312 ConsumeBracket(); // consume the l_square. 3313 3314 while (Tok.isNot(tok::r_square)) { 3315 // Parse list of array element expressions (all must be id types). 3316 ExprResult Res(ParseAssignmentExpression()); 3317 if (Res.isInvalid()) { 3318 // We must manually skip to a ']', otherwise the expression skipper will 3319 // stop at the ']' when it skips to the ';'. We want it to skip beyond 3320 // the enclosing expression. 3321 SkipUntil(tok::r_square, StopAtSemi); 3322 return Res; 3323 } 3324 3325 // Parse the ellipsis that indicates a pack expansion. 3326 if (Tok.is(tok::ellipsis)) 3327 Res = Actions.ActOnPackExpansion(Res.get(), ConsumeToken()); 3328 if (Res.isInvalid()) 3329 return true; 3330 3331 ElementExprs.push_back(Res.get()); 3332 3333 if (Tok.is(tok::comma)) 3334 ConsumeToken(); // Eat the ','. 3335 else if (Tok.isNot(tok::r_square)) 3336 return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_square 3337 << tok::comma); 3338 } 3339 SourceLocation EndLoc = ConsumeBracket(); // location of ']' 3340 MultiExprArg Args(ElementExprs); 3341 return Actions.BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args); 3342 } 3343 3344 ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) { 3345 SmallVector<ObjCDictionaryElement, 4> Elements; // dictionary elements. 3346 ConsumeBrace(); // consume the l_square. 3347 while (Tok.isNot(tok::r_brace)) { 3348 // Parse the comma separated key : value expressions. 3349 ExprResult KeyExpr; 3350 { 3351 ColonProtectionRAIIObject X(*this); 3352 KeyExpr = ParseAssignmentExpression(); 3353 if (KeyExpr.isInvalid()) { 3354 // We must manually skip to a '}', otherwise the expression skipper will 3355 // stop at the '}' when it skips to the ';'. We want it to skip beyond 3356 // the enclosing expression. 3357 SkipUntil(tok::r_brace, StopAtSemi); 3358 return KeyExpr; 3359 } 3360 } 3361 3362 if (ExpectAndConsume(tok::colon)) { 3363 SkipUntil(tok::r_brace, StopAtSemi); 3364 return ExprError(); 3365 } 3366 3367 ExprResult ValueExpr(ParseAssignmentExpression()); 3368 if (ValueExpr.isInvalid()) { 3369 // We must manually skip to a '}', otherwise the expression skipper will 3370 // stop at the '}' when it skips to the ';'. We want it to skip beyond 3371 // the enclosing expression. 3372 SkipUntil(tok::r_brace, StopAtSemi); 3373 return ValueExpr; 3374 } 3375 3376 // Parse the ellipsis that designates this as a pack expansion. 3377 SourceLocation EllipsisLoc; 3378 if (getLangOpts().CPlusPlus) 3379 TryConsumeToken(tok::ellipsis, EllipsisLoc); 3380 3381 // We have a valid expression. Collect it in a vector so we can 3382 // build the argument list. 3383 ObjCDictionaryElement Element = { 3384 KeyExpr.get(), ValueExpr.get(), EllipsisLoc, None 3385 }; 3386 Elements.push_back(Element); 3387 3388 if (!TryConsumeToken(tok::comma) && Tok.isNot(tok::r_brace)) 3389 return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_brace 3390 << tok::comma); 3391 } 3392 SourceLocation EndLoc = ConsumeBrace(); 3393 3394 // Create the ObjCDictionaryLiteral. 3395 return Actions.BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc), 3396 Elements.data(), Elements.size()); 3397 } 3398 3399 /// objc-encode-expression: 3400 /// \@encode ( type-name ) 3401 ExprResult 3402 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { 3403 assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!"); 3404 3405 SourceLocation EncLoc = ConsumeToken(); 3406 3407 if (Tok.isNot(tok::l_paren)) 3408 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode"); 3409 3410 BalancedDelimiterTracker T(*this, tok::l_paren); 3411 T.consumeOpen(); 3412 3413 TypeResult Ty = ParseTypeName(); 3414 3415 T.consumeClose(); 3416 3417 if (Ty.isInvalid()) 3418 return ExprError(); 3419 3420 return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.getOpenLocation(), 3421 Ty.get(), T.getCloseLocation()); 3422 } 3423 3424 /// objc-protocol-expression 3425 /// \@protocol ( protocol-name ) 3426 ExprResult 3427 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { 3428 SourceLocation ProtoLoc = ConsumeToken(); 3429 3430 if (Tok.isNot(tok::l_paren)) 3431 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol"); 3432 3433 BalancedDelimiterTracker T(*this, tok::l_paren); 3434 T.consumeOpen(); 3435 3436 if (Tok.isNot(tok::identifier)) 3437 return ExprError(Diag(Tok, diag::err_expected) << tok::identifier); 3438 3439 IdentifierInfo *protocolId = Tok.getIdentifierInfo(); 3440 SourceLocation ProtoIdLoc = ConsumeToken(); 3441 3442 T.consumeClose(); 3443 3444 return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, 3445 T.getOpenLocation(), ProtoIdLoc, 3446 T.getCloseLocation()); 3447 } 3448 3449 /// objc-selector-expression 3450 /// @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')' 3451 ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { 3452 SourceLocation SelectorLoc = ConsumeToken(); 3453 3454 if (Tok.isNot(tok::l_paren)) 3455 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector"); 3456 3457 SmallVector<IdentifierInfo *, 12> KeyIdents; 3458 SourceLocation sLoc; 3459 3460 BalancedDelimiterTracker T(*this, tok::l_paren); 3461 T.consumeOpen(); 3462 bool HasOptionalParen = Tok.is(tok::l_paren); 3463 if (HasOptionalParen) 3464 ConsumeParen(); 3465 3466 if (Tok.is(tok::code_completion)) { 3467 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); 3468 cutOffParsing(); 3469 return ExprError(); 3470 } 3471 3472 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc); 3473 if (!SelIdent && // missing selector name. 3474 Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon)) 3475 return ExprError(Diag(Tok, diag::err_expected) << tok::identifier); 3476 3477 KeyIdents.push_back(SelIdent); 3478 3479 unsigned nColons = 0; 3480 if (Tok.isNot(tok::r_paren)) { 3481 while (1) { 3482 if (TryConsumeToken(tok::coloncolon)) { // Handle :: in C++. 3483 ++nColons; 3484 KeyIdents.push_back(nullptr); 3485 } else if (ExpectAndConsume(tok::colon)) // Otherwise expect ':'. 3486 return ExprError(); 3487 ++nColons; 3488 3489 if (Tok.is(tok::r_paren)) 3490 break; 3491 3492 if (Tok.is(tok::code_completion)) { 3493 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); 3494 cutOffParsing(); 3495 return ExprError(); 3496 } 3497 3498 // Check for another keyword selector. 3499 SourceLocation Loc; 3500 SelIdent = ParseObjCSelectorPiece(Loc); 3501 KeyIdents.push_back(SelIdent); 3502 if (!SelIdent && Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon)) 3503 break; 3504 } 3505 } 3506 if (HasOptionalParen && Tok.is(tok::r_paren)) 3507 ConsumeParen(); // ')' 3508 T.consumeClose(); 3509 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]); 3510 return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, 3511 T.getOpenLocation(), 3512 T.getCloseLocation(), 3513 !HasOptionalParen); 3514 } 3515 3516 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { 3517 // MCDecl might be null due to error in method or c-function prototype, etc. 3518 Decl *MCDecl = LM.D; 3519 bool skip = MCDecl && 3520 ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) || 3521 (!parseMethod && Actions.isObjCMethodDecl(MCDecl))); 3522 if (skip) 3523 return; 3524 3525 // Save the current token position. 3526 SourceLocation OrigLoc = Tok.getLocation(); 3527 3528 assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!"); 3529 // Append the current token at the end of the new token stream so that it 3530 // doesn't get lost. 3531 LM.Toks.push_back(Tok); 3532 PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false); 3533 3534 // Consume the previously pushed token. 3535 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 3536 3537 assert(Tok.isOneOf(tok::l_brace, tok::kw_try, tok::colon) && 3538 "Inline objective-c method not starting with '{' or 'try' or ':'"); 3539 // Enter a scope for the method or c-function body. 3540 ParseScope BodyScope(this, 3541 parseMethod 3542 ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope 3543 : Scope::FnScope|Scope::DeclScope); 3544 3545 // Tell the actions module that we have entered a method or c-function definition 3546 // with the specified Declarator for the method/function. 3547 if (parseMethod) 3548 Actions.ActOnStartOfObjCMethodDef(getCurScope(), MCDecl); 3549 else 3550 Actions.ActOnStartOfFunctionDef(getCurScope(), MCDecl); 3551 if (Tok.is(tok::kw_try)) 3552 ParseFunctionTryBlock(MCDecl, BodyScope); 3553 else { 3554 if (Tok.is(tok::colon)) 3555 ParseConstructorInitializer(MCDecl); 3556 ParseFunctionStatementBody(MCDecl, BodyScope); 3557 } 3558 3559 if (Tok.getLocation() != OrigLoc) { 3560 // Due to parsing error, we either went over the cached tokens or 3561 // there are still cached tokens left. If it's the latter case skip the 3562 // leftover tokens. 3563 // Since this is an uncommon situation that should be avoided, use the 3564 // expensive isBeforeInTranslationUnit call. 3565 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), 3566 OrigLoc)) 3567 while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) 3568 ConsumeAnyToken(); 3569 } 3570 3571 return; 3572 } 3573