brintos

brintos / llvm-project-archived public Read only

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