clang API Documentation

ParseObjc.cpp
Go to the documentation of this file.
00001 //===--- ParseObjC.cpp - Objective C Parsing ------------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements the Objective-C portions of the Parser interface.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Parse/Parser.h"
00015 #include "RAIIObjectsForParser.h"
00016 #include "clang/Basic/CharInfo.h"
00017 #include "clang/Parse/ParseDiagnostic.h"
00018 #include "clang/Sema/DeclSpec.h"
00019 #include "clang/Sema/PrettyDeclStackTrace.h"
00020 #include "clang/Sema/Scope.h"
00021 #include "llvm/ADT/SmallVector.h"
00022 #include "llvm/ADT/StringExtras.h"
00023 using namespace clang;
00024 
00025 /// Skips attributes after an Objective-C @ directive. Emits a diagnostic.
00026 void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
00027   ParsedAttributes attrs(AttrFactory);
00028   if (Tok.is(tok::kw___attribute)) {
00029     if (Kind == tok::objc_interface || Kind == tok::objc_protocol)
00030       Diag(Tok, diag::err_objc_postfix_attribute_hint)
00031           << (Kind == tok::objc_protocol);
00032     else
00033       Diag(Tok, diag::err_objc_postfix_attribute);
00034     ParseGNUAttributes(attrs);
00035   }
00036 }
00037 
00038 /// ParseObjCAtDirectives - Handle parts of the external-declaration production:
00039 ///       external-declaration: [C99 6.9]
00040 /// [OBJC]  objc-class-definition
00041 /// [OBJC]  objc-class-declaration
00042 /// [OBJC]  objc-alias-declaration
00043 /// [OBJC]  objc-protocol-definition
00044 /// [OBJC]  objc-method-definition
00045 /// [OBJC]  '@' 'end'
00046 Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() {
00047   SourceLocation AtLoc = ConsumeToken(); // the "@"
00048 
00049   if (Tok.is(tok::code_completion)) {
00050     Actions.CodeCompleteObjCAtDirective(getCurScope());
00051     cutOffParsing();
00052     return DeclGroupPtrTy();
00053   }
00054 
00055   Decl *SingleDecl = nullptr;
00056   switch (Tok.getObjCKeywordID()) {
00057   case tok::objc_class:
00058     return ParseObjCAtClassDeclaration(AtLoc);
00059   case tok::objc_interface: {
00060     ParsedAttributes attrs(AttrFactory);
00061     SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
00062     break;
00063   }
00064   case tok::objc_protocol: {
00065     ParsedAttributes attrs(AttrFactory);
00066     return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
00067   }
00068   case tok::objc_implementation:
00069     return ParseObjCAtImplementationDeclaration(AtLoc);
00070   case tok::objc_end:
00071     return ParseObjCAtEndDeclaration(AtLoc);
00072   case tok::objc_compatibility_alias:
00073     SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
00074     break;
00075   case tok::objc_synthesize:
00076     SingleDecl = ParseObjCPropertySynthesize(AtLoc);
00077     break;
00078   case tok::objc_dynamic:
00079     SingleDecl = ParseObjCPropertyDynamic(AtLoc);
00080     break;
00081   case tok::objc_import:
00082     if (getLangOpts().Modules)
00083       return ParseModuleImport(AtLoc);
00084     Diag(AtLoc, diag::err_atimport);
00085     SkipUntil(tok::semi);
00086     return Actions.ConvertDeclToDeclGroup(nullptr);
00087   default:
00088     Diag(AtLoc, diag::err_unexpected_at);
00089     SkipUntil(tok::semi);
00090     SingleDecl = nullptr;
00091     break;
00092   }
00093   return Actions.ConvertDeclToDeclGroup(SingleDecl);
00094 }
00095 
00096 ///
00097 /// objc-class-declaration:
00098 ///    '@' 'class' identifier-list ';'
00099 ///
00100 Parser::DeclGroupPtrTy
00101 Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
00102   ConsumeToken(); // the identifier "class"
00103   SmallVector<IdentifierInfo *, 8> ClassNames;
00104   SmallVector<SourceLocation, 8> ClassLocs;
00105 
00106 
00107   while (1) {
00108     MaybeSkipAttributes(tok::objc_class);
00109     if (Tok.isNot(tok::identifier)) {
00110       Diag(Tok, diag::err_expected) << tok::identifier;
00111       SkipUntil(tok::semi);
00112       return Actions.ConvertDeclToDeclGroup(nullptr);
00113     }
00114     ClassNames.push_back(Tok.getIdentifierInfo());
00115     ClassLocs.push_back(Tok.getLocation());
00116     ConsumeToken();
00117 
00118     if (!TryConsumeToken(tok::comma))
00119       break;
00120   }
00121 
00122   // Consume the ';'.
00123   if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class"))
00124     return Actions.ConvertDeclToDeclGroup(nullptr);
00125 
00126   return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
00127                                               ClassLocs.data(),
00128                                               ClassNames.size());
00129 }
00130 
00131 void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
00132 {
00133   Sema::ObjCContainerKind ock = Actions.getObjCContainerKind();
00134   if (ock == Sema::OCK_None)
00135     return;
00136 
00137   Decl *Decl = Actions.getObjCDeclContext();
00138   if (CurParsedObjCImpl) {
00139     CurParsedObjCImpl->finish(AtLoc);
00140   } else {
00141     Actions.ActOnAtEnd(getCurScope(), AtLoc);
00142   }
00143   Diag(AtLoc, diag::err_objc_missing_end)
00144       << FixItHint::CreateInsertion(AtLoc, "@end\n");
00145   if (Decl)
00146     Diag(Decl->getLocStart(), diag::note_objc_container_start)
00147         << (int) ock;
00148 }
00149 
00150 ///
00151 ///   objc-interface:
00152 ///     objc-class-interface-attributes[opt] objc-class-interface
00153 ///     objc-category-interface
00154 ///
00155 ///   objc-class-interface:
00156 ///     '@' 'interface' identifier objc-superclass[opt]
00157 ///       objc-protocol-refs[opt]
00158 ///       objc-class-instance-variables[opt]
00159 ///       objc-interface-decl-list
00160 ///     @end
00161 ///
00162 ///   objc-category-interface:
00163 ///     '@' 'interface' identifier '(' identifier[opt] ')'
00164 ///       objc-protocol-refs[opt]
00165 ///       objc-interface-decl-list
00166 ///     @end
00167 ///
00168 ///   objc-superclass:
00169 ///     ':' identifier
00170 ///
00171 ///   objc-class-interface-attributes:
00172 ///     __attribute__((visibility("default")))
00173 ///     __attribute__((visibility("hidden")))
00174 ///     __attribute__((deprecated))
00175 ///     __attribute__((unavailable))
00176 ///     __attribute__((objc_exception)) - used by NSException on 64-bit
00177 ///     __attribute__((objc_root_class))
00178 ///
00179 Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
00180                                               ParsedAttributes &attrs) {
00181   assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
00182          "ParseObjCAtInterfaceDeclaration(): Expected @interface");
00183   CheckNestedObjCContexts(AtLoc);
00184   ConsumeToken(); // the "interface" identifier
00185 
00186   // Code completion after '@interface'.
00187   if (Tok.is(tok::code_completion)) {
00188     Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
00189     cutOffParsing();
00190     return nullptr;
00191   }
00192 
00193   MaybeSkipAttributes(tok::objc_interface);
00194 
00195   if (Tok.isNot(tok::identifier)) {
00196     Diag(Tok, diag::err_expected)
00197         << tok::identifier; // missing class or category name.
00198     return nullptr;
00199   }
00200 
00201   // We have a class or category name - consume it.
00202   IdentifierInfo *nameId = Tok.getIdentifierInfo();
00203   SourceLocation nameLoc = ConsumeToken();
00204   if (Tok.is(tok::l_paren) && 
00205       !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { // we have a category.
00206     
00207     BalancedDelimiterTracker T(*this, tok::l_paren);
00208     T.consumeOpen();
00209 
00210     SourceLocation categoryLoc;
00211     IdentifierInfo *categoryId = nullptr;
00212     if (Tok.is(tok::code_completion)) {
00213       Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
00214       cutOffParsing();
00215       return nullptr;
00216     }
00217     
00218     // For ObjC2, the category name is optional (not an error).
00219     if (Tok.is(tok::identifier)) {
00220       categoryId = Tok.getIdentifierInfo();
00221       categoryLoc = ConsumeToken();
00222     }
00223     else if (!getLangOpts().ObjC2) {
00224       Diag(Tok, diag::err_expected)
00225           << tok::identifier; // missing category name.
00226       return nullptr;
00227     }
00228    
00229     T.consumeClose();
00230     if (T.getCloseLocation().isInvalid())
00231       return nullptr;
00232 
00233     if (!attrs.empty()) { // categories don't support attributes.
00234       Diag(nameLoc, diag::err_objc_no_attributes_on_category);
00235       attrs.clear();
00236     }
00237     
00238     // Next, we need to check for any protocol references.
00239     SourceLocation LAngleLoc, EndProtoLoc;
00240     SmallVector<Decl *, 8> ProtocolRefs;
00241     SmallVector<SourceLocation, 8> ProtocolLocs;
00242     if (Tok.is(tok::less) &&
00243         ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
00244                                     LAngleLoc, EndProtoLoc))
00245       return nullptr;
00246 
00247     Decl *CategoryType =
00248     Actions.ActOnStartCategoryInterface(AtLoc,
00249                                         nameId, nameLoc,
00250                                         categoryId, categoryLoc,
00251                                         ProtocolRefs.data(),
00252                                         ProtocolRefs.size(),
00253                                         ProtocolLocs.data(),
00254                                         EndProtoLoc);
00255     
00256     if (Tok.is(tok::l_brace))
00257       ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
00258       
00259     ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
00260     return CategoryType;
00261   }
00262   // Parse a class interface.
00263   IdentifierInfo *superClassId = nullptr;
00264   SourceLocation superClassLoc;
00265 
00266   if (Tok.is(tok::colon)) { // a super class is specified.
00267     ConsumeToken();
00268 
00269     // Code completion of superclass names.
00270     if (Tok.is(tok::code_completion)) {
00271       Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
00272       cutOffParsing();
00273       return nullptr;
00274     }
00275 
00276     if (Tok.isNot(tok::identifier)) {
00277       Diag(Tok, diag::err_expected)
00278           << tok::identifier; // missing super class name.
00279       return nullptr;
00280     }
00281     superClassId = Tok.getIdentifierInfo();
00282     superClassLoc = ConsumeToken();
00283   }
00284   // Next, we need to check for any protocol references.
00285   SmallVector<Decl *, 8> ProtocolRefs;
00286   SmallVector<SourceLocation, 8> ProtocolLocs;
00287   SourceLocation LAngleLoc, EndProtoLoc;
00288   if (Tok.is(tok::less) &&
00289       ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
00290                                   LAngleLoc, EndProtoLoc))
00291     return nullptr;
00292 
00293   if (Tok.isNot(tok::less))
00294     Actions.ActOnTypedefedProtocols(ProtocolRefs, superClassId, superClassLoc);
00295   
00296   Decl *ClsType =
00297     Actions.ActOnStartClassInterface(AtLoc, nameId, nameLoc,
00298                                      superClassId, superClassLoc,
00299                                      ProtocolRefs.data(), ProtocolRefs.size(),
00300                                      ProtocolLocs.data(),
00301                                      EndProtoLoc, attrs.getList());
00302 
00303   if (Tok.is(tok::l_brace))
00304     ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
00305 
00306   ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
00307   return ClsType;
00308 }
00309 
00310 ///   objc-interface-decl-list:
00311 ///     empty
00312 ///     objc-interface-decl-list objc-property-decl [OBJC2]
00313 ///     objc-interface-decl-list objc-method-requirement [OBJC2]
00314 ///     objc-interface-decl-list objc-method-proto ';'
00315 ///     objc-interface-decl-list declaration
00316 ///     objc-interface-decl-list ';'
00317 ///
00318 ///   objc-method-requirement: [OBJC2]
00319 ///     @required
00320 ///     @optional
00321 ///
00322 void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, 
00323                                         Decl *CDecl) {
00324   SmallVector<Decl *, 32> allMethods;
00325   SmallVector<Decl *, 16> allProperties;
00326   SmallVector<DeclGroupPtrTy, 8> allTUVariables;
00327   tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
00328 
00329   SourceRange AtEnd;
00330     
00331   while (1) {
00332     // If this is a method prototype, parse it.
00333     if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
00334       if (Decl *methodPrototype =
00335           ParseObjCMethodPrototype(MethodImplKind, false))
00336         allMethods.push_back(methodPrototype);
00337       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
00338       // method definitions.
00339       if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
00340         // We didn't find a semi and we error'ed out. Skip until a ';' or '@'.
00341         SkipUntil(tok::at, StopAtSemi | StopBeforeMatch);
00342         if (Tok.is(tok::semi))
00343           ConsumeToken();
00344       }
00345       continue;
00346     }
00347     if (Tok.is(tok::l_paren)) {
00348       Diag(Tok, diag::err_expected_minus_or_plus);
00349       ParseObjCMethodDecl(Tok.getLocation(), 
00350                           tok::minus, 
00351                           MethodImplKind, false);
00352       continue;
00353     }
00354     // Ignore excess semicolons.
00355     if (Tok.is(tok::semi)) {
00356       ConsumeToken();
00357       continue;
00358     }
00359 
00360     // If we got to the end of the file, exit the loop.
00361     if (isEofOrEom())
00362       break;
00363 
00364     // Code completion within an Objective-C interface.
00365     if (Tok.is(tok::code_completion)) {
00366       Actions.CodeCompleteOrdinaryName(getCurScope(), 
00367                             CurParsedObjCImpl? Sema::PCC_ObjCImplementation
00368                                              : Sema::PCC_ObjCInterface);
00369       return cutOffParsing();
00370     }
00371     
00372     // If we don't have an @ directive, parse it as a function definition.
00373     if (Tok.isNot(tok::at)) {
00374       // The code below does not consume '}'s because it is afraid of eating the
00375       // end of a namespace.  Because of the way this code is structured, an
00376       // erroneous r_brace would cause an infinite loop if not handled here.
00377       if (Tok.is(tok::r_brace))
00378         break;
00379       ParsedAttributesWithRange attrs(AttrFactory);
00380       allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
00381       continue;
00382     }
00383 
00384     // Otherwise, we have an @ directive, eat the @.
00385     SourceLocation AtLoc = ConsumeToken(); // the "@"
00386     if (Tok.is(tok::code_completion)) {
00387       Actions.CodeCompleteObjCAtDirective(getCurScope());
00388       return cutOffParsing();
00389     }
00390 
00391     tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID();
00392 
00393     if (DirectiveKind == tok::objc_end) { // @end -> terminate list
00394       AtEnd.setBegin(AtLoc);
00395       AtEnd.setEnd(Tok.getLocation());
00396       break;
00397     } else if (DirectiveKind == tok::objc_not_keyword) {
00398       Diag(Tok, diag::err_objc_unknown_at);
00399       SkipUntil(tok::semi);
00400       continue;
00401     }
00402 
00403     // Eat the identifier.
00404     ConsumeToken();
00405 
00406     switch (DirectiveKind) {
00407     default:
00408       // FIXME: If someone forgets an @end on a protocol, this loop will
00409       // continue to eat up tons of stuff and spew lots of nonsense errors.  It
00410       // would probably be better to bail out if we saw an @class or @interface
00411       // or something like that.
00412       Diag(AtLoc, diag::err_objc_illegal_interface_qual);
00413       // Skip until we see an '@' or '}' or ';'.
00414       SkipUntil(tok::r_brace, tok::at, StopAtSemi);
00415       break;
00416         
00417     case tok::objc_implementation:
00418     case tok::objc_interface:
00419       Diag(AtLoc, diag::err_objc_missing_end)
00420           << FixItHint::CreateInsertion(AtLoc, "@end\n");
00421       Diag(CDecl->getLocStart(), diag::note_objc_container_start)
00422           << (int) Actions.getObjCContainerKind();
00423       ConsumeToken();
00424       break;
00425         
00426     case tok::objc_required:
00427     case tok::objc_optional:
00428       // This is only valid on protocols.
00429       // FIXME: Should this check for ObjC2 being enabled?
00430       if (contextKey != tok::objc_protocol)
00431         Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
00432       else
00433         MethodImplKind = DirectiveKind;
00434       break;
00435 
00436     case tok::objc_property:
00437       if (!getLangOpts().ObjC2)
00438         Diag(AtLoc, diag::err_objc_properties_require_objc2);
00439 
00440       ObjCDeclSpec OCDS;
00441       SourceLocation LParenLoc;
00442       // Parse property attribute list, if any.
00443       if (Tok.is(tok::l_paren)) {
00444         LParenLoc = Tok.getLocation();
00445         ParseObjCPropertyAttribute(OCDS);
00446       }
00447 
00448       auto ObjCPropertyCallback = [&](ParsingFieldDeclarator &FD) {
00449         if (FD.D.getIdentifier() == nullptr) {
00450           Diag(AtLoc, diag::err_objc_property_requires_field_name)
00451               << FD.D.getSourceRange();
00452           return;
00453         }
00454         if (FD.BitfieldSize) {
00455           Diag(AtLoc, diag::err_objc_property_bitfield)
00456               << FD.D.getSourceRange();
00457           return;
00458         }
00459 
00460         // Install the property declarator into interfaceDecl.
00461         IdentifierInfo *SelName =
00462             OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
00463 
00464         Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName);
00465         IdentifierInfo *SetterName = OCDS.getSetterName();
00466         Selector SetterSel;
00467         if (SetterName)
00468           SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
00469         else
00470           SetterSel = SelectorTable::constructSetterSelector(
00471               PP.getIdentifierTable(), PP.getSelectorTable(),
00472               FD.D.getIdentifier());
00473         bool isOverridingProperty = false;
00474         Decl *Property = Actions.ActOnProperty(
00475             getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
00476             &isOverridingProperty, MethodImplKind);
00477         if (!isOverridingProperty)
00478           allProperties.push_back(Property);
00479 
00480         FD.complete(Property);
00481       };
00482 
00483       // Parse all the comma separated declarators.
00484       ParsingDeclSpec DS(*this);
00485       ParseStructDeclaration(DS, ObjCPropertyCallback);
00486 
00487       ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
00488       break;
00489     }
00490   }
00491 
00492   // We break out of the big loop in two cases: when we see @end or when we see
00493   // EOF.  In the former case, eat the @end.  In the later case, emit an error.
00494   if (Tok.is(tok::code_completion)) {
00495     Actions.CodeCompleteObjCAtDirective(getCurScope());
00496     return cutOffParsing();
00497   } else if (Tok.isObjCAtKeyword(tok::objc_end)) {
00498     ConsumeToken(); // the "end" identifier
00499   } else {
00500     Diag(Tok, diag::err_objc_missing_end)
00501         << FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n");
00502     Diag(CDecl->getLocStart(), diag::note_objc_container_start)
00503         << (int) Actions.getObjCContainerKind();
00504     AtEnd.setBegin(Tok.getLocation());
00505     AtEnd.setEnd(Tok.getLocation());
00506   }
00507 
00508   // Insert collected methods declarations into the @interface object.
00509   // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
00510   Actions.ActOnAtEnd(getCurScope(), AtEnd, allMethods, allTUVariables);
00511 }
00512 
00513 ///   Parse property attribute declarations.
00514 ///
00515 ///   property-attr-decl: '(' property-attrlist ')'
00516 ///   property-attrlist:
00517 ///     property-attribute
00518 ///     property-attrlist ',' property-attribute
00519 ///   property-attribute:
00520 ///     getter '=' identifier
00521 ///     setter '=' identifier ':'
00522 ///     readonly
00523 ///     readwrite
00524 ///     assign
00525 ///     retain
00526 ///     copy
00527 ///     nonatomic
00528 ///     atomic
00529 ///     strong
00530 ///     weak
00531 ///     unsafe_unretained
00532 ///
00533 void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
00534   assert(Tok.getKind() == tok::l_paren);
00535   BalancedDelimiterTracker T(*this, tok::l_paren);
00536   T.consumeOpen();
00537 
00538   while (1) {
00539     if (Tok.is(tok::code_completion)) {
00540       Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS);
00541       return cutOffParsing();
00542     }
00543     const IdentifierInfo *II = Tok.getIdentifierInfo();
00544 
00545     // If this is not an identifier at all, bail out early.
00546     if (!II) {
00547       T.consumeClose();
00548       return;
00549     }
00550 
00551     SourceLocation AttrName = ConsumeToken(); // consume last attribute name
00552 
00553     if (II->isStr("readonly"))
00554       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly);
00555     else if (II->isStr("assign"))
00556       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign);
00557     else if (II->isStr("unsafe_unretained"))
00558       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_unsafe_unretained);
00559     else if (II->isStr("readwrite"))
00560       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite);
00561     else if (II->isStr("retain"))
00562       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain);
00563     else if (II->isStr("strong"))
00564       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_strong);
00565     else if (II->isStr("copy"))
00566       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
00567     else if (II->isStr("nonatomic"))
00568       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
00569     else if (II->isStr("atomic"))
00570       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_atomic);
00571     else if (II->isStr("weak"))
00572       DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_weak);
00573     else if (II->isStr("getter") || II->isStr("setter")) {
00574       bool IsSetter = II->getNameStart()[0] == 's';
00575 
00576       // getter/setter require extra treatment.
00577       unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
00578         diag::err_objc_expected_equal_for_getter;
00579 
00580       if (ExpectAndConsume(tok::equal, DiagID)) {
00581         SkipUntil(tok::r_paren, StopAtSemi);
00582         return;
00583       }
00584 
00585       if (Tok.is(tok::code_completion)) {
00586         if (IsSetter)
00587           Actions.CodeCompleteObjCPropertySetter(getCurScope());
00588         else
00589           Actions.CodeCompleteObjCPropertyGetter(getCurScope());
00590         return cutOffParsing();
00591       }
00592 
00593       
00594       SourceLocation SelLoc;
00595       IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc);
00596 
00597       if (!SelIdent) {
00598         Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
00599           << IsSetter;
00600         SkipUntil(tok::r_paren, StopAtSemi);
00601         return;
00602       }
00603 
00604       if (IsSetter) {
00605         DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
00606         DS.setSetterName(SelIdent);
00607 
00608         if (ExpectAndConsume(tok::colon,
00609                              diag::err_expected_colon_after_setter_name)) {
00610           SkipUntil(tok::r_paren, StopAtSemi);
00611           return;
00612         }
00613       } else {
00614         DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
00615         DS.setGetterName(SelIdent);
00616       }
00617     } else {
00618       Diag(AttrName, diag::err_objc_expected_property_attr) << II;
00619       SkipUntil(tok::r_paren, StopAtSemi);
00620       return;
00621     }
00622 
00623     if (Tok.isNot(tok::comma))
00624       break;
00625 
00626     ConsumeToken();
00627   }
00628 
00629   T.consumeClose();
00630 }
00631 
00632 ///   objc-method-proto:
00633 ///     objc-instance-method objc-method-decl objc-method-attributes[opt]
00634 ///     objc-class-method objc-method-decl objc-method-attributes[opt]
00635 ///
00636 ///   objc-instance-method: '-'
00637 ///   objc-class-method: '+'
00638 ///
00639 ///   objc-method-attributes:         [OBJC2]
00640 ///     __attribute__((deprecated))
00641 ///
00642 Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
00643                                        bool MethodDefinition) {
00644   assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
00645 
00646   tok::TokenKind methodType = Tok.getKind();
00647   SourceLocation mLoc = ConsumeToken();
00648   Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
00649                                     MethodDefinition);
00650   // Since this rule is used for both method declarations and definitions,
00651   // the caller is (optionally) responsible for consuming the ';'.
00652   return MDecl;
00653 }
00654 
00655 ///   objc-selector:
00656 ///     identifier
00657 ///     one of
00658 ///       enum struct union if else while do for switch case default
00659 ///       break continue return goto asm sizeof typeof __alignof
00660 ///       unsigned long const short volatile signed restrict _Complex
00661 ///       in out inout bycopy byref oneway int char float double void _Bool
00662 ///
00663 IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
00664 
00665   switch (Tok.getKind()) {
00666   default:
00667     return nullptr;
00668   case tok::ampamp:
00669   case tok::ampequal:
00670   case tok::amp:
00671   case tok::pipe:
00672   case tok::tilde:
00673   case tok::exclaim:
00674   case tok::exclaimequal:
00675   case tok::pipepipe:
00676   case tok::pipeequal:
00677   case tok::caret:
00678   case tok::caretequal: {
00679     std::string ThisTok(PP.getSpelling(Tok));
00680     if (isLetter(ThisTok[0])) {
00681       IdentifierInfo *II = &PP.getIdentifierTable().get(ThisTok.data());
00682       Tok.setKind(tok::identifier);
00683       SelectorLoc = ConsumeToken();
00684       return II;
00685     }
00686     return nullptr;
00687   }
00688       
00689   case tok::identifier:
00690   case tok::kw_asm:
00691   case tok::kw_auto:
00692   case tok::kw_bool:
00693   case tok::kw_break:
00694   case tok::kw_case:
00695   case tok::kw_catch:
00696   case tok::kw_char:
00697   case tok::kw_class:
00698   case tok::kw_const:
00699   case tok::kw_const_cast:
00700   case tok::kw_continue:
00701   case tok::kw_default:
00702   case tok::kw_delete:
00703   case tok::kw_do:
00704   case tok::kw_double:
00705   case tok::kw_dynamic_cast:
00706   case tok::kw_else:
00707   case tok::kw_enum:
00708   case tok::kw_explicit:
00709   case tok::kw_export:
00710   case tok::kw_extern:
00711   case tok::kw_false:
00712   case tok::kw_float:
00713   case tok::kw_for:
00714   case tok::kw_friend:
00715   case tok::kw_goto:
00716   case tok::kw_if:
00717   case tok::kw_inline:
00718   case tok::kw_int:
00719   case tok::kw_long:
00720   case tok::kw_mutable:
00721   case tok::kw_namespace:
00722   case tok::kw_new:
00723   case tok::kw_operator:
00724   case tok::kw_private:
00725   case tok::kw_protected:
00726   case tok::kw_public:
00727   case tok::kw_register:
00728   case tok::kw_reinterpret_cast:
00729   case tok::kw_restrict:
00730   case tok::kw_return:
00731   case tok::kw_short:
00732   case tok::kw_signed:
00733   case tok::kw_sizeof:
00734   case tok::kw_static:
00735   case tok::kw_static_cast:
00736   case tok::kw_struct:
00737   case tok::kw_switch:
00738   case tok::kw_template:
00739   case tok::kw_this:
00740   case tok::kw_throw:
00741   case tok::kw_true:
00742   case tok::kw_try:
00743   case tok::kw_typedef:
00744   case tok::kw_typeid:
00745   case tok::kw_typename:
00746   case tok::kw_typeof:
00747   case tok::kw_union:
00748   case tok::kw_unsigned:
00749   case tok::kw_using:
00750   case tok::kw_virtual:
00751   case tok::kw_void:
00752   case tok::kw_volatile:
00753   case tok::kw_wchar_t:
00754   case tok::kw_while:
00755   case tok::kw__Bool:
00756   case tok::kw__Complex:
00757   case tok::kw___alignof:
00758     IdentifierInfo *II = Tok.getIdentifierInfo();
00759     SelectorLoc = ConsumeToken();
00760     return II;
00761   }
00762 }
00763 
00764 ///  objc-for-collection-in: 'in'
00765 ///
00766 bool Parser::isTokIdentifier_in() const {
00767   // FIXME: May have to do additional look-ahead to only allow for
00768   // valid tokens following an 'in'; such as an identifier, unary operators,
00769   // '[' etc.
00770   return (getLangOpts().ObjC2 && Tok.is(tok::identifier) &&
00771           Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
00772 }
00773 
00774 /// ParseObjCTypeQualifierList - This routine parses the objective-c's type
00775 /// qualifier list and builds their bitmask representation in the input
00776 /// argument.
00777 ///
00778 ///   objc-type-qualifiers:
00779 ///     objc-type-qualifier
00780 ///     objc-type-qualifiers objc-type-qualifier
00781 ///
00782 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
00783                                         Declarator::TheContext Context) {
00784   assert(Context == Declarator::ObjCParameterContext ||
00785          Context == Declarator::ObjCResultContext);
00786 
00787   while (1) {
00788     if (Tok.is(tok::code_completion)) {
00789       Actions.CodeCompleteObjCPassingType(getCurScope(), DS, 
00790                           Context == Declarator::ObjCParameterContext);
00791       return cutOffParsing();
00792     }
00793     
00794     if (Tok.isNot(tok::identifier))
00795       return;
00796 
00797     const IdentifierInfo *II = Tok.getIdentifierInfo();
00798     for (unsigned i = 0; i != objc_NumQuals; ++i) {
00799       if (II != ObjCTypeQuals[i])
00800         continue;
00801 
00802       ObjCDeclSpec::ObjCDeclQualifier Qual;
00803       switch (i) {
00804       default: llvm_unreachable("Unknown decl qualifier");
00805       case objc_in:     Qual = ObjCDeclSpec::DQ_In; break;
00806       case objc_out:    Qual = ObjCDeclSpec::DQ_Out; break;
00807       case objc_inout:  Qual = ObjCDeclSpec::DQ_Inout; break;
00808       case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break;
00809       case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break;
00810       case objc_byref:  Qual = ObjCDeclSpec::DQ_Byref; break;
00811       }
00812       DS.setObjCDeclQualifier(Qual);
00813       ConsumeToken();
00814       II = nullptr;
00815       break;
00816     }
00817 
00818     // If this wasn't a recognized qualifier, bail out.
00819     if (II) return;
00820   }
00821 }
00822 
00823 /// Take all the decl attributes out of the given list and add
00824 /// them to the given attribute set.
00825 static void takeDeclAttributes(ParsedAttributes &attrs,
00826                                AttributeList *list) {
00827   while (list) {
00828     AttributeList *cur = list;
00829     list = cur->getNext();
00830 
00831     if (!cur->isUsedAsTypeAttr()) {
00832       // Clear out the next pointer.  We're really completely
00833       // destroying the internal invariants of the declarator here,
00834       // but it doesn't matter because we're done with it.
00835       cur->setNext(nullptr);
00836       attrs.add(cur);
00837     }
00838   }
00839 }
00840 
00841 /// takeDeclAttributes - Take all the decl attributes from the given
00842 /// declarator and add them to the given list.
00843 static void takeDeclAttributes(ParsedAttributes &attrs,
00844                                Declarator &D) {
00845   // First, take ownership of all attributes.
00846   attrs.getPool().takeAllFrom(D.getAttributePool());
00847   attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool());
00848 
00849   // Now actually move the attributes over.
00850   takeDeclAttributes(attrs, D.getDeclSpec().getAttributes().getList());
00851   takeDeclAttributes(attrs, D.getAttributes());
00852   for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
00853     takeDeclAttributes(attrs,
00854                   const_cast<AttributeList*>(D.getTypeObject(i).getAttrs()));
00855 }
00856 
00857 ///   objc-type-name:
00858 ///     '(' objc-type-qualifiers[opt] type-name ')'
00859 ///     '(' objc-type-qualifiers[opt] ')'
00860 ///
00861 ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, 
00862                                      Declarator::TheContext context,
00863                                      ParsedAttributes *paramAttrs) {
00864   assert(context == Declarator::ObjCParameterContext ||
00865          context == Declarator::ObjCResultContext);
00866   assert((paramAttrs != nullptr) ==
00867          (context == Declarator::ObjCParameterContext));
00868 
00869   assert(Tok.is(tok::l_paren) && "expected (");
00870 
00871   BalancedDelimiterTracker T(*this, tok::l_paren);
00872   T.consumeOpen();
00873 
00874   SourceLocation TypeStartLoc = Tok.getLocation();
00875   ObjCDeclContextSwitch ObjCDC(*this);
00876 
00877   // Parse type qualifiers, in, inout, etc.
00878   ParseObjCTypeQualifierList(DS, context);
00879 
00880   ParsedType Ty;
00881   if (isTypeSpecifierQualifier()) {
00882     // Parse an abstract declarator.
00883     DeclSpec declSpec(AttrFactory);
00884     declSpec.setObjCQualifiers(&DS);
00885     ParseSpecifierQualifierList(declSpec);
00886     declSpec.SetRangeEnd(Tok.getLocation());
00887     Declarator declarator(declSpec, context);
00888     ParseDeclarator(declarator);
00889 
00890     // If that's not invalid, extract a type.
00891     if (!declarator.isInvalidType()) {
00892       TypeResult type = Actions.ActOnTypeName(getCurScope(), declarator);
00893       if (!type.isInvalid())
00894         Ty = type.get();
00895 
00896       // If we're parsing a parameter, steal all the decl attributes
00897       // and add them to the decl spec.
00898       if (context == Declarator::ObjCParameterContext)
00899         takeDeclAttributes(*paramAttrs, declarator);
00900     }
00901   } else if (context == Declarator::ObjCResultContext &&
00902              Tok.is(tok::identifier)) {
00903     if (!Ident_instancetype)
00904       Ident_instancetype = PP.getIdentifierInfo("instancetype");
00905     
00906     if (Tok.getIdentifierInfo() == Ident_instancetype) {
00907       Ty = Actions.ActOnObjCInstanceType(Tok.getLocation());
00908       ConsumeToken();
00909     }
00910   }
00911 
00912   if (Tok.is(tok::r_paren))
00913     T.consumeClose();
00914   else if (Tok.getLocation() == TypeStartLoc) {
00915     // If we didn't eat any tokens, then this isn't a type.
00916     Diag(Tok, diag::err_expected_type);
00917     SkipUntil(tok::r_paren, StopAtSemi);
00918   } else {
00919     // Otherwise, we found *something*, but didn't get a ')' in the right
00920     // place.  Emit an error then return what we have as the type.
00921     T.consumeClose();
00922   }
00923   return Ty;
00924 }
00925 
00926 ///   objc-method-decl:
00927 ///     objc-selector
00928 ///     objc-keyword-selector objc-parmlist[opt]
00929 ///     objc-type-name objc-selector
00930 ///     objc-type-name objc-keyword-selector objc-parmlist[opt]
00931 ///
00932 ///   objc-keyword-selector:
00933 ///     objc-keyword-decl
00934 ///     objc-keyword-selector objc-keyword-decl
00935 ///
00936 ///   objc-keyword-decl:
00937 ///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
00938 ///     objc-selector ':' objc-keyword-attributes[opt] identifier
00939 ///     ':' objc-type-name objc-keyword-attributes[opt] identifier
00940 ///     ':' objc-keyword-attributes[opt] identifier
00941 ///
00942 ///   objc-parmlist:
00943 ///     objc-parms objc-ellipsis[opt]
00944 ///
00945 ///   objc-parms:
00946 ///     objc-parms , parameter-declaration
00947 ///
00948 ///   objc-ellipsis:
00949 ///     , ...
00950 ///
00951 ///   objc-keyword-attributes:         [OBJC2]
00952 ///     __attribute__((unused))
00953 ///
00954 Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
00955                                   tok::TokenKind mType,
00956                                   tok::ObjCKeywordKind MethodImplKind,
00957                                   bool MethodDefinition) {
00958   ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
00959 
00960   if (Tok.is(tok::code_completion)) {
00961     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
00962                                        /*ReturnType=*/ ParsedType());
00963     cutOffParsing();
00964     return nullptr;
00965   }
00966 
00967   // Parse the return type if present.
00968   ParsedType ReturnType;
00969   ObjCDeclSpec DSRet;
00970   if (Tok.is(tok::l_paren))
00971     ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext,
00972                                    nullptr);
00973 
00974   // If attributes exist before the method, parse them.
00975   ParsedAttributes methodAttrs(AttrFactory);
00976   if (getLangOpts().ObjC2)
00977     MaybeParseGNUAttributes(methodAttrs);
00978 
00979   if (Tok.is(tok::code_completion)) {
00980     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
00981                                        ReturnType);
00982     cutOffParsing();
00983     return nullptr;
00984   }
00985 
00986   // Now parse the selector.
00987   SourceLocation selLoc;
00988   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
00989 
00990   // An unnamed colon is valid.
00991   if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
00992     Diag(Tok, diag::err_expected_selector_for_method)
00993       << SourceRange(mLoc, Tok.getLocation());
00994     // Skip until we get a ; or @.
00995     SkipUntil(tok::at, StopAtSemi | StopBeforeMatch);
00996     return nullptr;
00997   }
00998 
00999   SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
01000   if (Tok.isNot(tok::colon)) {
01001     // If attributes exist after the method, parse them.
01002     if (getLangOpts().ObjC2)
01003       MaybeParseGNUAttributes(methodAttrs);
01004 
01005     Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
01006     Decl *Result
01007          = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
01008                                           mType, DSRet, ReturnType, 
01009                                           selLoc, Sel, nullptr,
01010                                           CParamInfo.data(), CParamInfo.size(),
01011                                           methodAttrs.getList(), MethodImplKind,
01012                                           false, MethodDefinition);
01013     PD.complete(Result);
01014     return Result;
01015   }
01016 
01017   SmallVector<IdentifierInfo *, 12> KeyIdents;
01018   SmallVector<SourceLocation, 12> KeyLocs;
01019   SmallVector<Sema::ObjCArgInfo, 12> ArgInfos;
01020   ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
01021                             Scope::FunctionDeclarationScope | Scope::DeclScope);
01022 
01023   AttributePool allParamAttrs(AttrFactory);
01024   while (1) {
01025     ParsedAttributes paramAttrs(AttrFactory);
01026     Sema::ObjCArgInfo ArgInfo;
01027 
01028     // Each iteration parses a single keyword argument.
01029     if (ExpectAndConsume(tok::colon))
01030       break;
01031 
01032     ArgInfo.Type = ParsedType();
01033     if (Tok.is(tok::l_paren)) // Parse the argument type if present.
01034       ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec,
01035                                        Declarator::ObjCParameterContext,
01036                                        &paramAttrs);
01037 
01038     // If attributes exist before the argument name, parse them.
01039     // Regardless, collect all the attributes we've parsed so far.
01040     ArgInfo.ArgAttrs = nullptr;
01041     if (getLangOpts().ObjC2) {
01042       MaybeParseGNUAttributes(paramAttrs);
01043       ArgInfo.ArgAttrs = paramAttrs.getList();
01044     }
01045 
01046     // Code completion for the next piece of the selector.
01047     if (Tok.is(tok::code_completion)) {
01048       KeyIdents.push_back(SelIdent);
01049       Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), 
01050                                                  mType == tok::minus,
01051                                                  /*AtParameterName=*/true,
01052                                                  ReturnType, KeyIdents);
01053       cutOffParsing();
01054       return nullptr;
01055     }
01056     
01057     if (Tok.isNot(tok::identifier)) {
01058       Diag(Tok, diag::err_expected)
01059           << tok::identifier; // missing argument name.
01060       break;
01061     }
01062 
01063     ArgInfo.Name = Tok.getIdentifierInfo();
01064     ArgInfo.NameLoc = Tok.getLocation();
01065     ConsumeToken(); // Eat the identifier.
01066 
01067     ArgInfos.push_back(ArgInfo);
01068     KeyIdents.push_back(SelIdent);
01069     KeyLocs.push_back(selLoc);
01070 
01071     // Make sure the attributes persist.
01072     allParamAttrs.takeAllFrom(paramAttrs.getPool());
01073 
01074     // Code completion for the next piece of the selector.
01075     if (Tok.is(tok::code_completion)) {
01076       Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), 
01077                                                  mType == tok::minus,
01078                                                  /*AtParameterName=*/false,
01079                                                  ReturnType, KeyIdents);
01080       cutOffParsing();
01081       return nullptr;
01082     }
01083     
01084     // Check for another keyword selector.
01085     SelIdent = ParseObjCSelectorPiece(selLoc);
01086     if (!SelIdent && Tok.isNot(tok::colon))
01087       break;
01088     if (!SelIdent) {
01089       SourceLocation ColonLoc = Tok.getLocation();
01090       if (PP.getLocForEndOfToken(ArgInfo.NameLoc) == ColonLoc) {
01091         Diag(ArgInfo.NameLoc, diag::warn_missing_selector_name) << ArgInfo.Name;
01092         Diag(ArgInfo.NameLoc, diag::note_missing_selector_name) << ArgInfo.Name;
01093         Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.Name;
01094       }
01095     }
01096     // We have a selector or a colon, continue parsing.
01097   }
01098 
01099   bool isVariadic = false;
01100   bool cStyleParamWarned = false;
01101   // Parse the (optional) parameter list.
01102   while (Tok.is(tok::comma)) {
01103     ConsumeToken();
01104     if (Tok.is(tok::ellipsis)) {
01105       isVariadic = true;
01106       ConsumeToken();
01107       break;
01108     }
01109     if (!cStyleParamWarned) {
01110       Diag(Tok, diag::warn_cstyle_param);
01111       cStyleParamWarned = true;
01112     }
01113     DeclSpec DS(AttrFactory);
01114     ParseDeclarationSpecifiers(DS);
01115     // Parse the declarator.
01116     Declarator ParmDecl(DS, Declarator::PrototypeContext);
01117     ParseDeclarator(ParmDecl);
01118     IdentifierInfo *ParmII = ParmDecl.getIdentifier();
01119     Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
01120     CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
01121                                                     ParmDecl.getIdentifierLoc(), 
01122                                                     Param,
01123                                                     nullptr));
01124   }
01125 
01126   // FIXME: Add support for optional parameter list...
01127   // If attributes exist after the method, parse them.
01128   if (getLangOpts().ObjC2)
01129     MaybeParseGNUAttributes(methodAttrs);
01130   
01131   if (KeyIdents.size() == 0)
01132     return nullptr;
01133 
01134   Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
01135                                                    &KeyIdents[0]);
01136   Decl *Result
01137        = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
01138                                         mType, DSRet, ReturnType, 
01139                                         KeyLocs, Sel, &ArgInfos[0], 
01140                                         CParamInfo.data(), CParamInfo.size(),
01141                                         methodAttrs.getList(),
01142                                         MethodImplKind, isVariadic, MethodDefinition);
01143   
01144   PD.complete(Result);
01145   return Result;
01146 }
01147 
01148 ///   objc-protocol-refs:
01149 ///     '<' identifier-list '>'
01150 ///
01151 bool Parser::
01152 ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
01153                             SmallVectorImpl<SourceLocation> &ProtocolLocs,
01154                             bool WarnOnDeclarations,
01155                             SourceLocation &LAngleLoc, SourceLocation &EndLoc) {
01156   assert(Tok.is(tok::less) && "expected <");
01157 
01158   LAngleLoc = ConsumeToken(); // the "<"
01159 
01160   SmallVector<IdentifierLocPair, 8> ProtocolIdents;
01161 
01162   while (1) {
01163     if (Tok.is(tok::code_completion)) {
01164       Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(), 
01165                                                  ProtocolIdents.size());
01166       cutOffParsing();
01167       return true;
01168     }
01169 
01170     if (Tok.isNot(tok::identifier)) {
01171       Diag(Tok, diag::err_expected) << tok::identifier;
01172       SkipUntil(tok::greater, StopAtSemi);
01173       return true;
01174     }
01175     ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
01176                                        Tok.getLocation()));
01177     ProtocolLocs.push_back(Tok.getLocation());
01178     ConsumeToken();
01179 
01180     if (!TryConsumeToken(tok::comma))
01181       break;
01182   }
01183 
01184   // Consume the '>'.
01185   if (ParseGreaterThanInTemplateList(EndLoc, /*ConsumeLastToken=*/true))
01186     return true;
01187 
01188   // Convert the list of protocols identifiers into a list of protocol decls.
01189   Actions.FindProtocolDeclaration(WarnOnDeclarations,
01190                                   &ProtocolIdents[0], ProtocolIdents.size(),
01191                                   Protocols);
01192   return false;
01193 }
01194 
01195 /// \brief Parse the Objective-C protocol qualifiers that follow a typename
01196 /// in a decl-specifier-seq, starting at the '<'.
01197 bool Parser::ParseObjCProtocolQualifiers(DeclSpec &DS) {
01198   assert(Tok.is(tok::less) && "Protocol qualifiers start with '<'");
01199   assert(getLangOpts().ObjC1 && "Protocol qualifiers only exist in Objective-C");
01200   SourceLocation LAngleLoc, EndProtoLoc;
01201   SmallVector<Decl *, 8> ProtocolDecl;
01202   SmallVector<SourceLocation, 8> ProtocolLocs;
01203   bool Result = ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
01204                                             LAngleLoc, EndProtoLoc);
01205   DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
01206                            ProtocolLocs.data(), LAngleLoc);
01207   if (EndProtoLoc.isValid())
01208     DS.SetRangeEnd(EndProtoLoc);
01209   return Result;
01210 }
01211 
01212 void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,
01213                                  BalancedDelimiterTracker &T,
01214                                  SmallVectorImpl<Decl *> &AllIvarDecls,
01215                                  bool RBraceMissing) {
01216   if (!RBraceMissing)
01217     T.consumeClose();
01218   
01219   Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
01220   Actions.ActOnLastBitfield(T.getCloseLocation(), AllIvarDecls);
01221   Actions.ActOnObjCContainerFinishDefinition();
01222   // Call ActOnFields() even if we don't have any decls. This is useful
01223   // for code rewriting tools that need to be aware of the empty list.
01224   Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
01225                       AllIvarDecls,
01226                       T.getOpenLocation(), T.getCloseLocation(), nullptr);
01227 }
01228 
01229 ///   objc-class-instance-variables:
01230 ///     '{' objc-instance-variable-decl-list[opt] '}'
01231 ///
01232 ///   objc-instance-variable-decl-list:
01233 ///     objc-visibility-spec
01234 ///     objc-instance-variable-decl ';'
01235 ///     ';'
01236 ///     objc-instance-variable-decl-list objc-visibility-spec
01237 ///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
01238 ///     objc-instance-variable-decl-list ';'
01239 ///
01240 ///   objc-visibility-spec:
01241 ///     @private
01242 ///     @protected
01243 ///     @public
01244 ///     @package [OBJC2]
01245 ///
01246 ///   objc-instance-variable-decl:
01247 ///     struct-declaration
01248 ///
01249 void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
01250                                              tok::ObjCKeywordKind visibility,
01251                                              SourceLocation atLoc) {
01252   assert(Tok.is(tok::l_brace) && "expected {");
01253   SmallVector<Decl *, 32> AllIvarDecls;
01254     
01255   ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
01256   ObjCDeclContextSwitch ObjCDC(*this);
01257 
01258   BalancedDelimiterTracker T(*this, tok::l_brace);
01259   T.consumeOpen();
01260   // While we still have something to read, read the instance variables.
01261   while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
01262     // Each iteration of this loop reads one objc-instance-variable-decl.
01263 
01264     // Check for extraneous top-level semicolon.
01265     if (Tok.is(tok::semi)) {
01266       ConsumeExtraSemi(InstanceVariableList);
01267       continue;
01268     }
01269 
01270     // Set the default visibility to private.
01271     if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec
01272       if (Tok.is(tok::code_completion)) {
01273         Actions.CodeCompleteObjCAtVisibility(getCurScope());
01274         return cutOffParsing();
01275       }
01276       
01277       switch (Tok.getObjCKeywordID()) {
01278       case tok::objc_private:
01279       case tok::objc_public:
01280       case tok::objc_protected:
01281       case tok::objc_package:
01282         visibility = Tok.getObjCKeywordID();
01283         ConsumeToken();
01284         continue;
01285 
01286       case tok::objc_end:
01287         Diag(Tok, diag::err_objc_unexpected_atend);
01288         Tok.setLocation(Tok.getLocation().getLocWithOffset(-1));
01289         Tok.setKind(tok::at);
01290         Tok.setLength(1);
01291         PP.EnterToken(Tok);
01292         HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
01293                                          T, AllIvarDecls, true);
01294         return;
01295           
01296       default:
01297         Diag(Tok, diag::err_objc_illegal_visibility_spec);
01298         continue;
01299       }
01300     }
01301 
01302     if (Tok.is(tok::code_completion)) {
01303       Actions.CodeCompleteOrdinaryName(getCurScope(), 
01304                                        Sema::PCC_ObjCInstanceVariableList);
01305       return cutOffParsing();
01306     }
01307 
01308     auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) {
01309       Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
01310       // Install the declarator into the interface decl.
01311       Decl *Field = Actions.ActOnIvar(
01312           getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
01313           FD.BitfieldSize, visibility);
01314       Actions.ActOnObjCContainerFinishDefinition();
01315       if (Field)
01316         AllIvarDecls.push_back(Field);
01317       FD.complete(Field);
01318     };
01319 
01320     // Parse all the comma separated declarators.
01321     ParsingDeclSpec DS(*this);
01322     ParseStructDeclaration(DS, ObjCIvarCallback);
01323 
01324     if (Tok.is(tok::semi)) {
01325       ConsumeToken();
01326     } else {
01327       Diag(Tok, diag::err_expected_semi_decl_list);
01328       // Skip to end of block or statement
01329       SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
01330     }
01331   }
01332   HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
01333                                    T, AllIvarDecls, false);
01334   return;
01335 }
01336 
01337 ///   objc-protocol-declaration:
01338 ///     objc-protocol-definition
01339 ///     objc-protocol-forward-reference
01340 ///
01341 ///   objc-protocol-definition:
01342 ///     \@protocol identifier
01343 ///       objc-protocol-refs[opt]
01344 ///       objc-interface-decl-list
01345 ///     \@end
01346 ///
01347 ///   objc-protocol-forward-reference:
01348 ///     \@protocol identifier-list ';'
01349 ///
01350 ///   "\@protocol identifier ;" should be resolved as "\@protocol
01351 ///   identifier-list ;": objc-interface-decl-list may not start with a
01352 ///   semicolon in the first alternative if objc-protocol-refs are omitted.
01353 Parser::DeclGroupPtrTy 
01354 Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
01355                                        ParsedAttributes &attrs) {
01356   assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
01357          "ParseObjCAtProtocolDeclaration(): Expected @protocol");
01358   ConsumeToken(); // the "protocol" identifier
01359 
01360   if (Tok.is(tok::code_completion)) {
01361     Actions.CodeCompleteObjCProtocolDecl(getCurScope());
01362     cutOffParsing();
01363     return DeclGroupPtrTy();
01364   }
01365 
01366   MaybeSkipAttributes(tok::objc_protocol);
01367 
01368   if (Tok.isNot(tok::identifier)) {
01369     Diag(Tok, diag::err_expected) << tok::identifier; // missing protocol name.
01370     return DeclGroupPtrTy();
01371   }
01372   // Save the protocol name, then consume it.
01373   IdentifierInfo *protocolName = Tok.getIdentifierInfo();
01374   SourceLocation nameLoc = ConsumeToken();
01375 
01376   if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol.
01377     IdentifierLocPair ProtoInfo(protocolName, nameLoc);
01378     return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
01379                                                    attrs.getList());
01380   }
01381 
01382   CheckNestedObjCContexts(AtLoc);
01383 
01384   if (Tok.is(tok::comma)) { // list of forward declarations.
01385     SmallVector<IdentifierLocPair, 8> ProtocolRefs;
01386     ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
01387 
01388     // Parse the list of forward declarations.
01389     while (1) {
01390       ConsumeToken(); // the ','
01391       if (Tok.isNot(tok::identifier)) {
01392         Diag(Tok, diag::err_expected) << tok::identifier;
01393         SkipUntil(tok::semi);
01394         return DeclGroupPtrTy();
01395       }
01396       ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
01397                                                Tok.getLocation()));
01398       ConsumeToken(); // the identifier
01399 
01400       if (Tok.isNot(tok::comma))
01401         break;
01402     }
01403     // Consume the ';'.
01404     if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol"))
01405       return DeclGroupPtrTy();
01406 
01407     return Actions.ActOnForwardProtocolDeclaration(AtLoc,
01408                                                    &ProtocolRefs[0],
01409                                                    ProtocolRefs.size(),
01410                                                    attrs.getList());
01411   }
01412 
01413   // Last, and definitely not least, parse a protocol declaration.
01414   SourceLocation LAngleLoc, EndProtoLoc;
01415 
01416   SmallVector<Decl *, 8> ProtocolRefs;
01417   SmallVector<SourceLocation, 8> ProtocolLocs;
01418   if (Tok.is(tok::less) &&
01419       ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false,
01420                                   LAngleLoc, EndProtoLoc))
01421     return DeclGroupPtrTy();
01422 
01423   Decl *ProtoType =
01424     Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
01425                                         ProtocolRefs.data(),
01426                                         ProtocolRefs.size(),
01427                                         ProtocolLocs.data(),
01428                                         EndProtoLoc, attrs.getList());
01429 
01430   ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
01431   return Actions.ConvertDeclToDeclGroup(ProtoType);
01432 }
01433 
01434 ///   objc-implementation:
01435 ///     objc-class-implementation-prologue
01436 ///     objc-category-implementation-prologue
01437 ///
01438 ///   objc-class-implementation-prologue:
01439 ///     @implementation identifier objc-superclass[opt]
01440 ///       objc-class-instance-variables[opt]
01441 ///
01442 ///   objc-category-implementation-prologue:
01443 ///     @implementation identifier ( identifier )
01444 Parser::DeclGroupPtrTy
01445 Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
01446   assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
01447          "ParseObjCAtImplementationDeclaration(): Expected @implementation");
01448   CheckNestedObjCContexts(AtLoc);
01449   ConsumeToken(); // the "implementation" identifier
01450 
01451   // Code completion after '@implementation'.
01452   if (Tok.is(tok::code_completion)) {
01453     Actions.CodeCompleteObjCImplementationDecl(getCurScope());
01454     cutOffParsing();
01455     return DeclGroupPtrTy();
01456   }
01457 
01458   MaybeSkipAttributes(tok::objc_implementation);
01459 
01460   if (Tok.isNot(tok::identifier)) {
01461     Diag(Tok, diag::err_expected)
01462         << tok::identifier; // missing class or category name.
01463     return DeclGroupPtrTy();
01464   }
01465   // We have a class or category name - consume it.
01466   IdentifierInfo *nameId = Tok.getIdentifierInfo();
01467   SourceLocation nameLoc = ConsumeToken(); // consume class or category name
01468   Decl *ObjCImpDecl = nullptr;
01469 
01470   if (Tok.is(tok::l_paren)) {
01471     // we have a category implementation.
01472     ConsumeParen();
01473     SourceLocation categoryLoc, rparenLoc;
01474     IdentifierInfo *categoryId = nullptr;
01475 
01476     if (Tok.is(tok::code_completion)) {
01477       Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
01478       cutOffParsing();
01479       return DeclGroupPtrTy();
01480     }
01481     
01482     if (Tok.is(tok::identifier)) {
01483       categoryId = Tok.getIdentifierInfo();
01484       categoryLoc = ConsumeToken();
01485     } else {
01486       Diag(Tok, diag::err_expected)
01487           << tok::identifier; // missing category name.
01488       return DeclGroupPtrTy();
01489     }
01490     if (Tok.isNot(tok::r_paren)) {
01491       Diag(Tok, diag::err_expected) << tok::r_paren;
01492       SkipUntil(tok::r_paren); // don't stop at ';'
01493       return DeclGroupPtrTy();
01494     }
01495     rparenLoc = ConsumeParen();
01496     if (Tok.is(tok::less)) { // we have illegal '<' try to recover
01497       Diag(Tok, diag::err_unexpected_protocol_qualifier);
01498       AttributeFactory attr;
01499       DeclSpec DS(attr);
01500       (void)ParseObjCProtocolQualifiers(DS);
01501     }
01502     ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
01503                                     AtLoc, nameId, nameLoc, categoryId,
01504                                     categoryLoc);
01505 
01506   } else {
01507     // We have a class implementation
01508     SourceLocation superClassLoc;
01509     IdentifierInfo *superClassId = nullptr;
01510     if (TryConsumeToken(tok::colon)) {
01511       // We have a super class
01512       if (Tok.isNot(tok::identifier)) {
01513         Diag(Tok, diag::err_expected)
01514             << tok::identifier; // missing super class name.
01515         return DeclGroupPtrTy();
01516       }
01517       superClassId = Tok.getIdentifierInfo();
01518       superClassLoc = ConsumeToken(); // Consume super class name
01519     }
01520     ObjCImpDecl = Actions.ActOnStartClassImplementation(
01521                                     AtLoc, nameId, nameLoc,
01522                                     superClassId, superClassLoc);
01523   
01524     if (Tok.is(tok::l_brace)) // we have ivars
01525       ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
01526     else if (Tok.is(tok::less)) { // we have illegal '<' try to recover
01527       Diag(Tok, diag::err_unexpected_protocol_qualifier);
01528       // try to recover.
01529       AttributeFactory attr;
01530       DeclSpec DS(attr);
01531       (void)ParseObjCProtocolQualifiers(DS);
01532     }
01533   }
01534   assert(ObjCImpDecl);
01535 
01536   SmallVector<Decl *, 8> DeclsInGroup;
01537 
01538   {
01539     ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
01540     while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
01541       ParsedAttributesWithRange attrs(AttrFactory);
01542       MaybeParseCXX11Attributes(attrs);
01543       MaybeParseMicrosoftAttributes(attrs);
01544       if (DeclGroupPtrTy DGP = ParseExternalDeclaration(attrs)) {
01545         DeclGroupRef DG = DGP.get();
01546         DeclsInGroup.append(DG.begin(), DG.end());
01547       }
01548     }
01549   }
01550 
01551   return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup);
01552 }
01553 
01554 Parser::DeclGroupPtrTy
01555 Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
01556   assert(Tok.isObjCAtKeyword(tok::objc_end) &&
01557          "ParseObjCAtEndDeclaration(): Expected @end");
01558   ConsumeToken(); // the "end" identifier
01559   if (CurParsedObjCImpl)
01560     CurParsedObjCImpl->finish(atEnd);
01561   else
01562     // missing @implementation
01563     Diag(atEnd.getBegin(), diag::err_expected_objc_container);
01564   return DeclGroupPtrTy();
01565 }
01566 
01567 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
01568   if (!Finished) {
01569     finish(P.Tok.getLocation());
01570     if (P.isEofOrEom()) {
01571       P.Diag(P.Tok, diag::err_objc_missing_end)
01572           << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n@end\n");
01573       P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
01574           << Sema::OCK_Implementation;
01575     }
01576   }
01577   P.CurParsedObjCImpl = nullptr;
01578   assert(LateParsedObjCMethods.empty());
01579 }
01580 
01581 void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
01582   assert(!Finished);
01583   P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl);
01584   for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
01585     P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], 
01586                                true/*Methods*/);
01587 
01588   P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd);
01589 
01590   if (HasCFunction)
01591     for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
01592       P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i], 
01593                                  false/*c-functions*/);
01594   
01595   /// \brief Clear and free the cached objc methods.
01596   for (LateParsedObjCMethodContainer::iterator
01597          I = LateParsedObjCMethods.begin(),
01598          E = LateParsedObjCMethods.end(); I != E; ++I)
01599     delete *I;
01600   LateParsedObjCMethods.clear();
01601 
01602   Finished = true;
01603 }
01604 
01605 ///   compatibility-alias-decl:
01606 ///     @compatibility_alias alias-name  class-name ';'
01607 ///
01608 Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
01609   assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
01610          "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
01611   ConsumeToken(); // consume compatibility_alias
01612   if (Tok.isNot(tok::identifier)) {
01613     Diag(Tok, diag::err_expected) << tok::identifier;
01614     return nullptr;
01615   }
01616   IdentifierInfo *aliasId = Tok.getIdentifierInfo();
01617   SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
01618   if (Tok.isNot(tok::identifier)) {
01619     Diag(Tok, diag::err_expected) << tok::identifier;
01620     return nullptr;
01621   }
01622   IdentifierInfo *classId = Tok.getIdentifierInfo();
01623   SourceLocation classLoc = ConsumeToken(); // consume class-name;
01624   ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias");
01625   return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
01626                                          classId, classLoc);
01627 }
01628 
01629 ///   property-synthesis:
01630 ///     @synthesize property-ivar-list ';'
01631 ///
01632 ///   property-ivar-list:
01633 ///     property-ivar
01634 ///     property-ivar-list ',' property-ivar
01635 ///
01636 ///   property-ivar:
01637 ///     identifier
01638 ///     identifier '=' identifier
01639 ///
01640 Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
01641   assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
01642          "ParseObjCPropertySynthesize(): Expected '@synthesize'");
01643   ConsumeToken(); // consume synthesize
01644 
01645   while (true) {
01646     if (Tok.is(tok::code_completion)) {
01647       Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
01648       cutOffParsing();
01649       return nullptr;
01650     }
01651     
01652     if (Tok.isNot(tok::identifier)) {
01653       Diag(Tok, diag::err_synthesized_property_name);
01654       SkipUntil(tok::semi);
01655       return nullptr;
01656     }
01657 
01658     IdentifierInfo *propertyIvar = nullptr;
01659     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
01660     SourceLocation propertyLoc = ConsumeToken(); // consume property name
01661     SourceLocation propertyIvarLoc;
01662     if (TryConsumeToken(tok::equal)) {
01663       // property '=' ivar-name
01664       if (Tok.is(tok::code_completion)) {
01665         Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
01666         cutOffParsing();
01667         return nullptr;
01668       }
01669       
01670       if (Tok.isNot(tok::identifier)) {
01671         Diag(Tok, diag::err_expected) << tok::identifier;
01672         break;
01673       }
01674       propertyIvar = Tok.getIdentifierInfo();
01675       propertyIvarLoc = ConsumeToken(); // consume ivar-name
01676     }
01677     Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true,
01678                                   propertyId, propertyIvar, propertyIvarLoc);
01679     if (Tok.isNot(tok::comma))
01680       break;
01681     ConsumeToken(); // consume ','
01682   }
01683   ExpectAndConsume(tok::semi, diag::err_expected_after, "@synthesize");
01684   return nullptr;
01685 }
01686 
01687 ///   property-dynamic:
01688 ///     @dynamic  property-list
01689 ///
01690 ///   property-list:
01691 ///     identifier
01692 ///     property-list ',' identifier
01693 ///
01694 Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
01695   assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
01696          "ParseObjCPropertyDynamic(): Expected '@dynamic'");
01697   ConsumeToken(); // consume dynamic
01698   while (true) {
01699     if (Tok.is(tok::code_completion)) {
01700       Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
01701       cutOffParsing();
01702       return nullptr;
01703     }
01704     
01705     if (Tok.isNot(tok::identifier)) {
01706       Diag(Tok, diag::err_expected) << tok::identifier;
01707       SkipUntil(tok::semi);
01708       return nullptr;
01709     }
01710     
01711     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
01712     SourceLocation propertyLoc = ConsumeToken(); // consume property name
01713     Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false,
01714                                   propertyId, nullptr, SourceLocation());
01715 
01716     if (Tok.isNot(tok::comma))
01717       break;
01718     ConsumeToken(); // consume ','
01719   }
01720   ExpectAndConsume(tok::semi, diag::err_expected_after, "@dynamic");
01721   return nullptr;
01722 }
01723 
01724 ///  objc-throw-statement:
01725 ///    throw expression[opt];
01726 ///
01727 StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
01728   ExprResult Res;
01729   ConsumeToken(); // consume throw
01730   if (Tok.isNot(tok::semi)) {
01731     Res = ParseExpression();
01732     if (Res.isInvalid()) {
01733       SkipUntil(tok::semi);
01734       return StmtError();
01735     }
01736   }
01737   // consume ';'
01738   ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw");
01739   return Actions.ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope());
01740 }
01741 
01742 /// objc-synchronized-statement:
01743 ///   @synchronized '(' expression ')' compound-statement
01744 ///
01745 StmtResult
01746 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
01747   ConsumeToken(); // consume synchronized
01748   if (Tok.isNot(tok::l_paren)) {
01749     Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
01750     return StmtError();
01751   }
01752 
01753   // The operand is surrounded with parentheses.
01754   ConsumeParen();  // '('
01755   ExprResult operand(ParseExpression());
01756 
01757   if (Tok.is(tok::r_paren)) {
01758     ConsumeParen();  // ')'
01759   } else {
01760     if (!operand.isInvalid())
01761       Diag(Tok, diag::err_expected) << tok::r_paren;
01762 
01763     // Skip forward until we see a left brace, but don't consume it.
01764     SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
01765   }
01766 
01767   // Require a compound statement.
01768   if (Tok.isNot(tok::l_brace)) {
01769     if (!operand.isInvalid())
01770       Diag(Tok, diag::err_expected) << tok::l_brace;
01771     return StmtError();
01772   }
01773 
01774   // Check the @synchronized operand now.
01775   if (!operand.isInvalid())
01776     operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.get());
01777 
01778   // Parse the compound statement within a new scope.
01779   ParseScope bodyScope(this, Scope::DeclScope);
01780   StmtResult body(ParseCompoundStatementBody());
01781   bodyScope.Exit();
01782 
01783   // If there was a semantic or parse error earlier with the
01784   // operand, fail now.
01785   if (operand.isInvalid())
01786     return StmtError();
01787 
01788   if (body.isInvalid())
01789     body = Actions.ActOnNullStmt(Tok.getLocation());
01790 
01791   return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get());
01792 }
01793 
01794 ///  objc-try-catch-statement:
01795 ///    @try compound-statement objc-catch-list[opt]
01796 ///    @try compound-statement objc-catch-list[opt] @finally compound-statement
01797 ///
01798 ///  objc-catch-list:
01799 ///    @catch ( parameter-declaration ) compound-statement
01800 ///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
01801 ///  catch-parameter-declaration:
01802 ///     parameter-declaration
01803 ///     '...' [OBJC2]
01804 ///
01805 StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
01806   bool catch_or_finally_seen = false;
01807 
01808   ConsumeToken(); // consume try
01809   if (Tok.isNot(tok::l_brace)) {
01810     Diag(Tok, diag::err_expected) << tok::l_brace;
01811     return StmtError();
01812   }
01813   StmtVector CatchStmts;
01814   StmtResult FinallyStmt;
01815   ParseScope TryScope(this, Scope::DeclScope);
01816   StmtResult TryBody(ParseCompoundStatementBody());
01817   TryScope.Exit();
01818   if (TryBody.isInvalid())
01819     TryBody = Actions.ActOnNullStmt(Tok.getLocation());
01820 
01821   while (Tok.is(tok::at)) {
01822     // At this point, we need to lookahead to determine if this @ is the start
01823     // of an @catch or @finally.  We don't want to consume the @ token if this
01824     // is an @try or @encode or something else.
01825     Token AfterAt = GetLookAheadToken(1);
01826     if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
01827         !AfterAt.isObjCAtKeyword(tok::objc_finally))
01828       break;
01829 
01830     SourceLocation AtCatchFinallyLoc = ConsumeToken();
01831     if (Tok.isObjCAtKeyword(tok::objc_catch)) {
01832       Decl *FirstPart = nullptr;
01833       ConsumeToken(); // consume catch
01834       if (Tok.is(tok::l_paren)) {
01835         ConsumeParen();
01836         ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
01837         if (Tok.isNot(tok::ellipsis)) {
01838           DeclSpec DS(AttrFactory);
01839           ParseDeclarationSpecifiers(DS);
01840           Declarator ParmDecl(DS, Declarator::ObjCCatchContext);
01841           ParseDeclarator(ParmDecl);
01842 
01843           // Inform the actions module about the declarator, so it
01844           // gets added to the current scope.
01845           FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl);
01846         } else
01847           ConsumeToken(); // consume '...'
01848 
01849         SourceLocation RParenLoc;
01850 
01851         if (Tok.is(tok::r_paren))
01852           RParenLoc = ConsumeParen();
01853         else // Skip over garbage, until we get to ')'.  Eat the ')'.
01854           SkipUntil(tok::r_paren, StopAtSemi);
01855 
01856         StmtResult CatchBody(true);
01857         if (Tok.is(tok::l_brace))
01858           CatchBody = ParseCompoundStatementBody();
01859         else
01860           Diag(Tok, diag::err_expected) << tok::l_brace;
01861         if (CatchBody.isInvalid())
01862           CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
01863         
01864         StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
01865                                                               RParenLoc, 
01866                                                               FirstPart, 
01867                                                               CatchBody.get());
01868         if (!Catch.isInvalid())
01869           CatchStmts.push_back(Catch.get());
01870         
01871       } else {
01872         Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
01873           << "@catch clause";
01874         return StmtError();
01875       }
01876       catch_or_finally_seen = true;
01877     } else {
01878       assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
01879       ConsumeToken(); // consume finally
01880       ParseScope FinallyScope(this, Scope::DeclScope);
01881 
01882       StmtResult FinallyBody(true);
01883       if (Tok.is(tok::l_brace))
01884         FinallyBody = ParseCompoundStatementBody();
01885       else
01886         Diag(Tok, diag::err_expected) << tok::l_brace;
01887       if (FinallyBody.isInvalid())
01888         FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
01889       FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
01890                                                    FinallyBody.get());
01891       catch_or_finally_seen = true;
01892       break;
01893     }
01894   }
01895   if (!catch_or_finally_seen) {
01896     Diag(atLoc, diag::err_missing_catch_finally);
01897     return StmtError();
01898   }
01899   
01900   return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(), 
01901                                     CatchStmts,
01902                                     FinallyStmt.get());
01903 }
01904 
01905 /// objc-autoreleasepool-statement:
01906 ///   @autoreleasepool compound-statement
01907 ///
01908 StmtResult
01909 Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
01910   ConsumeToken(); // consume autoreleasepool
01911   if (Tok.isNot(tok::l_brace)) {
01912     Diag(Tok, diag::err_expected) << tok::l_brace;
01913     return StmtError();
01914   }
01915   // Enter a scope to hold everything within the compound stmt.  Compound
01916   // statements can always hold declarations.
01917   ParseScope BodyScope(this, Scope::DeclScope);
01918 
01919   StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
01920 
01921   BodyScope.Exit();
01922   if (AutoreleasePoolBody.isInvalid())
01923     AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
01924   return Actions.ActOnObjCAutoreleasePoolStmt(atLoc, 
01925                                                 AutoreleasePoolBody.get());
01926 }
01927 
01928 /// StashAwayMethodOrFunctionBodyTokens -  Consume the tokens and store them 
01929 /// for later parsing.
01930 void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
01931   LexedMethod* LM = new LexedMethod(this, MDecl);
01932   CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
01933   CachedTokens &Toks = LM->Toks;
01934   // Begin by storing the '{' or 'try' or ':' token.
01935   Toks.push_back(Tok);
01936   if (Tok.is(tok::kw_try)) {
01937     ConsumeToken();
01938     if (Tok.is(tok::colon)) {
01939       Toks.push_back(Tok);
01940       ConsumeToken();
01941       while (Tok.isNot(tok::l_brace)) {
01942         ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
01943         ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
01944       }
01945     }
01946     Toks.push_back(Tok); // also store '{'
01947   }
01948   else if (Tok.is(tok::colon)) {
01949     ConsumeToken();
01950     while (Tok.isNot(tok::l_brace)) {
01951       ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
01952       ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
01953     }
01954     Toks.push_back(Tok); // also store '{'
01955   }
01956   ConsumeBrace();
01957   // Consume everything up to (and including) the matching right brace.
01958   ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
01959   while (Tok.is(tok::kw_catch)) {
01960     ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
01961     ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
01962   }
01963 }
01964 
01965 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
01966 ///
01967 Decl *Parser::ParseObjCMethodDefinition() {
01968   Decl *MDecl = ParseObjCMethodPrototype();
01969 
01970   PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(),
01971                                       "parsing Objective-C method");
01972 
01973   // parse optional ';'
01974   if (Tok.is(tok::semi)) {
01975     if (CurParsedObjCImpl) {
01976       Diag(Tok, diag::warn_semicolon_before_method_body)
01977         << FixItHint::CreateRemoval(Tok.getLocation());
01978     }
01979     ConsumeToken();
01980   }
01981 
01982   // We should have an opening brace now.
01983   if (Tok.isNot(tok::l_brace)) {
01984     Diag(Tok, diag::err_expected_method_body);
01985 
01986     // Skip over garbage, until we get to '{'.  Don't eat the '{'.
01987     SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
01988 
01989     // If we didn't find the '{', bail out.
01990     if (Tok.isNot(tok::l_brace))
01991       return nullptr;
01992   }
01993 
01994   if (!MDecl) {
01995     ConsumeBrace();
01996     SkipUntil(tok::r_brace);
01997     return nullptr;
01998   }
01999 
02000   // Allow the rest of sema to find private method decl implementations.
02001   Actions.AddAnyMethodToGlobalPool(MDecl);
02002   assert (CurParsedObjCImpl 
02003           && "ParseObjCMethodDefinition - Method out of @implementation");
02004   // Consume the tokens and store them for later parsing.
02005   StashAwayMethodOrFunctionBodyTokens(MDecl);
02006   return MDecl;
02007 }
02008 
02009 StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
02010   if (Tok.is(tok::code_completion)) {
02011     Actions.CodeCompleteObjCAtStatement(getCurScope());
02012     cutOffParsing();
02013     return StmtError();
02014   }
02015   
02016   if (Tok.isObjCAtKeyword(tok::objc_try))
02017     return ParseObjCTryStmt(AtLoc);
02018   
02019   if (Tok.isObjCAtKeyword(tok::objc_throw))
02020     return ParseObjCThrowStmt(AtLoc);
02021   
02022   if (Tok.isObjCAtKeyword(tok::objc_synchronized))
02023     return ParseObjCSynchronizedStmt(AtLoc);
02024 
02025   if (Tok.isObjCAtKeyword(tok::objc_autoreleasepool))
02026     return ParseObjCAutoreleasePoolStmt(AtLoc);
02027   
02028   ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
02029   if (Res.isInvalid()) {
02030     // If the expression is invalid, skip ahead to the next semicolon. Not
02031     // doing this opens us up to the possibility of infinite loops if
02032     // ParseExpression does not consume any tokens.
02033     SkipUntil(tok::semi);
02034     return StmtError();
02035   }
02036   
02037   // Otherwise, eat the semicolon.
02038   ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
02039   return Actions.ActOnExprStmt(Res);
02040 }
02041 
02042 ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
02043   switch (Tok.getKind()) {
02044   case tok::code_completion:
02045     Actions.CodeCompleteObjCAtExpression(getCurScope());
02046     cutOffParsing();
02047     return ExprError();
02048 
02049   case tok::minus:
02050   case tok::plus: {
02051     tok::TokenKind Kind = Tok.getKind();
02052     SourceLocation OpLoc = ConsumeToken();
02053 
02054     if (!Tok.is(tok::numeric_constant)) {
02055       const char *Symbol = nullptr;
02056       switch (Kind) {
02057       case tok::minus: Symbol = "-"; break;
02058       case tok::plus: Symbol = "+"; break;
02059       default: llvm_unreachable("missing unary operator case");
02060       }
02061       Diag(Tok, diag::err_nsnumber_nonliteral_unary)
02062         << Symbol;
02063       return ExprError();
02064     }
02065 
02066     ExprResult Lit(Actions.ActOnNumericConstant(Tok));
02067     if (Lit.isInvalid()) {
02068       return Lit;
02069     }
02070     ConsumeToken(); // Consume the literal token.
02071 
02072     Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.get());
02073     if (Lit.isInvalid())
02074       return Lit;
02075 
02076     return ParsePostfixExpressionSuffix(
02077              Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()));
02078   }
02079 
02080   case tok::string_literal:    // primary-expression: string-literal
02081   case tok::wide_string_literal:
02082     return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
02083 
02084   case tok::char_constant:
02085     return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
02086       
02087   case tok::numeric_constant:
02088     return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
02089 
02090   case tok::kw_true:  // Objective-C++, etc.
02091   case tok::kw___objc_yes: // c/c++/objc/objc++ __objc_yes
02092     return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, true));
02093   case tok::kw_false: // Objective-C++, etc.
02094   case tok::kw___objc_no: // c/c++/objc/objc++ __objc_no
02095     return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, false));
02096     
02097   case tok::l_square:
02098     // Objective-C array literal
02099     return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
02100           
02101   case tok::l_brace:
02102     // Objective-C dictionary literal
02103     return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
02104           
02105   case tok::l_paren:
02106     // Objective-C boxed expression
02107     return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
02108           
02109   default:
02110     if (Tok.getIdentifierInfo() == nullptr)
02111       return ExprError(Diag(AtLoc, diag::err_unexpected_at));
02112 
02113     switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
02114     case tok::objc_encode:
02115       return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
02116     case tok::objc_protocol:
02117       return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
02118     case tok::objc_selector:
02119       return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
02120       default: {
02121         const char *str = nullptr;
02122         if (GetLookAheadToken(1).is(tok::l_brace)) {
02123           char ch = Tok.getIdentifierInfo()->getNameStart()[0];
02124           str =  
02125             ch == 't' ? "try" 
02126                       : (ch == 'f' ? "finally" 
02127                                    : (ch == 'a' ? "autoreleasepool" : nullptr));
02128         }
02129         if (str) {
02130           SourceLocation kwLoc = Tok.getLocation();
02131           return ExprError(Diag(AtLoc, diag::err_unexpected_at) << 
02132                              FixItHint::CreateReplacement(kwLoc, str));
02133         }
02134         else
02135           return ExprError(Diag(AtLoc, diag::err_unexpected_at));
02136       }
02137     }
02138   }
02139 }
02140 
02141 /// \brief Parse the receiver of an Objective-C++ message send.
02142 ///
02143 /// This routine parses the receiver of a message send in
02144 /// Objective-C++ either as a type or as an expression. Note that this
02145 /// routine must not be called to parse a send to 'super', since it
02146 /// has no way to return such a result.
02147 /// 
02148 /// \param IsExpr Whether the receiver was parsed as an expression.
02149 ///
02150 /// \param TypeOrExpr If the receiver was parsed as an expression (\c
02151 /// IsExpr is true), the parsed expression. If the receiver was parsed
02152 /// as a type (\c IsExpr is false), the parsed type.
02153 ///
02154 /// \returns True if an error occurred during parsing or semantic
02155 /// analysis, in which case the arguments do not have valid
02156 /// values. Otherwise, returns false for a successful parse.
02157 ///
02158 ///   objc-receiver: [C++]
02159 ///     'super' [not parsed here]
02160 ///     expression
02161 ///     simple-type-specifier
02162 ///     typename-specifier
02163 bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
02164   InMessageExpressionRAIIObject InMessage(*this, true);
02165 
02166   if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || 
02167       Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope))
02168     TryAnnotateTypeOrScopeToken();
02169 
02170   if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
02171     //   objc-receiver:
02172     //     expression
02173     ExprResult Receiver = ParseExpression();
02174     if (Receiver.isInvalid())
02175       return true;
02176 
02177     IsExpr = true;
02178     TypeOrExpr = Receiver.get();
02179     return false;
02180   }
02181 
02182   // objc-receiver:
02183   //   typename-specifier
02184   //   simple-type-specifier
02185   //   expression (that starts with one of the above)
02186   DeclSpec DS(AttrFactory);
02187   ParseCXXSimpleTypeSpecifier(DS);
02188   
02189   if (Tok.is(tok::l_paren)) {
02190     // If we see an opening parentheses at this point, we are
02191     // actually parsing an expression that starts with a
02192     // function-style cast, e.g.,
02193     //
02194     //   postfix-expression:
02195     //     simple-type-specifier ( expression-list [opt] )
02196     //     typename-specifier ( expression-list [opt] )
02197     //
02198     // Parse the remainder of this case, then the (optional)
02199     // postfix-expression suffix, followed by the (optional)
02200     // right-hand side of the binary expression. We have an
02201     // instance method.
02202     ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
02203     if (!Receiver.isInvalid())
02204       Receiver = ParsePostfixExpressionSuffix(Receiver.get());
02205     if (!Receiver.isInvalid())
02206       Receiver = ParseRHSOfBinaryExpression(Receiver.get(), prec::Comma);
02207     if (Receiver.isInvalid())
02208       return true;
02209 
02210     IsExpr = true;
02211     TypeOrExpr = Receiver.get();
02212     return false;
02213   }
02214   
02215   // We have a class message. Turn the simple-type-specifier or
02216   // typename-specifier we parsed into a type and parse the
02217   // remainder of the class message.
02218   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
02219   TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
02220   if (Type.isInvalid())
02221     return true;
02222 
02223   IsExpr = false;
02224   TypeOrExpr = Type.get().getAsOpaquePtr();
02225   return false;
02226 }
02227 
02228 /// \brief Determine whether the parser is currently referring to a an
02229 /// Objective-C message send, using a simplified heuristic to avoid overhead.
02230 ///
02231 /// This routine will only return true for a subset of valid message-send
02232 /// expressions.
02233 bool Parser::isSimpleObjCMessageExpression() {
02234   assert(Tok.is(tok::l_square) && getLangOpts().ObjC1 &&
02235          "Incorrect start for isSimpleObjCMessageExpression");
02236   return GetLookAheadToken(1).is(tok::identifier) &&
02237          GetLookAheadToken(2).is(tok::identifier);
02238 }
02239 
02240 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
02241   if (!getLangOpts().ObjC1 || !NextToken().is(tok::identifier) || 
02242       InMessageExpression)
02243     return false;
02244   
02245   
02246   ParsedType Type;
02247 
02248   if (Tok.is(tok::annot_typename)) 
02249     Type = getTypeAnnotation(Tok);
02250   else if (Tok.is(tok::identifier))
02251     Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(), 
02252                                getCurScope());
02253   else
02254     return false;
02255   
02256   if (!Type.get().isNull() && Type.get()->isObjCObjectOrInterfaceType()) {
02257     const Token &AfterNext = GetLookAheadToken(2);
02258     if (AfterNext.is(tok::colon) || AfterNext.is(tok::r_square)) {
02259       if (Tok.is(tok::identifier))
02260         TryAnnotateTypeOrScopeToken();
02261       
02262       return Tok.is(tok::annot_typename);
02263     }
02264   }
02265 
02266   return false;
02267 }
02268 
02269 ///   objc-message-expr:
02270 ///     '[' objc-receiver objc-message-args ']'
02271 ///
02272 ///   objc-receiver: [C]
02273 ///     'super'
02274 ///     expression
02275 ///     class-name
02276 ///     type-name
02277 ///
02278 ExprResult Parser::ParseObjCMessageExpression() {
02279   assert(Tok.is(tok::l_square) && "'[' expected");
02280   SourceLocation LBracLoc = ConsumeBracket(); // consume '['
02281 
02282   if (Tok.is(tok::code_completion)) {
02283     Actions.CodeCompleteObjCMessageReceiver(getCurScope());
02284     cutOffParsing();
02285     return ExprError();
02286   }
02287   
02288   InMessageExpressionRAIIObject InMessage(*this, true);
02289   
02290   if (getLangOpts().CPlusPlus) {
02291     // We completely separate the C and C++ cases because C++ requires
02292     // more complicated (read: slower) parsing. 
02293     
02294     // Handle send to super.  
02295     // FIXME: This doesn't benefit from the same typo-correction we
02296     // get in Objective-C.
02297     if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
02298         NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope())
02299       return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
02300                                             ParsedType(), nullptr);
02301 
02302     // Parse the receiver, which is either a type or an expression.
02303     bool IsExpr;
02304     void *TypeOrExpr = nullptr;
02305     if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
02306       SkipUntil(tok::r_square, StopAtSemi);
02307       return ExprError();
02308     }
02309 
02310     if (IsExpr)
02311       return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
02312                                             ParsedType(),
02313                                             static_cast<Expr*>(TypeOrExpr));
02314 
02315     return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
02316                               ParsedType::getFromOpaquePtr(TypeOrExpr),
02317                                           nullptr);
02318   }
02319   
02320   if (Tok.is(tok::identifier)) {
02321     IdentifierInfo *Name = Tok.getIdentifierInfo();
02322     SourceLocation NameLoc = Tok.getLocation();
02323     ParsedType ReceiverType;
02324     switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc,
02325                                        Name == Ident_super,
02326                                        NextToken().is(tok::period),
02327                                        ReceiverType)) {
02328     case Sema::ObjCSuperMessage:
02329       return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
02330                                             ParsedType(), nullptr);
02331 
02332     case Sema::ObjCClassMessage:
02333       if (!ReceiverType) {
02334         SkipUntil(tok::r_square, StopAtSemi);
02335         return ExprError();
02336       }
02337 
02338       ConsumeToken(); // the type name
02339 
02340       return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
02341                                             ReceiverType, nullptr);
02342 
02343     case Sema::ObjCInstanceMessage:
02344       // Fall through to parse an expression.
02345       break;
02346     }
02347   }
02348   
02349   // Otherwise, an arbitrary expression can be the receiver of a send.
02350   ExprResult Res(ParseExpression());
02351   if (Res.isInvalid()) {
02352     SkipUntil(tok::r_square, StopAtSemi);
02353     return Res;
02354   }
02355 
02356   return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
02357                                         ParsedType(), Res.get());
02358 }
02359 
02360 /// \brief Parse the remainder of an Objective-C message following the
02361 /// '[' objc-receiver.
02362 ///
02363 /// This routine handles sends to super, class messages (sent to a
02364 /// class name), and instance messages (sent to an object), and the
02365 /// target is represented by \p SuperLoc, \p ReceiverType, or \p
02366 /// ReceiverExpr, respectively. Only one of these parameters may have
02367 /// a valid value.
02368 ///
02369 /// \param LBracLoc The location of the opening '['.
02370 ///
02371 /// \param SuperLoc If this is a send to 'super', the location of the
02372 /// 'super' keyword that indicates a send to the superclass.
02373 ///
02374 /// \param ReceiverType If this is a class message, the type of the
02375 /// class we are sending a message to.
02376 ///
02377 /// \param ReceiverExpr If this is an instance message, the expression
02378 /// used to compute the receiver object.
02379 ///
02380 ///   objc-message-args:
02381 ///     objc-selector
02382 ///     objc-keywordarg-list
02383 ///
02384 ///   objc-keywordarg-list:
02385 ///     objc-keywordarg
02386 ///     objc-keywordarg-list objc-keywordarg
02387 ///
02388 ///   objc-keywordarg:
02389 ///     selector-name[opt] ':' objc-keywordexpr
02390 ///
02391 ///   objc-keywordexpr:
02392 ///     nonempty-expr-list
02393 ///
02394 ///   nonempty-expr-list:
02395 ///     assignment-expression
02396 ///     nonempty-expr-list , assignment-expression
02397 ///
02398 ExprResult
02399 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
02400                                        SourceLocation SuperLoc,
02401                                        ParsedType ReceiverType,
02402                                        Expr *ReceiverExpr) {
02403   InMessageExpressionRAIIObject InMessage(*this, true);
02404 
02405   if (Tok.is(tok::code_completion)) {
02406     if (SuperLoc.isValid())
02407       Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None,
02408                                            false);
02409     else if (ReceiverType)
02410       Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, None,
02411                                            false);
02412     else
02413       Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
02414                                               None, false);
02415     cutOffParsing();
02416     return ExprError();
02417   }
02418   
02419   // Parse objc-selector
02420   SourceLocation Loc;
02421   IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
02422   
02423   SmallVector<IdentifierInfo *, 12> KeyIdents;
02424   SmallVector<SourceLocation, 12> KeyLocs;
02425   ExprVector KeyExprs;
02426 
02427   if (Tok.is(tok::colon)) {
02428     while (1) {
02429       // Each iteration parses a single keyword argument.
02430       KeyIdents.push_back(selIdent);
02431       KeyLocs.push_back(Loc);
02432 
02433       if (ExpectAndConsume(tok::colon)) {
02434         // We must manually skip to a ']', otherwise the expression skipper will
02435         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
02436         // the enclosing expression.
02437         SkipUntil(tok::r_square, StopAtSemi);
02438         return ExprError();
02439       }
02440 
02441       ///  Parse the expression after ':'
02442       
02443       if (Tok.is(tok::code_completion)) {
02444         if (SuperLoc.isValid())
02445           Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, 
02446                                                KeyIdents,
02447                                                /*AtArgumentEpression=*/true);
02448         else if (ReceiverType)
02449           Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
02450                                                KeyIdents,
02451                                                /*AtArgumentEpression=*/true);
02452         else
02453           Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
02454                                                   KeyIdents,
02455                                                   /*AtArgumentEpression=*/true);
02456 
02457         cutOffParsing();
02458         return ExprError();
02459       }
02460       
02461       ExprResult Expr;
02462       if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
02463         Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
02464         Expr = ParseBraceInitializer();
02465       } else
02466         Expr = ParseAssignmentExpression();
02467       
02468       ExprResult Res(Expr);
02469       if (Res.isInvalid()) {
02470         // We must manually skip to a ']', otherwise the expression skipper will
02471         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
02472         // the enclosing expression.
02473         SkipUntil(tok::r_square, StopAtSemi);
02474         return Res;
02475       }
02476 
02477       // We have a valid expression.
02478       KeyExprs.push_back(Res.get());
02479 
02480       // Code completion after each argument.
02481       if (Tok.is(tok::code_completion)) {
02482         if (SuperLoc.isValid())
02483           Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, 
02484                                                KeyIdents,
02485                                                /*AtArgumentEpression=*/false);
02486         else if (ReceiverType)
02487           Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
02488                                                KeyIdents,
02489                                                /*AtArgumentEpression=*/false);
02490         else
02491           Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
02492                                                   KeyIdents,
02493                                                 /*AtArgumentEpression=*/false);
02494         cutOffParsing();
02495         return ExprError();
02496       }
02497             
02498       // Check for another keyword selector.
02499       selIdent = ParseObjCSelectorPiece(Loc);
02500       if (!selIdent && Tok.isNot(tok::colon))
02501         break;
02502       // We have a selector or a colon, continue parsing.
02503     }
02504     // Parse the, optional, argument list, comma separated.
02505     while (Tok.is(tok::comma)) {
02506       SourceLocation commaLoc = ConsumeToken(); // Eat the ','.
02507       ///  Parse the expression after ','
02508       ExprResult Res(ParseAssignmentExpression());
02509       if (Res.isInvalid()) {
02510         if (Tok.is(tok::colon)) {
02511           Diag(commaLoc, diag::note_extra_comma_message_arg) <<
02512             FixItHint::CreateRemoval(commaLoc);
02513         }
02514         // We must manually skip to a ']', otherwise the expression skipper will
02515         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
02516         // the enclosing expression.
02517         SkipUntil(tok::r_square, StopAtSemi);
02518         return Res;
02519       }
02520 
02521       // We have a valid expression.
02522       KeyExprs.push_back(Res.get());
02523     }
02524   } else if (!selIdent) {
02525     Diag(Tok, diag::err_expected) << tok::identifier; // missing selector name.
02526 
02527     // We must manually skip to a ']', otherwise the expression skipper will
02528     // stop at the ']' when it skips to the ';'.  We want it to skip beyond
02529     // the enclosing expression.
02530     SkipUntil(tok::r_square, StopAtSemi);
02531     return ExprError();
02532   }
02533     
02534   if (Tok.isNot(tok::r_square)) {
02535     Diag(Tok, diag::err_expected)
02536         << (Tok.is(tok::identifier) ? tok::colon : tok::r_square);
02537     // We must manually skip to a ']', otherwise the expression skipper will
02538     // stop at the ']' when it skips to the ';'.  We want it to skip beyond
02539     // the enclosing expression.
02540     SkipUntil(tok::r_square, StopAtSemi);
02541     return ExprError();
02542   }
02543   
02544   SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
02545 
02546   unsigned nKeys = KeyIdents.size();
02547   if (nKeys == 0) {
02548     KeyIdents.push_back(selIdent);
02549     KeyLocs.push_back(Loc);
02550   }
02551   Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
02552 
02553   if (SuperLoc.isValid())
02554     return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel,
02555                                      LBracLoc, KeyLocs, RBracLoc, KeyExprs);
02556   else if (ReceiverType)
02557     return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel,
02558                                      LBracLoc, KeyLocs, RBracLoc, KeyExprs);
02559   return Actions.ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel,
02560                                       LBracLoc, KeyLocs, RBracLoc, KeyExprs);
02561 }
02562 
02563 ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
02564   ExprResult Res(ParseStringLiteralExpression());
02565   if (Res.isInvalid()) return Res;
02566 
02567   // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
02568   // expressions.  At this point, we know that the only valid thing that starts
02569   // with '@' is an @"".
02570   SmallVector<SourceLocation, 4> AtLocs;
02571   ExprVector AtStrings;
02572   AtLocs.push_back(AtLoc);
02573   AtStrings.push_back(Res.get());
02574 
02575   while (Tok.is(tok::at)) {
02576     AtLocs.push_back(ConsumeToken()); // eat the @.
02577 
02578     // Invalid unless there is a string literal.
02579     if (!isTokenStringLiteral())
02580       return ExprError(Diag(Tok, diag::err_objc_concat_string));
02581 
02582     ExprResult Lit(ParseStringLiteralExpression());
02583     if (Lit.isInvalid())
02584       return Lit;
02585 
02586     AtStrings.push_back(Lit.get());
02587   }
02588 
02589   return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.data(),
02590                                         AtStrings.size());
02591 }
02592 
02593 /// ParseObjCBooleanLiteral -
02594 /// objc-scalar-literal : '@' boolean-keyword
02595 ///                        ;
02596 /// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
02597 ///                        ;
02598 ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc, 
02599                                            bool ArgValue) {
02600   SourceLocation EndLoc = ConsumeToken();             // consume the keyword.
02601   return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
02602 }
02603 
02604 /// ParseObjCCharacterLiteral -
02605 /// objc-scalar-literal : '@' character-literal
02606 ///                        ;
02607 ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {
02608   ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
02609   if (Lit.isInvalid()) {
02610     return Lit;
02611   }
02612   ConsumeToken(); // Consume the literal token.
02613   return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
02614 }
02615 
02616 /// ParseObjCNumericLiteral -
02617 /// objc-scalar-literal : '@' scalar-literal
02618 ///                        ;
02619 /// scalar-literal : | numeric-constant     /* any numeric constant. */
02620 ///                    ;
02621 ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {
02622   ExprResult Lit(Actions.ActOnNumericConstant(Tok));
02623   if (Lit.isInvalid()) {
02624     return Lit;
02625   }
02626   ConsumeToken(); // Consume the literal token.
02627   return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
02628 }
02629 
02630 /// ParseObjCBoxedExpr -
02631 /// objc-box-expression:
02632 ///       @( assignment-expression )
02633 ExprResult
02634 Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) {
02635   if (Tok.isNot(tok::l_paren))
02636     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@");
02637 
02638   BalancedDelimiterTracker T(*this, tok::l_paren);
02639   T.consumeOpen();
02640   ExprResult ValueExpr(ParseAssignmentExpression());
02641   if (T.consumeClose())
02642     return ExprError();
02643 
02644   if (ValueExpr.isInvalid())
02645     return ExprError();
02646 
02647   // Wrap the sub-expression in a parenthesized expression, to distinguish
02648   // a boxed expression from a literal.
02649   SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation();
02650   ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
02651   return Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
02652                                     ValueExpr.get());
02653 }
02654 
02655 ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
02656   ExprVector ElementExprs;                   // array elements.
02657   ConsumeBracket(); // consume the l_square.
02658 
02659   while (Tok.isNot(tok::r_square)) {
02660     // Parse list of array element expressions (all must be id types).
02661     ExprResult Res(ParseAssignmentExpression());
02662     if (Res.isInvalid()) {
02663       // We must manually skip to a ']', otherwise the expression skipper will
02664       // stop at the ']' when it skips to the ';'.  We want it to skip beyond
02665       // the enclosing expression.
02666       SkipUntil(tok::r_square, StopAtSemi);
02667       return Res;
02668     }    
02669     
02670     // Parse the ellipsis that indicates a pack expansion.
02671     if (Tok.is(tok::ellipsis))
02672       Res = Actions.ActOnPackExpansion(Res.get(), ConsumeToken());    
02673     if (Res.isInvalid())
02674       return true;
02675 
02676     ElementExprs.push_back(Res.get());
02677 
02678     if (Tok.is(tok::comma))
02679       ConsumeToken(); // Eat the ','.
02680     else if (Tok.isNot(tok::r_square))
02681       return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_square
02682                                                             << tok::comma);
02683   }
02684   SourceLocation EndLoc = ConsumeBracket(); // location of ']'
02685   MultiExprArg Args(ElementExprs);
02686   return Actions.BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args);
02687 }
02688 
02689 ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
02690   SmallVector<ObjCDictionaryElement, 4> Elements; // dictionary elements.
02691   ConsumeBrace(); // consume the l_square.
02692   while (Tok.isNot(tok::r_brace)) {
02693     // Parse the comma separated key : value expressions.
02694     ExprResult KeyExpr;
02695     {
02696       ColonProtectionRAIIObject X(*this);
02697       KeyExpr = ParseAssignmentExpression();
02698       if (KeyExpr.isInvalid()) {
02699         // We must manually skip to a '}', otherwise the expression skipper will
02700         // stop at the '}' when it skips to the ';'.  We want it to skip beyond
02701         // the enclosing expression.
02702         SkipUntil(tok::r_brace, StopAtSemi);
02703         return KeyExpr;
02704       }
02705     }
02706 
02707     if (ExpectAndConsume(tok::colon)) {
02708       SkipUntil(tok::r_brace, StopAtSemi);
02709       return ExprError();
02710     }
02711     
02712     ExprResult ValueExpr(ParseAssignmentExpression());
02713     if (ValueExpr.isInvalid()) {
02714       // We must manually skip to a '}', otherwise the expression skipper will
02715       // stop at the '}' when it skips to the ';'.  We want it to skip beyond
02716       // the enclosing expression.
02717       SkipUntil(tok::r_brace, StopAtSemi);
02718       return ValueExpr;
02719     }
02720     
02721     // Parse the ellipsis that designates this as a pack expansion.
02722     SourceLocation EllipsisLoc;
02723     if (getLangOpts().CPlusPlus)
02724       TryConsumeToken(tok::ellipsis, EllipsisLoc);
02725 
02726     // We have a valid expression. Collect it in a vector so we can
02727     // build the argument list.
02728     ObjCDictionaryElement Element = { 
02729       KeyExpr.get(), ValueExpr.get(), EllipsisLoc, None 
02730     };
02731     Elements.push_back(Element);
02732 
02733     if (!TryConsumeToken(tok::comma) && Tok.isNot(tok::r_brace))
02734       return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_brace
02735                                                             << tok::comma);
02736   }
02737   SourceLocation EndLoc = ConsumeBrace();
02738   
02739   // Create the ObjCDictionaryLiteral.
02740   return Actions.BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc),
02741                                             Elements.data(), Elements.size());
02742 }
02743 
02744 ///    objc-encode-expression:
02745 ///      \@encode ( type-name )
02746 ExprResult
02747 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
02748   assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
02749 
02750   SourceLocation EncLoc = ConsumeToken();
02751 
02752   if (Tok.isNot(tok::l_paren))
02753     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
02754 
02755   BalancedDelimiterTracker T(*this, tok::l_paren);
02756   T.consumeOpen();
02757 
02758   TypeResult Ty = ParseTypeName();
02759 
02760   T.consumeClose();
02761 
02762   if (Ty.isInvalid())
02763     return ExprError();
02764 
02765   return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.getOpenLocation(),
02766                                            Ty.get(), T.getCloseLocation());
02767 }
02768 
02769 ///     objc-protocol-expression
02770 ///       \@protocol ( protocol-name )
02771 ExprResult
02772 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
02773   SourceLocation ProtoLoc = ConsumeToken();
02774 
02775   if (Tok.isNot(tok::l_paren))
02776     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
02777 
02778   BalancedDelimiterTracker T(*this, tok::l_paren);
02779   T.consumeOpen();
02780 
02781   if (Tok.isNot(tok::identifier))
02782     return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
02783 
02784   IdentifierInfo *protocolId = Tok.getIdentifierInfo();
02785   SourceLocation ProtoIdLoc = ConsumeToken();
02786 
02787   T.consumeClose();
02788 
02789   return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
02790                                              T.getOpenLocation(), ProtoIdLoc,
02791                                              T.getCloseLocation());
02792 }
02793 
02794 ///     objc-selector-expression
02795 ///       @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
02796 ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
02797   SourceLocation SelectorLoc = ConsumeToken();
02798 
02799   if (Tok.isNot(tok::l_paren))
02800     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
02801 
02802   SmallVector<IdentifierInfo *, 12> KeyIdents;
02803   SourceLocation sLoc;
02804   
02805   BalancedDelimiterTracker T(*this, tok::l_paren);
02806   T.consumeOpen();
02807   bool HasOptionalParen = Tok.is(tok::l_paren);
02808   if (HasOptionalParen)
02809     ConsumeParen();
02810   
02811   if (Tok.is(tok::code_completion)) {
02812     Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
02813     cutOffParsing();
02814     return ExprError();
02815   }
02816   
02817   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
02818   if (!SelIdent &&  // missing selector name.
02819       Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
02820     return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
02821 
02822   KeyIdents.push_back(SelIdent);
02823   
02824   unsigned nColons = 0;
02825   if (Tok.isNot(tok::r_paren)) {
02826     while (1) {
02827       if (TryConsumeToken(tok::coloncolon)) { // Handle :: in C++.
02828         ++nColons;
02829         KeyIdents.push_back(nullptr);
02830       } else if (ExpectAndConsume(tok::colon)) // Otherwise expect ':'.
02831         return ExprError();
02832       ++nColons;
02833 
02834       if (Tok.is(tok::r_paren))
02835         break;
02836       
02837       if (Tok.is(tok::code_completion)) {
02838         Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
02839         cutOffParsing();
02840         return ExprError();
02841       }
02842 
02843       // Check for another keyword selector.
02844       SourceLocation Loc;
02845       SelIdent = ParseObjCSelectorPiece(Loc);
02846       KeyIdents.push_back(SelIdent);
02847       if (!SelIdent && Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
02848         break;
02849     }
02850   }
02851   if (HasOptionalParen && Tok.is(tok::r_paren))
02852     ConsumeParen(); // ')'
02853   T.consumeClose();
02854   Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
02855   return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
02856                                              T.getOpenLocation(),
02857                                              T.getCloseLocation(),
02858                                              !HasOptionalParen);
02859  }
02860 
02861 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
02862   // MCDecl might be null due to error in method or c-function  prototype, etc.
02863   Decl *MCDecl = LM.D;
02864   bool skip = MCDecl && 
02865               ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
02866               (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
02867   if (skip)
02868     return;
02869   
02870   // Save the current token position.
02871   SourceLocation OrigLoc = Tok.getLocation();
02872 
02873   assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!");
02874   // Append the current token at the end of the new token stream so that it
02875   // doesn't get lost.
02876   LM.Toks.push_back(Tok);
02877   PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
02878   
02879   // Consume the previously pushed token.
02880   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
02881     
02882   assert((Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
02883           Tok.is(tok::colon)) && 
02884           "Inline objective-c method not starting with '{' or 'try' or ':'");
02885   // Enter a scope for the method or c-function body.
02886   ParseScope BodyScope(this,
02887                        parseMethod
02888                        ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope
02889                        : Scope::FnScope|Scope::DeclScope);
02890     
02891   // Tell the actions module that we have entered a method or c-function definition 
02892   // with the specified Declarator for the method/function.
02893   if (parseMethod)
02894     Actions.ActOnStartOfObjCMethodDef(getCurScope(), MCDecl);
02895   else
02896     Actions.ActOnStartOfFunctionDef(getCurScope(), MCDecl);
02897   if (Tok.is(tok::kw_try))
02898     ParseFunctionTryBlock(MCDecl, BodyScope);
02899   else {
02900     if (Tok.is(tok::colon))
02901       ParseConstructorInitializer(MCDecl);
02902     ParseFunctionStatementBody(MCDecl, BodyScope);
02903   }
02904   
02905   if (Tok.getLocation() != OrigLoc) {
02906     // Due to parsing error, we either went over the cached tokens or
02907     // there are still cached tokens left. If it's the latter case skip the
02908     // leftover tokens.
02909     // Since this is an uncommon situation that should be avoided, use the
02910     // expensive isBeforeInTranslationUnit call.
02911     if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
02912                                                      OrigLoc))
02913       while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
02914         ConsumeAnyToken();
02915   }
02916   
02917   return;
02918 }