clang API Documentation
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 ¶mAttrs); 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 }