Mercurial > hg > CbC > CbC_llvm
comparison clang/lib/Parse/ParseObjc.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
48 Parser::DeclGroupPtrTy | 48 Parser::DeclGroupPtrTy |
49 Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) { | 49 Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) { |
50 SourceLocation AtLoc = ConsumeToken(); // the "@" | 50 SourceLocation AtLoc = ConsumeToken(); // the "@" |
51 | 51 |
52 if (Tok.is(tok::code_completion)) { | 52 if (Tok.is(tok::code_completion)) { |
53 cutOffParsing(); | |
53 Actions.CodeCompleteObjCAtDirective(getCurScope()); | 54 Actions.CodeCompleteObjCAtDirective(getCurScope()); |
54 cutOffParsing(); | |
55 return nullptr; | 55 return nullptr; |
56 } | 56 } |
57 | 57 |
58 Decl *SingleDecl = nullptr; | 58 Decl *SingleDecl = nullptr; |
59 switch (Tok.getObjCKeywordID()) { | 59 switch (Tok.getObjCKeywordID()) { |
217 CheckNestedObjCContexts(AtLoc); | 217 CheckNestedObjCContexts(AtLoc); |
218 ConsumeToken(); // the "interface" identifier | 218 ConsumeToken(); // the "interface" identifier |
219 | 219 |
220 // Code completion after '@interface'. | 220 // Code completion after '@interface'. |
221 if (Tok.is(tok::code_completion)) { | 221 if (Tok.is(tok::code_completion)) { |
222 cutOffParsing(); | |
222 Actions.CodeCompleteObjCInterfaceDecl(getCurScope()); | 223 Actions.CodeCompleteObjCInterfaceDecl(getCurScope()); |
223 cutOffParsing(); | |
224 return nullptr; | 224 return nullptr; |
225 } | 225 } |
226 | 226 |
227 MaybeSkipAttributes(tok::objc_interface); | 227 MaybeSkipAttributes(tok::objc_interface); |
228 | 228 |
251 T.consumeOpen(); | 251 T.consumeOpen(); |
252 | 252 |
253 SourceLocation categoryLoc; | 253 SourceLocation categoryLoc; |
254 IdentifierInfo *categoryId = nullptr; | 254 IdentifierInfo *categoryId = nullptr; |
255 if (Tok.is(tok::code_completion)) { | 255 if (Tok.is(tok::code_completion)) { |
256 cutOffParsing(); | |
256 Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc); | 257 Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc); |
257 cutOffParsing(); | |
258 return nullptr; | 258 return nullptr; |
259 } | 259 } |
260 | 260 |
261 // For ObjC2, the category name is optional (not an error). | 261 // For ObjC2, the category name is optional (not an error). |
262 if (Tok.is(tok::identifier)) { | 262 if (Tok.is(tok::identifier)) { |
306 if (Tok.is(tok::colon)) { // a super class is specified. | 306 if (Tok.is(tok::colon)) { // a super class is specified. |
307 ConsumeToken(); | 307 ConsumeToken(); |
308 | 308 |
309 // Code completion of superclass names. | 309 // Code completion of superclass names. |
310 if (Tok.is(tok::code_completion)) { | 310 if (Tok.is(tok::code_completion)) { |
311 cutOffParsing(); | |
311 Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc); | 312 Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc); |
312 cutOffParsing(); | |
313 return nullptr; | 313 return nullptr; |
314 } | 314 } |
315 | 315 |
316 if (expectIdentifier()) | 316 if (expectIdentifier()) |
317 return nullptr; // missing super class name. | 317 return nullptr; // missing super class name. |
470 if (!Tok.is(tok::identifier)) { | 470 if (!Tok.is(tok::identifier)) { |
471 // Code completion. | 471 // Code completion. |
472 if (Tok.is(tok::code_completion)) { | 472 if (Tok.is(tok::code_completion)) { |
473 // FIXME: If these aren't protocol references, we'll need different | 473 // FIXME: If these aren't protocol references, we'll need different |
474 // completions. | 474 // completions. |
475 cutOffParsing(); | |
475 Actions.CodeCompleteObjCProtocolReferences(protocolIdents); | 476 Actions.CodeCompleteObjCProtocolReferences(protocolIdents); |
476 cutOffParsing(); | |
477 | 477 |
478 // FIXME: Better recovery here?. | 478 // FIXME: Better recovery here?. |
479 return nullptr; | 479 return nullptr; |
480 } | 480 } |
481 | 481 |
633 if (isEofOrEom()) | 633 if (isEofOrEom()) |
634 break; | 634 break; |
635 | 635 |
636 // Code completion within an Objective-C interface. | 636 // Code completion within an Objective-C interface. |
637 if (Tok.is(tok::code_completion)) { | 637 if (Tok.is(tok::code_completion)) { |
638 cutOffParsing(); | |
638 Actions.CodeCompleteOrdinaryName(getCurScope(), | 639 Actions.CodeCompleteOrdinaryName(getCurScope(), |
639 CurParsedObjCImpl? Sema::PCC_ObjCImplementation | 640 CurParsedObjCImpl? Sema::PCC_ObjCImplementation |
640 : Sema::PCC_ObjCInterface); | 641 : Sema::PCC_ObjCInterface); |
641 return cutOffParsing(); | 642 return; |
642 } | 643 } |
643 | 644 |
644 // If we don't have an @ directive, parse it as a function definition. | 645 // If we don't have an @ directive, parse it as a function definition. |
645 if (Tok.isNot(tok::at)) { | 646 if (Tok.isNot(tok::at)) { |
646 // The code below does not consume '}'s because it is afraid of eating the | 647 // The code below does not consume '}'s because it is afraid of eating the |
655 // ParseExternalDeclaration() below (so that this doesn't parse nested | 656 // ParseExternalDeclaration() below (so that this doesn't parse nested |
656 // @interfaces), this needs to duplicate some code from the latter. | 657 // @interfaces), this needs to duplicate some code from the latter. |
657 if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) { | 658 if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) { |
658 SourceLocation DeclEnd; | 659 SourceLocation DeclEnd; |
659 allTUVariables.push_back( | 660 allTUVariables.push_back( |
660 ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs)); | 661 ParseDeclaration(DeclaratorContext::File, DeclEnd, attrs)); |
661 continue; | 662 continue; |
662 } | 663 } |
663 | 664 |
664 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs)); | 665 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs)); |
665 continue; | 666 continue; |
666 } | 667 } |
667 | 668 |
668 // Otherwise, we have an @ directive, eat the @. | 669 // Otherwise, we have an @ directive, eat the @. |
669 SourceLocation AtLoc = ConsumeToken(); // the "@" | 670 SourceLocation AtLoc = ConsumeToken(); // the "@" |
670 if (Tok.is(tok::code_completion)) { | 671 if (Tok.is(tok::code_completion)) { |
672 cutOffParsing(); | |
671 Actions.CodeCompleteObjCAtDirective(getCurScope()); | 673 Actions.CodeCompleteObjCAtDirective(getCurScope()); |
672 return cutOffParsing(); | 674 return; |
673 } | 675 } |
674 | 676 |
675 tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID(); | 677 tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID(); |
676 | 678 |
677 if (DirectiveKind == tok::objc_end) { // @end -> terminate list | 679 if (DirectiveKind == tok::objc_end) { // @end -> terminate list |
776 } | 778 } |
777 | 779 |
778 // We break out of the big loop in two cases: when we see @end or when we see | 780 // We break out of the big loop in two cases: when we see @end or when we see |
779 // EOF. In the former case, eat the @end. In the later case, emit an error. | 781 // EOF. In the former case, eat the @end. In the later case, emit an error. |
780 if (Tok.is(tok::code_completion)) { | 782 if (Tok.is(tok::code_completion)) { |
783 cutOffParsing(); | |
781 Actions.CodeCompleteObjCAtDirective(getCurScope()); | 784 Actions.CodeCompleteObjCAtDirective(getCurScope()); |
782 return cutOffParsing(); | 785 return; |
783 } else if (Tok.isObjCAtKeyword(tok::objc_end)) { | 786 } else if (Tok.isObjCAtKeyword(tok::objc_end)) { |
784 ConsumeToken(); // the "end" identifier | 787 ConsumeToken(); // the "end" identifier |
785 } else { | 788 } else { |
786 Diag(Tok, diag::err_objc_missing_end) | 789 Diag(Tok, diag::err_objc_missing_end) |
787 << FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n"); | 790 << FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n"); |
845 BalancedDelimiterTracker T(*this, tok::l_paren); | 848 BalancedDelimiterTracker T(*this, tok::l_paren); |
846 T.consumeOpen(); | 849 T.consumeOpen(); |
847 | 850 |
848 while (1) { | 851 while (1) { |
849 if (Tok.is(tok::code_completion)) { | 852 if (Tok.is(tok::code_completion)) { |
853 cutOffParsing(); | |
850 Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS); | 854 Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS); |
851 return cutOffParsing(); | 855 return; |
852 } | 856 } |
853 const IdentifierInfo *II = Tok.getIdentifierInfo(); | 857 const IdentifierInfo *II = Tok.getIdentifierInfo(); |
854 | 858 |
855 // If this is not an identifier at all, bail out early. | 859 // If this is not an identifier at all, bail out early. |
856 if (!II) { | 860 if (!II) { |
891 SkipUntil(tok::r_paren, StopAtSemi); | 895 SkipUntil(tok::r_paren, StopAtSemi); |
892 return; | 896 return; |
893 } | 897 } |
894 | 898 |
895 if (Tok.is(tok::code_completion)) { | 899 if (Tok.is(tok::code_completion)) { |
900 cutOffParsing(); | |
896 if (IsSetter) | 901 if (IsSetter) |
897 Actions.CodeCompleteObjCPropertySetter(getCurScope()); | 902 Actions.CodeCompleteObjCPropertySetter(getCurScope()); |
898 else | 903 else |
899 Actions.CodeCompleteObjCPropertyGetter(getCurScope()); | 904 Actions.CodeCompleteObjCPropertyGetter(getCurScope()); |
900 return cutOffParsing(); | 905 return; |
901 } | 906 } |
902 | 907 |
903 SourceLocation SelLoc; | 908 SourceLocation SelLoc; |
904 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc); | 909 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc); |
905 | 910 |
1139 /// 'nullable' | 1144 /// 'nullable' |
1140 /// 'null_unspecified' | 1145 /// 'null_unspecified' |
1141 /// | 1146 /// |
1142 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, | 1147 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, |
1143 DeclaratorContext Context) { | 1148 DeclaratorContext Context) { |
1144 assert(Context == DeclaratorContext::ObjCParameterContext || | 1149 assert(Context == DeclaratorContext::ObjCParameter || |
1145 Context == DeclaratorContext::ObjCResultContext); | 1150 Context == DeclaratorContext::ObjCResult); |
1146 | 1151 |
1147 while (1) { | 1152 while (1) { |
1148 if (Tok.is(tok::code_completion)) { | 1153 if (Tok.is(tok::code_completion)) { |
1149 Actions.CodeCompleteObjCPassingType(getCurScope(), DS, | 1154 cutOffParsing(); |
1150 Context == DeclaratorContext::ObjCParameterContext); | 1155 Actions.CodeCompleteObjCPassingType( |
1151 return cutOffParsing(); | 1156 getCurScope(), DS, Context == DeclaratorContext::ObjCParameter); |
1157 return; | |
1152 } | 1158 } |
1153 | 1159 |
1154 if (Tok.isNot(tok::identifier)) | 1160 if (Tok.isNot(tok::identifier)) |
1155 return; | 1161 return; |
1156 | 1162 |
1235 /// '(' objc-type-qualifiers[opt] ')' | 1241 /// '(' objc-type-qualifiers[opt] ')' |
1236 /// | 1242 /// |
1237 ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, | 1243 ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, |
1238 DeclaratorContext context, | 1244 DeclaratorContext context, |
1239 ParsedAttributes *paramAttrs) { | 1245 ParsedAttributes *paramAttrs) { |
1240 assert(context == DeclaratorContext::ObjCParameterContext || | 1246 assert(context == DeclaratorContext::ObjCParameter || |
1241 context == DeclaratorContext::ObjCResultContext); | 1247 context == DeclaratorContext::ObjCResult); |
1242 assert((paramAttrs != nullptr) == | 1248 assert((paramAttrs != nullptr) == |
1243 (context == DeclaratorContext::ObjCParameterContext)); | 1249 (context == DeclaratorContext::ObjCParameter)); |
1244 | 1250 |
1245 assert(Tok.is(tok::l_paren) && "expected ("); | 1251 assert(Tok.is(tok::l_paren) && "expected ("); |
1246 | 1252 |
1247 BalancedDelimiterTracker T(*this, tok::l_paren); | 1253 BalancedDelimiterTracker T(*this, tok::l_paren); |
1248 T.consumeOpen(); | 1254 T.consumeOpen(); |
1257 if (isTypeSpecifierQualifier() || isObjCInstancetype()) { | 1263 if (isTypeSpecifierQualifier() || isObjCInstancetype()) { |
1258 // Parse an abstract declarator. | 1264 // Parse an abstract declarator. |
1259 DeclSpec declSpec(AttrFactory); | 1265 DeclSpec declSpec(AttrFactory); |
1260 declSpec.setObjCQualifiers(&DS); | 1266 declSpec.setObjCQualifiers(&DS); |
1261 DeclSpecContext dsContext = DeclSpecContext::DSC_normal; | 1267 DeclSpecContext dsContext = DeclSpecContext::DSC_normal; |
1262 if (context == DeclaratorContext::ObjCResultContext) | 1268 if (context == DeclaratorContext::ObjCResult) |
1263 dsContext = DeclSpecContext::DSC_objc_method_result; | 1269 dsContext = DeclSpecContext::DSC_objc_method_result; |
1264 ParseSpecifierQualifierList(declSpec, AS_none, dsContext); | 1270 ParseSpecifierQualifierList(declSpec, AS_none, dsContext); |
1265 Declarator declarator(declSpec, context); | 1271 Declarator declarator(declSpec, context); |
1266 ParseDeclarator(declarator); | 1272 ParseDeclarator(declarator); |
1267 | 1273 |
1279 if (!type.isInvalid()) | 1285 if (!type.isInvalid()) |
1280 Ty = type.get(); | 1286 Ty = type.get(); |
1281 | 1287 |
1282 // If we're parsing a parameter, steal all the decl attributes | 1288 // If we're parsing a parameter, steal all the decl attributes |
1283 // and add them to the decl spec. | 1289 // and add them to the decl spec. |
1284 if (context == DeclaratorContext::ObjCParameterContext) | 1290 if (context == DeclaratorContext::ObjCParameter) |
1285 takeDeclAttributes(*paramAttrs, declarator); | 1291 takeDeclAttributes(*paramAttrs, declarator); |
1286 } | 1292 } |
1287 } | 1293 } |
1288 | 1294 |
1289 if (Tok.is(tok::r_paren)) | 1295 if (Tok.is(tok::r_paren)) |
1333 tok::ObjCKeywordKind MethodImplKind, | 1339 tok::ObjCKeywordKind MethodImplKind, |
1334 bool MethodDefinition) { | 1340 bool MethodDefinition) { |
1335 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent); | 1341 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent); |
1336 | 1342 |
1337 if (Tok.is(tok::code_completion)) { | 1343 if (Tok.is(tok::code_completion)) { |
1344 cutOffParsing(); | |
1338 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, | 1345 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, |
1339 /*ReturnType=*/nullptr); | 1346 /*ReturnType=*/nullptr); |
1340 cutOffParsing(); | |
1341 return nullptr; | 1347 return nullptr; |
1342 } | 1348 } |
1343 | 1349 |
1344 // Parse the return type if present. | 1350 // Parse the return type if present. |
1345 ParsedType ReturnType; | 1351 ParsedType ReturnType; |
1346 ObjCDeclSpec DSRet; | 1352 ObjCDeclSpec DSRet; |
1347 if (Tok.is(tok::l_paren)) | 1353 if (Tok.is(tok::l_paren)) |
1348 ReturnType = ParseObjCTypeName(DSRet, DeclaratorContext::ObjCResultContext, | 1354 ReturnType = |
1349 nullptr); | 1355 ParseObjCTypeName(DSRet, DeclaratorContext::ObjCResult, nullptr); |
1350 | 1356 |
1351 // If attributes exist before the method, parse them. | 1357 // If attributes exist before the method, parse them. |
1352 ParsedAttributes methodAttrs(AttrFactory); | 1358 ParsedAttributes methodAttrs(AttrFactory); |
1353 if (getLangOpts().ObjC) | 1359 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0), |
1354 MaybeParseGNUAttributes(methodAttrs); | 1360 methodAttrs); |
1355 MaybeParseCXX11Attributes(methodAttrs); | |
1356 | 1361 |
1357 if (Tok.is(tok::code_completion)) { | 1362 if (Tok.is(tok::code_completion)) { |
1363 cutOffParsing(); | |
1358 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, | 1364 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, |
1359 ReturnType); | 1365 ReturnType); |
1360 cutOffParsing(); | |
1361 return nullptr; | 1366 return nullptr; |
1362 } | 1367 } |
1363 | 1368 |
1364 // Now parse the selector. | 1369 // Now parse the selector. |
1365 SourceLocation selLoc; | 1370 SourceLocation selLoc; |
1375 } | 1380 } |
1376 | 1381 |
1377 SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo; | 1382 SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo; |
1378 if (Tok.isNot(tok::colon)) { | 1383 if (Tok.isNot(tok::colon)) { |
1379 // If attributes exist after the method, parse them. | 1384 // If attributes exist after the method, parse them. |
1380 if (getLangOpts().ObjC) | 1385 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0), |
1381 MaybeParseGNUAttributes(methodAttrs); | 1386 methodAttrs); |
1382 MaybeParseCXX11Attributes(methodAttrs); | |
1383 | 1387 |
1384 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); | 1388 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); |
1385 Decl *Result = Actions.ActOnMethodDeclaration( | 1389 Decl *Result = Actions.ActOnMethodDeclaration( |
1386 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, | 1390 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, |
1387 selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs, | 1391 selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs, |
1405 if (ExpectAndConsume(tok::colon)) | 1409 if (ExpectAndConsume(tok::colon)) |
1406 break; | 1410 break; |
1407 | 1411 |
1408 ArgInfo.Type = nullptr; | 1412 ArgInfo.Type = nullptr; |
1409 if (Tok.is(tok::l_paren)) // Parse the argument type if present. | 1413 if (Tok.is(tok::l_paren)) // Parse the argument type if present. |
1410 ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec, | 1414 ArgInfo.Type = ParseObjCTypeName( |
1411 DeclaratorContext::ObjCParameterContext, | 1415 ArgInfo.DeclSpec, DeclaratorContext::ObjCParameter, ¶mAttrs); |
1412 ¶mAttrs); | |
1413 | 1416 |
1414 // If attributes exist before the argument name, parse them. | 1417 // If attributes exist before the argument name, parse them. |
1415 // Regardless, collect all the attributes we've parsed so far. | 1418 // Regardless, collect all the attributes we've parsed so far. |
1416 if (getLangOpts().ObjC) | 1419 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0), |
1417 MaybeParseGNUAttributes(paramAttrs); | 1420 paramAttrs); |
1418 MaybeParseCXX11Attributes(paramAttrs); | |
1419 ArgInfo.ArgAttrs = paramAttrs; | 1421 ArgInfo.ArgAttrs = paramAttrs; |
1420 | 1422 |
1421 // Code completion for the next piece of the selector. | 1423 // Code completion for the next piece of the selector. |
1422 if (Tok.is(tok::code_completion)) { | 1424 if (Tok.is(tok::code_completion)) { |
1425 cutOffParsing(); | |
1423 KeyIdents.push_back(SelIdent); | 1426 KeyIdents.push_back(SelIdent); |
1424 Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), | 1427 Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), |
1425 mType == tok::minus, | 1428 mType == tok::minus, |
1426 /*AtParameterName=*/true, | 1429 /*AtParameterName=*/true, |
1427 ReturnType, KeyIdents); | 1430 ReturnType, KeyIdents); |
1428 cutOffParsing(); | |
1429 return nullptr; | 1431 return nullptr; |
1430 } | 1432 } |
1431 | 1433 |
1432 if (expectIdentifier()) | 1434 if (expectIdentifier()) |
1433 break; // missing argument name. | 1435 break; // missing argument name. |
1443 // Make sure the attributes persist. | 1445 // Make sure the attributes persist. |
1444 allParamAttrs.takeAllFrom(paramAttrs.getPool()); | 1446 allParamAttrs.takeAllFrom(paramAttrs.getPool()); |
1445 | 1447 |
1446 // Code completion for the next piece of the selector. | 1448 // Code completion for the next piece of the selector. |
1447 if (Tok.is(tok::code_completion)) { | 1449 if (Tok.is(tok::code_completion)) { |
1450 cutOffParsing(); | |
1448 Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), | 1451 Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(), |
1449 mType == tok::minus, | 1452 mType == tok::minus, |
1450 /*AtParameterName=*/false, | 1453 /*AtParameterName=*/false, |
1451 ReturnType, KeyIdents); | 1454 ReturnType, KeyIdents); |
1452 cutOffParsing(); | |
1453 return nullptr; | 1455 return nullptr; |
1454 } | 1456 } |
1455 | 1457 |
1456 // Check for another keyword selector. | 1458 // Check for another keyword selector. |
1457 SelIdent = ParseObjCSelectorPiece(selLoc); | 1459 SelIdent = ParseObjCSelectorPiece(selLoc); |
1483 cStyleParamWarned = true; | 1485 cStyleParamWarned = true; |
1484 } | 1486 } |
1485 DeclSpec DS(AttrFactory); | 1487 DeclSpec DS(AttrFactory); |
1486 ParseDeclarationSpecifiers(DS); | 1488 ParseDeclarationSpecifiers(DS); |
1487 // Parse the declarator. | 1489 // Parse the declarator. |
1488 Declarator ParmDecl(DS, DeclaratorContext::PrototypeContext); | 1490 Declarator ParmDecl(DS, DeclaratorContext::Prototype); |
1489 ParseDeclarator(ParmDecl); | 1491 ParseDeclarator(ParmDecl); |
1490 IdentifierInfo *ParmII = ParmDecl.getIdentifier(); | 1492 IdentifierInfo *ParmII = ParmDecl.getIdentifier(); |
1491 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); | 1493 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); |
1492 CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, | 1494 CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, |
1493 ParmDecl.getIdentifierLoc(), | 1495 ParmDecl.getIdentifierLoc(), |
1495 nullptr)); | 1497 nullptr)); |
1496 } | 1498 } |
1497 | 1499 |
1498 // FIXME: Add support for optional parameter list... | 1500 // FIXME: Add support for optional parameter list... |
1499 // If attributes exist after the method, parse them. | 1501 // If attributes exist after the method, parse them. |
1500 if (getLangOpts().ObjC) | 1502 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0), |
1501 MaybeParseGNUAttributes(methodAttrs); | 1503 methodAttrs); |
1502 MaybeParseCXX11Attributes(methodAttrs); | |
1503 | 1504 |
1504 if (KeyIdents.size() == 0) | 1505 if (KeyIdents.size() == 0) |
1505 return nullptr; | 1506 return nullptr; |
1506 | 1507 |
1507 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), | 1508 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), |
1530 | 1531 |
1531 SmallVector<IdentifierLocPair, 8> ProtocolIdents; | 1532 SmallVector<IdentifierLocPair, 8> ProtocolIdents; |
1532 | 1533 |
1533 while (1) { | 1534 while (1) { |
1534 if (Tok.is(tok::code_completion)) { | 1535 if (Tok.is(tok::code_completion)) { |
1536 cutOffParsing(); | |
1535 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents); | 1537 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents); |
1536 cutOffParsing(); | |
1537 return true; | 1538 return true; |
1538 } | 1539 } |
1539 | 1540 |
1540 if (expectIdentifier()) { | 1541 if (expectIdentifier()) { |
1541 SkipUntil(tok::greater, StopAtSemi); | 1542 SkipUntil(tok::greater, StopAtSemi); |
1629 identifierLocPairs.push_back(IdentifierLocPair(identifiers[i], | 1630 identifierLocPairs.push_back(IdentifierLocPair(identifiers[i], |
1630 identifierLocs[i])); | 1631 identifierLocs[i])); |
1631 } | 1632 } |
1632 | 1633 |
1633 QualType BaseT = Actions.GetTypeFromParser(baseType); | 1634 QualType BaseT = Actions.GetTypeFromParser(baseType); |
1635 cutOffParsing(); | |
1634 if (!BaseT.isNull() && BaseT->acceptsObjCTypeParams()) { | 1636 if (!BaseT.isNull() && BaseT->acceptsObjCTypeParams()) { |
1635 Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); | 1637 Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); |
1636 } else { | 1638 } else { |
1637 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs); | 1639 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs); |
1638 } | 1640 } |
1639 cutOffParsing(); | |
1640 return; | 1641 return; |
1641 } | 1642 } |
1642 | 1643 |
1643 allSingleIdentifiers = false; | 1644 allSingleIdentifiers = false; |
1644 break; | 1645 break; |
1690 unsigned diagID; | 1691 unsigned diagID; |
1691 DS.SetTypeSpecType(TST_typename, identifierLocs[i], prevSpec, diagID, | 1692 DS.SetTypeSpecType(TST_typename, identifierLocs[i], prevSpec, diagID, |
1692 typeArg, Actions.getASTContext().getPrintingPolicy()); | 1693 typeArg, Actions.getASTContext().getPrintingPolicy()); |
1693 | 1694 |
1694 // Form a declarator to turn this into a type. | 1695 // Form a declarator to turn this into a type. |
1695 Declarator D(DS, DeclaratorContext::TypeNameContext); | 1696 Declarator D(DS, DeclaratorContext::TypeName); |
1696 TypeResult fullTypeArg = Actions.ActOnTypeName(getCurScope(), D); | 1697 TypeResult fullTypeArg = Actions.ActOnTypeName(getCurScope(), D); |
1697 if (fullTypeArg.isUsable()) { | 1698 if (fullTypeArg.isUsable()) { |
1698 typeArgs.push_back(fullTypeArg.get()); | 1699 typeArgs.push_back(fullTypeArg.get()); |
1699 if (!foundValidTypeId) { | 1700 if (!foundValidTypeId) { |
1700 foundValidTypeId = identifiers[i]; | 1701 foundValidTypeId = identifiers[i]; |
1923 } | 1924 } |
1924 | 1925 |
1925 // Set the default visibility to private. | 1926 // Set the default visibility to private. |
1926 if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec | 1927 if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec |
1927 if (Tok.is(tok::code_completion)) { | 1928 if (Tok.is(tok::code_completion)) { |
1929 cutOffParsing(); | |
1928 Actions.CodeCompleteObjCAtVisibility(getCurScope()); | 1930 Actions.CodeCompleteObjCAtVisibility(getCurScope()); |
1929 return cutOffParsing(); | 1931 return; |
1930 } | 1932 } |
1931 | 1933 |
1932 switch (Tok.getObjCKeywordID()) { | 1934 switch (Tok.getObjCKeywordID()) { |
1933 case tok::objc_private: | 1935 case tok::objc_private: |
1934 case tok::objc_public: | 1936 case tok::objc_public: |
1953 continue; | 1955 continue; |
1954 } | 1956 } |
1955 } | 1957 } |
1956 | 1958 |
1957 if (Tok.is(tok::code_completion)) { | 1959 if (Tok.is(tok::code_completion)) { |
1960 cutOffParsing(); | |
1958 Actions.CodeCompleteOrdinaryName(getCurScope(), | 1961 Actions.CodeCompleteOrdinaryName(getCurScope(), |
1959 Sema::PCC_ObjCInstanceVariableList); | 1962 Sema::PCC_ObjCInstanceVariableList); |
1960 return cutOffParsing(); | 1963 return; |
1961 } | 1964 } |
1962 | 1965 |
1963 // This needs to duplicate a small amount of code from | 1966 // This needs to duplicate a small amount of code from |
1964 // ParseStructUnionBody() for things that should work in both | 1967 // ParseStructUnionBody() for things that should work in both |
1965 // C struct and in Objective-C class instance variables. | 1968 // C struct and in Objective-C class instance variables. |
2020 assert(Tok.isObjCAtKeyword(tok::objc_protocol) && | 2023 assert(Tok.isObjCAtKeyword(tok::objc_protocol) && |
2021 "ParseObjCAtProtocolDeclaration(): Expected @protocol"); | 2024 "ParseObjCAtProtocolDeclaration(): Expected @protocol"); |
2022 ConsumeToken(); // the "protocol" identifier | 2025 ConsumeToken(); // the "protocol" identifier |
2023 | 2026 |
2024 if (Tok.is(tok::code_completion)) { | 2027 if (Tok.is(tok::code_completion)) { |
2028 cutOffParsing(); | |
2025 Actions.CodeCompleteObjCProtocolDecl(getCurScope()); | 2029 Actions.CodeCompleteObjCProtocolDecl(getCurScope()); |
2026 cutOffParsing(); | |
2027 return nullptr; | 2030 return nullptr; |
2028 } | 2031 } |
2029 | 2032 |
2030 MaybeSkipAttributes(tok::objc_protocol); | 2033 MaybeSkipAttributes(tok::objc_protocol); |
2031 | 2034 |
2104 CheckNestedObjCContexts(AtLoc); | 2107 CheckNestedObjCContexts(AtLoc); |
2105 ConsumeToken(); // the "implementation" identifier | 2108 ConsumeToken(); // the "implementation" identifier |
2106 | 2109 |
2107 // Code completion after '@implementation'. | 2110 // Code completion after '@implementation'. |
2108 if (Tok.is(tok::code_completion)) { | 2111 if (Tok.is(tok::code_completion)) { |
2112 cutOffParsing(); | |
2109 Actions.CodeCompleteObjCImplementationDecl(getCurScope()); | 2113 Actions.CodeCompleteObjCImplementationDecl(getCurScope()); |
2110 cutOffParsing(); | |
2111 return nullptr; | 2114 return nullptr; |
2112 } | 2115 } |
2113 | 2116 |
2114 MaybeSkipAttributes(tok::objc_implementation); | 2117 MaybeSkipAttributes(tok::objc_implementation); |
2115 | 2118 |
2142 ConsumeParen(); | 2145 ConsumeParen(); |
2143 SourceLocation categoryLoc, rparenLoc; | 2146 SourceLocation categoryLoc, rparenLoc; |
2144 IdentifierInfo *categoryId = nullptr; | 2147 IdentifierInfo *categoryId = nullptr; |
2145 | 2148 |
2146 if (Tok.is(tok::code_completion)) { | 2149 if (Tok.is(tok::code_completion)) { |
2150 cutOffParsing(); | |
2147 Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc); | 2151 Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc); |
2148 cutOffParsing(); | |
2149 return nullptr; | 2152 return nullptr; |
2150 } | 2153 } |
2151 | 2154 |
2152 if (Tok.is(tok::identifier)) { | 2155 if (Tok.is(tok::identifier)) { |
2153 categoryId = Tok.getIdentifierInfo(); | 2156 categoryId = Tok.getIdentifierInfo(); |
2312 "ParseObjCPropertySynthesize(): Expected '@synthesize'"); | 2315 "ParseObjCPropertySynthesize(): Expected '@synthesize'"); |
2313 ConsumeToken(); // consume synthesize | 2316 ConsumeToken(); // consume synthesize |
2314 | 2317 |
2315 while (true) { | 2318 while (true) { |
2316 if (Tok.is(tok::code_completion)) { | 2319 if (Tok.is(tok::code_completion)) { |
2320 cutOffParsing(); | |
2317 Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); | 2321 Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); |
2318 cutOffParsing(); | |
2319 return nullptr; | 2322 return nullptr; |
2320 } | 2323 } |
2321 | 2324 |
2322 if (Tok.isNot(tok::identifier)) { | 2325 if (Tok.isNot(tok::identifier)) { |
2323 Diag(Tok, diag::err_synthesized_property_name); | 2326 Diag(Tok, diag::err_synthesized_property_name); |
2330 SourceLocation propertyLoc = ConsumeToken(); // consume property name | 2333 SourceLocation propertyLoc = ConsumeToken(); // consume property name |
2331 SourceLocation propertyIvarLoc; | 2334 SourceLocation propertyIvarLoc; |
2332 if (TryConsumeToken(tok::equal)) { | 2335 if (TryConsumeToken(tok::equal)) { |
2333 // property '=' ivar-name | 2336 // property '=' ivar-name |
2334 if (Tok.is(tok::code_completion)) { | 2337 if (Tok.is(tok::code_completion)) { |
2338 cutOffParsing(); | |
2335 Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId); | 2339 Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId); |
2336 cutOffParsing(); | |
2337 return nullptr; | 2340 return nullptr; |
2338 } | 2341 } |
2339 | 2342 |
2340 if (expectIdentifier()) | 2343 if (expectIdentifier()) |
2341 break; | 2344 break; |
2390 } | 2393 } |
2391 } | 2394 } |
2392 | 2395 |
2393 while (true) { | 2396 while (true) { |
2394 if (Tok.is(tok::code_completion)) { | 2397 if (Tok.is(tok::code_completion)) { |
2398 cutOffParsing(); | |
2395 Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); | 2399 Actions.CodeCompleteObjCPropertyDefinition(getCurScope()); |
2396 cutOffParsing(); | |
2397 return nullptr; | 2400 return nullptr; |
2398 } | 2401 } |
2399 | 2402 |
2400 if (expectIdentifier()) { | 2403 if (expectIdentifier()) { |
2401 SkipUntil(tok::semi); | 2404 SkipUntil(tok::semi); |
2534 Scope::CompoundStmtScope | | 2537 Scope::CompoundStmtScope | |
2535 Scope::AtCatchScope); | 2538 Scope::AtCatchScope); |
2536 if (Tok.isNot(tok::ellipsis)) { | 2539 if (Tok.isNot(tok::ellipsis)) { |
2537 DeclSpec DS(AttrFactory); | 2540 DeclSpec DS(AttrFactory); |
2538 ParseDeclarationSpecifiers(DS); | 2541 ParseDeclarationSpecifiers(DS); |
2539 Declarator ParmDecl(DS, DeclaratorContext::ObjCCatchContext); | 2542 Declarator ParmDecl(DS, DeclaratorContext::ObjCCatch); |
2540 ParseDeclarator(ParmDecl); | 2543 ParseDeclarator(ParmDecl); |
2541 | 2544 |
2542 // Inform the actions module about the declarator, so it | 2545 // Inform the actions module about the declarator, so it |
2543 // gets added to the current scope. | 2546 // gets added to the current scope. |
2544 FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl); | 2547 FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl); |
2727 } | 2730 } |
2728 | 2731 |
2729 StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc, | 2732 StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc, |
2730 ParsedStmtContext StmtCtx) { | 2733 ParsedStmtContext StmtCtx) { |
2731 if (Tok.is(tok::code_completion)) { | 2734 if (Tok.is(tok::code_completion)) { |
2735 cutOffParsing(); | |
2732 Actions.CodeCompleteObjCAtStatement(getCurScope()); | 2736 Actions.CodeCompleteObjCAtStatement(getCurScope()); |
2733 cutOffParsing(); | |
2734 return StmtError(); | 2737 return StmtError(); |
2735 } | 2738 } |
2736 | 2739 |
2737 if (Tok.isObjCAtKeyword(tok::objc_try)) | 2740 if (Tok.isObjCAtKeyword(tok::objc_try)) |
2738 return ParseObjCTryStmt(AtLoc); | 2741 return ParseObjCTryStmt(AtLoc); |
2768 } | 2771 } |
2769 | 2772 |
2770 ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { | 2773 ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { |
2771 switch (Tok.getKind()) { | 2774 switch (Tok.getKind()) { |
2772 case tok::code_completion: | 2775 case tok::code_completion: |
2776 cutOffParsing(); | |
2773 Actions.CodeCompleteObjCAtExpression(getCurScope()); | 2777 Actions.CodeCompleteObjCAtExpression(getCurScope()); |
2774 cutOffParsing(); | |
2775 return ExprError(); | 2778 return ExprError(); |
2776 | 2779 |
2777 case tok::minus: | 2780 case tok::minus: |
2778 case tok::plus: { | 2781 case tok::plus: { |
2779 tok::TokenKind Kind = Tok.getKind(); | 2782 tok::TokenKind Kind = Tok.getKind(); |
2950 } | 2953 } |
2951 | 2954 |
2952 // We have a class message. Turn the simple-type-specifier or | 2955 // We have a class message. Turn the simple-type-specifier or |
2953 // typename-specifier we parsed into a type and parse the | 2956 // typename-specifier we parsed into a type and parse the |
2954 // remainder of the class message. | 2957 // remainder of the class message. |
2955 Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); | 2958 Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); |
2956 TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); | 2959 TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); |
2957 if (Type.isInvalid()) | 2960 if (Type.isInvalid()) |
2958 return true; | 2961 return true; |
2959 | 2962 |
2960 IsExpr = false; | 2963 IsExpr = false; |
3015 ExprResult Parser::ParseObjCMessageExpression() { | 3018 ExprResult Parser::ParseObjCMessageExpression() { |
3016 assert(Tok.is(tok::l_square) && "'[' expected"); | 3019 assert(Tok.is(tok::l_square) && "'[' expected"); |
3017 SourceLocation LBracLoc = ConsumeBracket(); // consume '[' | 3020 SourceLocation LBracLoc = ConsumeBracket(); // consume '[' |
3018 | 3021 |
3019 if (Tok.is(tok::code_completion)) { | 3022 if (Tok.is(tok::code_completion)) { |
3023 cutOffParsing(); | |
3020 Actions.CodeCompleteObjCMessageReceiver(getCurScope()); | 3024 Actions.CodeCompleteObjCMessageReceiver(getCurScope()); |
3021 cutOffParsing(); | |
3022 return ExprError(); | 3025 return ExprError(); |
3023 } | 3026 } |
3024 | 3027 |
3025 InMessageExpressionRAIIObject InMessage(*this, true); | 3028 InMessageExpressionRAIIObject InMessage(*this, true); |
3026 | 3029 |
3152 ParsedType ReceiverType, | 3155 ParsedType ReceiverType, |
3153 Expr *ReceiverExpr) { | 3156 Expr *ReceiverExpr) { |
3154 InMessageExpressionRAIIObject InMessage(*this, true); | 3157 InMessageExpressionRAIIObject InMessage(*this, true); |
3155 | 3158 |
3156 if (Tok.is(tok::code_completion)) { | 3159 if (Tok.is(tok::code_completion)) { |
3160 cutOffParsing(); | |
3157 if (SuperLoc.isValid()) | 3161 if (SuperLoc.isValid()) |
3158 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None, | 3162 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None, |
3159 false); | 3163 false); |
3160 else if (ReceiverType) | 3164 else if (ReceiverType) |
3161 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, None, | 3165 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, None, |
3162 false); | 3166 false); |
3163 else | 3167 else |
3164 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, | 3168 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, |
3165 None, false); | 3169 None, false); |
3166 cutOffParsing(); | |
3167 return ExprError(); | 3170 return ExprError(); |
3168 } | 3171 } |
3169 | 3172 |
3170 // Parse objc-selector | 3173 // Parse objc-selector |
3171 SourceLocation Loc; | 3174 SourceLocation Loc; |
3190 } | 3193 } |
3191 | 3194 |
3192 /// Parse the expression after ':' | 3195 /// Parse the expression after ':' |
3193 | 3196 |
3194 if (Tok.is(tok::code_completion)) { | 3197 if (Tok.is(tok::code_completion)) { |
3198 cutOffParsing(); | |
3195 if (SuperLoc.isValid()) | 3199 if (SuperLoc.isValid()) |
3196 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, | 3200 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, |
3197 KeyIdents, | 3201 KeyIdents, |
3198 /*AtArgumentExpression=*/true); | 3202 /*AtArgumentExpression=*/true); |
3199 else if (ReceiverType) | 3203 else if (ReceiverType) |
3203 else | 3207 else |
3204 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, | 3208 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, |
3205 KeyIdents, | 3209 KeyIdents, |
3206 /*AtArgumentExpression=*/true); | 3210 /*AtArgumentExpression=*/true); |
3207 | 3211 |
3208 cutOffParsing(); | |
3209 return ExprError(); | 3212 return ExprError(); |
3210 } | 3213 } |
3211 | 3214 |
3212 ExprResult Expr; | 3215 ExprResult Expr; |
3213 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { | 3216 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { |
3228 // We have a valid expression. | 3231 // We have a valid expression. |
3229 KeyExprs.push_back(Res.get()); | 3232 KeyExprs.push_back(Res.get()); |
3230 | 3233 |
3231 // Code completion after each argument. | 3234 // Code completion after each argument. |
3232 if (Tok.is(tok::code_completion)) { | 3235 if (Tok.is(tok::code_completion)) { |
3236 cutOffParsing(); | |
3233 if (SuperLoc.isValid()) | 3237 if (SuperLoc.isValid()) |
3234 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, | 3238 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, |
3235 KeyIdents, | 3239 KeyIdents, |
3236 /*AtArgumentExpression=*/false); | 3240 /*AtArgumentExpression=*/false); |
3237 else if (ReceiverType) | 3241 else if (ReceiverType) |
3240 /*AtArgumentExpression=*/false); | 3244 /*AtArgumentExpression=*/false); |
3241 else | 3245 else |
3242 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, | 3246 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, |
3243 KeyIdents, | 3247 KeyIdents, |
3244 /*AtArgumentExpression=*/false); | 3248 /*AtArgumentExpression=*/false); |
3245 cutOffParsing(); | |
3246 return ExprError(); | 3249 return ExprError(); |
3247 } | 3250 } |
3248 | 3251 |
3249 // Check for another keyword selector. | 3252 // Check for another keyword selector. |
3250 selIdent = ParseObjCSelectorPiece(Loc); | 3253 selIdent = ParseObjCSelectorPiece(Loc); |
3580 bool HasOptionalParen = Tok.is(tok::l_paren); | 3583 bool HasOptionalParen = Tok.is(tok::l_paren); |
3581 if (HasOptionalParen) | 3584 if (HasOptionalParen) |
3582 ConsumeParen(); | 3585 ConsumeParen(); |
3583 | 3586 |
3584 if (Tok.is(tok::code_completion)) { | 3587 if (Tok.is(tok::code_completion)) { |
3588 cutOffParsing(); | |
3585 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); | 3589 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); |
3586 cutOffParsing(); | |
3587 return ExprError(); | 3590 return ExprError(); |
3588 } | 3591 } |
3589 | 3592 |
3590 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc); | 3593 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc); |
3591 if (!SelIdent && // missing selector name. | 3594 if (!SelIdent && // missing selector name. |
3606 | 3609 |
3607 if (Tok.is(tok::r_paren)) | 3610 if (Tok.is(tok::r_paren)) |
3608 break; | 3611 break; |
3609 | 3612 |
3610 if (Tok.is(tok::code_completion)) { | 3613 if (Tok.is(tok::code_completion)) { |
3614 cutOffParsing(); | |
3611 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); | 3615 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents); |
3612 cutOffParsing(); | |
3613 return ExprError(); | 3616 return ExprError(); |
3614 } | 3617 } |
3615 | 3618 |
3616 // Check for another keyword selector. | 3619 // Check for another keyword selector. |
3617 SourceLocation Loc; | 3620 SourceLocation Loc; |