22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/StringExtras.h" 25 using namespace clang;
30 if (Tok.
is(tok::kw___attribute)) {
31 if (Kind == tok::objc_interface || Kind == tok::objc_protocol)
32 Diag(Tok, diag::err_objc_postfix_attribute_hint)
33 << (Kind == tok::objc_protocol);
35 Diag(Tok, diag::err_objc_postfix_attribute);
36 ParseGNUAttributes(attrs);
49 Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) {
52 if (Tok.
is(tok::code_completion)) {
58 Decl *SingleDecl =
nullptr;
61 return ParseObjCAtClassDeclaration(AtLoc);
62 case tok::objc_interface:
63 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, Attrs);
65 case tok::objc_protocol:
66 return ParseObjCAtProtocolDeclaration(AtLoc, Attrs);
67 case tok::objc_implementation:
68 return ParseObjCAtImplementationDeclaration(AtLoc);
70 return ParseObjCAtEndDeclaration(AtLoc);
71 case tok::objc_compatibility_alias:
72 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
74 case tok::objc_synthesize:
75 SingleDecl = ParseObjCPropertySynthesize(AtLoc);
77 case tok::objc_dynamic:
78 SingleDecl = ParseObjCPropertyDynamic(AtLoc);
80 case tok::objc_import:
82 SingleDecl = ParseModuleImport(AtLoc);
85 Diag(AtLoc, diag::err_atimport);
89 Diag(AtLoc, diag::err_unexpected_at);
105 : Actions(Actions), S(S), Params(nullptr) {}
138 MaybeSkipAttributes(tok::objc_class);
139 if (expectIdentifier()) {
141 return Actions.ConvertDeclToDeclGroup(
nullptr);
143 ClassNames.push_back(Tok.getIdentifierInfo());
144 ClassLocs.push_back(Tok.getLocation());
149 if (Tok.
is(tok::less))
150 TypeParams = parseObjCTypeParamList();
151 ClassTypeParams.push_back(TypeParams);
157 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@class"))
158 return Actions.ConvertDeclToDeclGroup(
nullptr);
160 return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
172 Decl *
Decl = Actions.getObjCDeclContext();
173 if (CurParsedObjCImpl) {
174 CurParsedObjCImpl->finish(AtLoc);
178 Diag(AtLoc, diag::err_objc_missing_end)
217 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
218 CheckNestedObjCContexts(AtLoc);
222 if (Tok.
is(tok::code_completion)) {
223 Actions.CodeCompleteObjCInterfaceDecl(
getCurScope());
228 MaybeSkipAttributes(tok::objc_interface);
230 if (expectIdentifier())
244 if (Tok.
is(tok::less))
245 typeParameterList = parseObjCTypeParamListOrProtocolRefs(
246 typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
248 if (Tok.
is(tok::l_paren) &&
249 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
256 if (Tok.
is(tok::code_completion)) {
257 Actions.CodeCompleteObjCInterfaceCategory(
getCurScope(), nameId, nameLoc);
263 if (Tok.
is(tok::identifier)) {
264 categoryId = Tok.getIdentifierInfo();
268 Diag(Tok, diag::err_expected)
278 assert(LAngleLoc.
isInvalid() &&
"Cannot have already parsed protocols");
281 if (Tok.
is(tok::less) &&
282 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
true,
true,
283 LAngleLoc, EndProtoLoc,
287 Decl *CategoryType = Actions.ActOnStartCategoryInterface(
288 AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
289 ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
292 if (Tok.
is(tok::l_brace))
293 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
295 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
307 if (Tok.
is(tok::colon)) {
311 if (Tok.
is(tok::code_completion)) {
312 Actions.CodeCompleteObjCSuperclass(
getCurScope(), nameId, nameLoc);
317 if (expectIdentifier())
319 superClassId = Tok.getIdentifierInfo();
323 if (Tok.
is(tok::less)) {
324 parseObjCTypeArgsOrProtocolQualifiers(
325 nullptr, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, LAngleLoc,
326 protocols, protocolLocs, EndProtoLoc,
336 if (!ProtocolIdents.empty()) {
339 for (
const auto &pair : ProtocolIdents) {
340 protocolLocs.push_back(pair.second);
342 Actions.FindProtocolDeclaration(
true,
344 ProtocolIdents, protocols);
346 }
else if (protocols.empty() && Tok.
is(tok::less) &&
347 ParseObjCProtocolReferences(protocols, protocolLocs,
true,
true,
348 LAngleLoc, EndProtoLoc,
353 if (Tok.
isNot(tok::less))
354 Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
355 superClassId, superClassLoc);
357 Decl *ClsType = Actions.ActOnStartClassInterface(
358 getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
359 superClassLoc, typeArgs,
360 SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(),
361 protocols.size(), protocolLocs.data(), EndProtoLoc, attrs);
363 if (Tok.
is(tok::l_brace))
364 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
366 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
377 bool &addedToDeclSpec) {
389 }
else if (!addedToDeclSpec) {
394 addedToDeclSpec =
true;
426 assert(Tok.
is(tok::less) &&
"Not at the beginning of a type parameter list");
434 auto makeProtocolIdentsIntoTypeParameters = [&]() {
436 for (
const auto &pair : protocolIdents) {
437 DeclResult typeParam = Actions.actOnObjCTypeParam(
441 typeParams.push_back(typeParam.
get());
444 protocolIdents.clear();
445 mayBeProtocolList =
false;
448 bool invalid =
false;
455 if (Tok.
is(tok::kw___covariant) || Tok.
is(tok::kw___contravariant)) {
456 variance = Tok.
is(tok::kw___covariant)
463 if (mayBeProtocolList) {
466 makeProtocolIdentsIntoTypeParameters();
471 if (!Tok.
is(tok::identifier)) {
473 if (Tok.
is(tok::code_completion)) {
476 Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
483 Diag(Tok, diag::err_objc_expected_type_parameter);
497 if (mayBeProtocolList) {
500 makeProtocolIdentsIntoTypeParameters();
507 }
else if (mayBeProtocolList) {
510 protocolIdents.push_back(std::make_pair(paramName, paramLoc));
515 DeclResult typeParam = Actions.actOnObjCTypeParam(
516 getCurScope(), variance, varianceLoc, typeParams.size(), paramName,
517 paramLoc, colonLoc, boundType.
isUsable() ? boundType.
get() :
nullptr);
519 typeParams.push_back(typeParam.
get());
525 if (Tok.
is(tok::greater))
527 }
else if (ParseGreaterThanInTemplateList(rAngleLoc,
530 Diag(lAngleLoc, diag::note_matching) <<
"'<'";
531 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
532 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
533 tok::comma, tok::semi },
535 if (Tok.
is(tok::greater))
539 if (mayBeProtocolList) {
544 if (Tok.
isNot(tok::colon) && Tok.
isNot(tok::l_paren)) {
553 makeProtocolIdentsIntoTypeParameters();
568 return invalid ? nullptr : list;
577 ObjCTypeParamListScope Scope(Actions,
getCurScope());
578 return parseObjCTypeParamListOrProtocolRefs(Scope, lAngleLoc, protocolIdents,
605 if (Tok.
isOneOf(tok::minus, tok::plus)) {
606 if (
Decl *methodPrototype =
607 ParseObjCMethodPrototype(MethodImplKind,
false))
608 allMethods.push_back(methodPrototype);
611 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
614 if (Tok.
is(tok::semi))
619 if (Tok.
is(tok::l_paren)) {
620 Diag(Tok, diag::err_expected_minus_or_plus);
621 ParseObjCMethodDecl(Tok.getLocation(),
623 MethodImplKind,
false);
627 if (Tok.
is(tok::semi)) {
637 if (Tok.
is(tok::code_completion)) {
641 return cutOffParsing();
645 if (Tok.
isNot(tok::at)) {
649 if (Tok.
is(tok::r_brace))
651 ParsedAttributesWithRange attrs(AttrFactory);
652 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
658 if (Tok.
is(tok::code_completion)) {
659 Actions.CodeCompleteObjCAtDirective(
getCurScope());
660 return cutOffParsing();
665 if (DirectiveKind == tok::objc_end) {
667 AtEnd.
setEnd(Tok.getLocation());
669 }
else if (DirectiveKind == tok::objc_not_keyword) {
670 Diag(Tok, diag::err_objc_unknown_at);
678 switch (DirectiveKind) {
684 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
689 case tok::objc_implementation:
690 case tok::objc_interface:
691 Diag(AtLoc, diag::err_objc_missing_end)
694 << (
int) Actions.getObjCContainerKind();
698 case tok::objc_required:
699 case tok::objc_optional:
702 if (contextKey != tok::objc_protocol)
703 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
705 MethodImplKind = DirectiveKind;
708 case tok::objc_property:
710 Diag(AtLoc, diag::err_objc_properties_require_objc2);
715 if (Tok.
is(tok::l_paren)) {
716 LParenLoc = Tok.getLocation();
717 ParseObjCPropertyAttribute(OCDS);
720 bool addedToDeclSpec =
false;
722 if (FD.D.getIdentifier() ==
nullptr) {
723 Diag(AtLoc, diag::err_objc_property_requires_field_name)
724 << FD.D.getSourceRange();
727 if (FD.BitfieldSize) {
728 Diag(AtLoc, diag::err_objc_property_bitfield)
729 << FD.D.getSourceRange();
744 Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName);
748 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
751 PP.getIdentifierTable(), PP.getSelectorTable(),
752 FD.D.getIdentifier());
754 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
757 FD.complete(Property);
762 ParseStructDeclaration(DS, ObjCPropertyCallback);
764 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
771 if (Tok.
is(tok::code_completion)) {
772 Actions.CodeCompleteObjCAtDirective(
getCurScope());
773 return cutOffParsing();
777 Diag(Tok, diag::err_objc_missing_end)
780 << (
int) Actions.getObjCContainerKind();
782 AtEnd.
setEnd(Tok.getLocation());
787 Actions.ActOnAtEnd(
getCurScope(), AtEnd, allMethods, allTUVariables);
796 P.
Diag(nullabilityLoc, diag::warn_nullability_duplicate)
802 P.
Diag(nullabilityLoc, diag::err_nullability_conflicting)
833 void Parser::ParseObjCPropertyAttribute(
ObjCDeclSpec &DS) {
834 assert(Tok.getKind() == tok::l_paren);
839 if (Tok.
is(tok::code_completion)) {
840 Actions.CodeCompleteObjCPropertyFlags(
getCurScope(), DS);
841 return cutOffParsing();
853 if (II->
isStr(
"readonly"))
855 else if (II->
isStr(
"assign"))
857 else if (II->
isStr(
"unsafe_unretained"))
859 else if (II->
isStr(
"readwrite"))
861 else if (II->
isStr(
"retain"))
863 else if (II->
isStr(
"strong"))
865 else if (II->
isStr(
"copy"))
867 else if (II->
isStr(
"nonatomic"))
869 else if (II->
isStr(
"atomic"))
871 else if (II->
isStr(
"weak"))
873 else if (II->
isStr(
"getter") || II->
isStr(
"setter")) {
877 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
878 diag::err_objc_expected_equal_for_getter;
880 if (ExpectAndConsume(tok::equal, DiagID)) {
885 if (Tok.
is(tok::code_completion)) {
887 Actions.CodeCompleteObjCPropertySetter(
getCurScope());
889 Actions.CodeCompleteObjCPropertyGetter(
getCurScope());
890 return cutOffParsing();
897 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
907 if (ExpectAndConsume(tok::colon,
908 diag::err_expected_colon_after_setter_name)) {
916 }
else if (II->
isStr(
"nonnull")) {
923 }
else if (II->
isStr(
"nullable")) {
930 }
else if (II->
isStr(
"null_unspecified")) {
937 }
else if (II->
isStr(
"null_resettable")) {
947 }
else if (II->
isStr(
"class")) {
950 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
955 if (Tok.
isNot(tok::comma))
975 bool MethodDefinition) {
976 assert(Tok.
isOneOf(tok::minus, tok::plus) &&
"expected +/-");
980 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
997 switch (Tok.getKind()) {
1002 SelectorLoc = Tok.getLocation();
1010 case tok::exclaimequal:
1012 case tok::pipeequal:
1014 case tok::caretequal: {
1015 std::string ThisTok(PP.getSpelling(Tok));
1018 Tok.setKind(tok::identifier);
1025 case tok::identifier:
1035 case tok::kw_const_cast:
1036 case tok::kw_continue:
1037 case tok::kw_default:
1038 case tok::kw_delete:
1040 case tok::kw_double:
1041 case tok::kw_dynamic_cast:
1044 case tok::kw_explicit:
1045 case tok::kw_export:
1046 case tok::kw_extern:
1050 case tok::kw_friend:
1053 case tok::kw_inline:
1056 case tok::kw_mutable:
1057 case tok::kw_namespace:
1059 case tok::kw_operator:
1060 case tok::kw_private:
1061 case tok::kw_protected:
1062 case tok::kw_public:
1063 case tok::kw_register:
1064 case tok::kw_reinterpret_cast:
1065 case tok::kw_restrict:
1066 case tok::kw_return:
1068 case tok::kw_signed:
1069 case tok::kw_sizeof:
1070 case tok::kw_static:
1071 case tok::kw_static_cast:
1072 case tok::kw_struct:
1073 case tok::kw_switch:
1074 case tok::kw_template:
1079 case tok::kw_typedef:
1080 case tok::kw_typeid:
1081 case tok::kw_typename:
1082 case tok::kw_typeof:
1084 case tok::kw_unsigned:
1086 case tok::kw_virtual:
1088 case tok::kw_volatile:
1089 case tok::kw_wchar_t:
1092 case tok::kw__Complex:
1093 case tok::kw___alignof:
1094 case tok::kw___auto_type:
1103 bool Parser::isTokIdentifier_in()
const {
1108 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
1130 void Parser::ParseObjCTypeQualifierList(
ObjCDeclSpec &DS,
1136 if (Tok.
is(tok::code_completion)) {
1137 Actions.CodeCompleteObjCPassingType(
getCurScope(), DS,
1139 return cutOffParsing();
1142 if (Tok.
isNot(tok::identifier))
1146 for (
unsigned i = 0; i != objc_NumQuals; ++i) {
1147 if (II != ObjCTypeQuals[i] ||
1155 default: llvm_unreachable(
"Unknown decl qualifier");
1173 case objc_null_unspecified:
1198 for (
auto &AL : llvm::reverse(from)) {
1199 if (!AL.isUsedAsTypeAttr()) {
1230 assert((paramAttrs !=
nullptr) ==
1233 assert(Tok.
is(tok::l_paren) &&
"expected (");
1242 ParseObjCTypeQualifierList(DS, context);
1245 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1249 DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
1251 dsContext = DeclSpecContext::DSC_objc_method_result;
1252 ParseSpecifierQualifierList(declSpec,
AS_none, dsContext);
1254 ParseDeclarator(declarator);
1259 bool addedToDeclSpec =
false;
1277 if (Tok.
is(tok::r_paren))
1279 else if (Tok.getLocation() == TypeStartLoc) {
1281 Diag(Tok, diag::err_expected_type);
1322 bool MethodDefinition) {
1325 if (Tok.
is(tok::code_completion)) {
1326 Actions.CodeCompleteObjCMethodDecl(
getCurScope(), mType == tok::minus,
1335 if (Tok.
is(tok::l_paren))
1342 MaybeParseGNUAttributes(methodAttrs);
1343 MaybeParseCXX11Attributes(methodAttrs);
1345 if (Tok.
is(tok::code_completion)) {
1346 Actions.CodeCompleteObjCMethodDecl(
getCurScope(), mType == tok::minus,
1357 if (!SelIdent && Tok.
isNot(tok::colon)) {
1358 Diag(Tok, diag::err_expected_selector_for_method)
1366 if (Tok.
isNot(tok::colon)) {
1369 MaybeParseGNUAttributes(methodAttrs);
1370 MaybeParseCXX11Attributes(methodAttrs);
1372 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
1373 Decl *
Result = Actions.ActOnMethodDeclaration(
1374 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType,
1375 selLoc, Sel,
nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
1376 MethodImplKind,
false, MethodDefinition);
1393 if (ExpectAndConsume(tok::colon))
1396 ArgInfo.
Type =
nullptr;
1397 if (Tok.
is(tok::l_paren))
1405 MaybeParseGNUAttributes(paramAttrs);
1406 MaybeParseCXX11Attributes(paramAttrs);
1410 if (Tok.
is(tok::code_completion)) {
1411 KeyIdents.push_back(SelIdent);
1412 Actions.CodeCompleteObjCMethodDeclSelector(
getCurScope(),
1413 mType == tok::minus,
1415 ReturnType, KeyIdents);
1420 if (expectIdentifier())
1423 ArgInfo.
Name = Tok.getIdentifierInfo();
1424 ArgInfo.
NameLoc = Tok.getLocation();
1427 ArgInfos.push_back(ArgInfo);
1428 KeyIdents.push_back(SelIdent);
1429 KeyLocs.push_back(selLoc);
1435 if (Tok.
is(tok::code_completion)) {
1436 Actions.CodeCompleteObjCMethodDeclSelector(
getCurScope(),
1437 mType == tok::minus,
1439 ReturnType, KeyIdents);
1445 SelIdent = ParseObjCSelectorPiece(selLoc);
1446 if (!SelIdent && Tok.
isNot(tok::colon))
1451 Diag(ArgInfo.
NameLoc, diag::warn_missing_selector_name) << ArgInfo.
Name;
1452 Diag(ArgInfo.
NameLoc, diag::note_missing_selector_name) << ArgInfo.
Name;
1453 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.
Name;
1459 bool isVariadic =
false;
1460 bool cStyleParamWarned =
false;
1462 while (Tok.
is(tok::comma)) {
1464 if (Tok.
is(tok::ellipsis)) {
1469 if (!cStyleParamWarned) {
1470 Diag(Tok, diag::warn_cstyle_param);
1471 cStyleParamWarned =
true;
1474 ParseDeclarationSpecifiers(DS);
1477 ParseDeclarator(ParmDecl);
1489 MaybeParseGNUAttributes(methodAttrs);
1490 MaybeParseCXX11Attributes(methodAttrs);
1492 if (KeyIdents.size() == 0)
1495 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
1497 Decl *
Result = Actions.ActOnMethodDeclaration(
1498 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
1499 Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
1500 MethodImplKind, isVariadic, MethodDefinition);
1512 bool WarnOnDeclarations,
bool ForObjCContainer,
1514 bool consumeLastToken) {
1515 assert(Tok.
is(tok::less) &&
"expected <");
1522 if (Tok.
is(tok::code_completion)) {
1523 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
1528 if (expectIdentifier()) {
1532 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
1533 Tok.getLocation()));
1534 ProtocolLocs.push_back(Tok.getLocation());
1542 if (ParseGreaterThanInTemplateList(EndLoc, consumeLastToken,
1547 Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer,
1548 ProtocolIdents, Protocols);
1553 assert(Tok.
is(tok::less) &&
"Protocol qualifiers start with '<'");
1554 assert(
getLangOpts().ObjC1 &&
"Protocol qualifiers only exist in Objective-C");
1559 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
false,
false,
1560 lAngleLoc, rAngleLoc,
1562 TypeResult result = Actions.actOnObjCProtocolQualifierType(lAngleLoc,
1567 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1580 void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1589 bool consumeLastToken,
1590 bool warnOnIncompleteProtocols) {
1591 assert(Tok.
is(tok::less) &&
"Not at the start of type args or protocols");
1596 bool allSingleIdentifiers =
true;
1604 if (Tok.
is(tok::identifier) &&
1608 identifiers.push_back(Tok.getIdentifierInfo());
1613 if (Tok.
is(tok::code_completion)) {
1616 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1618 identifierLocs[i]));
1621 QualType BaseT = Actions.GetTypeFromParser(baseType);
1625 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
1631 allSingleIdentifiers =
false;
1637 if (allSingleIdentifiers) {
1640 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1644 Actions.actOnObjCTypeArgsOrProtocolQualifiers(
getCurScope(),
1656 warnOnIncompleteProtocols);
1666 bool invalid =
false;
1667 IdentifierInfo *foundProtocolId =
nullptr, *foundValidTypeId =
nullptr;
1672 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1674 = Actions.getTypeName(*identifiers[i], identifierLocs[i],
getCurScope());
1677 const char *prevSpec =
nullptr;
1680 typeArg, Actions.getASTContext().getPrintingPolicy());
1686 typeArgs.push_back(fullTypeArg.
get());
1687 if (!foundValidTypeId) {
1688 foundValidTypeId = identifiers[i];
1689 foundValidTypeSrcLoc = identifierLocs[i];
1693 unknownTypeArgs.push_back(identifiers[i]);
1694 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1698 if (!Actions.LookupProtocol(identifiers[i], identifierLocs[i])) {
1699 unknownTypeArgs.push_back(identifiers[i]);
1700 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1701 }
else if (!foundProtocolId) {
1702 foundProtocolId = identifiers[i];
1703 foundProtocolSrcLoc = identifierLocs[i];
1710 Token CurTypeTok = Tok;
1717 typeArg = Actions.ActOnPackExpansion(typeArg.
get(), ellipsisLoc);
1721 typeArgs.push_back(typeArg.
get());
1722 if (!foundValidTypeId) {
1732 if (foundProtocolId && foundValidTypeId)
1733 Actions.DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc,
1735 foundValidTypeSrcLoc);
1739 if (unknownTypeArgs.size())
1740 for (
unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1741 Actions.DiagnoseUnknownTypeName(unknownTypeArgs[i], unknownTypeArgsLoc[i],
1746 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1755 typeArgsLAngleLoc = lAngleLoc;
1756 typeArgsRAngleLoc = rAngleLoc;
1759 void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1768 bool consumeLastToken) {
1769 assert(Tok.
is(tok::less));
1772 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1788 if ((consumeLastToken && Tok.
is(tok::less)) ||
1789 (!consumeLastToken &&
NextToken().
is(tok::less))) {
1792 if (!consumeLastToken)
1795 if (!protocols.empty()) {
1797 if (!consumeLastToken)
1799 Diag(Tok, diag::err_objc_type_args_after_protocols)
1800 <<
SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1801 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1803 ParseObjCProtocolReferences(protocols, protocolLocs,
1806 protocolLAngleLoc, protocolRAngleLoc,
1812 TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1815 bool consumeLastToken,
1817 assert(Tok.
is(tok::less));
1827 parseObjCTypeArgsAndProtocolQualifiers(type, typeArgsLAngleLoc, typeArgs,
1828 typeArgsRAngleLoc, protocolLAngleLoc,
1829 protocols, protocolLocs,
1830 protocolRAngleLoc, consumeLastToken);
1836 if (consumeLastToken)
1837 endLoc = PrevTokLocation;
1839 endLoc = Tok.getLocation();
1841 return Actions.actOnObjCTypeArgsAndProtocolQualifiers(
1854 void Parser::HelperActionsForIvarDeclarations(
Decl *interfaceDecl,
SourceLocation atLoc,
1857 bool RBraceMissing) {
1861 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1863 Actions.ActOnObjCContainerFinishDefinition();
1866 Actions.ActOnFields(
getCurScope(), atLoc, interfaceDecl, AllIvarDecls,
1891 void Parser::ParseObjCClassInstanceVariables(
Decl *interfaceDecl,
1894 assert(Tok.
is(tok::l_brace) &&
"expected {");
1903 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
1907 if (Tok.
is(tok::semi)) {
1908 ConsumeExtraSemi(InstanceVariableList);
1914 if (Tok.
is(tok::code_completion)) {
1915 Actions.CodeCompleteObjCAtVisibility(
getCurScope());
1916 return cutOffParsing();
1919 switch (Tok.getObjCKeywordID()) {
1920 case tok::objc_private:
1921 case tok::objc_public:
1922 case tok::objc_protected:
1923 case tok::objc_package:
1924 visibility = Tok.getObjCKeywordID();
1929 Diag(Tok, diag::err_objc_unexpected_atend);
1930 Tok.setLocation(Tok.getLocation().getLocWithOffset(-1));
1931 Tok.setKind(tok::at);
1934 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1935 T, AllIvarDecls,
true);
1939 Diag(Tok, diag::err_objc_illegal_visibility_spec);
1944 if (Tok.
is(tok::code_completion)) {
1947 return cutOffParsing();
1951 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1953 FD.D.setObjCIvar(
true);
1954 Decl *Field = Actions.ActOnIvar(
1955 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
1956 FD.BitfieldSize, visibility);
1957 Actions.ActOnObjCContainerFinishDefinition();
1959 AllIvarDecls.push_back(Field);
1965 ParseStructDeclaration(DS, ObjCIvarCallback);
1967 if (Tok.
is(tok::semi)) {
1970 Diag(Tok, diag::err_expected_semi_decl_list);
1975 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1976 T, AllIvarDecls,
false);
1999 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2002 if (Tok.
is(tok::code_completion)) {
2003 Actions.CodeCompleteObjCProtocolDecl(
getCurScope());
2008 MaybeSkipAttributes(tok::objc_protocol);
2010 if (expectIdentifier())
2018 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs);
2021 CheckNestedObjCContexts(AtLoc);
2023 if (Tok.
is(tok::comma)) {
2025 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2030 if (expectIdentifier()) {
2035 Tok.getLocation()));
2038 if (Tok.
isNot(tok::comma))
2042 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@protocol"))
2045 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs);
2053 if (Tok.
is(tok::less) &&
2054 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
false,
true,
2055 LAngleLoc, EndProtoLoc,
2059 Decl *ProtoType = Actions.ActOnStartProtocolInterface(
2060 AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
2061 ProtocolLocs.data(), EndProtoLoc, attrs);
2063 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2064 return Actions.ConvertDeclToDeclGroup(ProtoType);
2078 Parser::ParseObjCAtImplementationDeclaration(
SourceLocation AtLoc) {
2080 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2081 CheckNestedObjCContexts(AtLoc);
2085 if (Tok.
is(tok::code_completion)) {
2086 Actions.CodeCompleteObjCImplementationDecl(
getCurScope());
2091 MaybeSkipAttributes(tok::objc_implementation);
2093 if (expectIdentifier())
2098 Decl *ObjCImpDecl =
nullptr;
2102 if (Tok.
is(tok::less)) {
2106 ObjCTypeParamListScope typeParamScope(Actions,
getCurScope());
2107 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
2108 protocolIdents, rAngleLoc)) {
2109 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2111 }
else if (lAngleLoc.
isValid()) {
2112 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2117 if (Tok.
is(tok::l_paren)) {
2123 if (Tok.
is(tok::code_completion)) {
2124 Actions.CodeCompleteObjCImplementationCategory(
getCurScope(), nameId, nameLoc);
2129 if (Tok.
is(tok::identifier)) {
2130 categoryId = Tok.getIdentifierInfo();
2133 Diag(Tok, diag::err_expected)
2137 if (Tok.
isNot(tok::r_paren)) {
2138 Diag(Tok, diag::err_expected) << tok::r_paren;
2142 rparenLoc = ConsumeParen();
2143 if (Tok.
is(tok::less)) {
2144 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2148 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2151 protocolLAngleLoc, protocolRAngleLoc,
2154 ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
2155 AtLoc, nameId, nameLoc, categoryId,
2164 if (expectIdentifier())
2166 superClassId = Tok.getIdentifierInfo();
2169 ObjCImpDecl = Actions.ActOnStartClassImplementation(
2170 AtLoc, nameId, nameLoc,
2171 superClassId, superClassLoc);
2173 if (Tok.
is(tok::l_brace))
2174 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2175 else if (Tok.
is(tok::less)) {
2176 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2181 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2184 protocolLAngleLoc, protocolRAngleLoc,
2188 assert(ObjCImpDecl);
2193 ObjCImplParsingDataRAII ObjCImplParsing(*
this, ObjCImpDecl);
2194 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2195 ParsedAttributesWithRange attrs(AttrFactory);
2196 MaybeParseCXX11Attributes(attrs);
2199 DeclsInGroup.append(DG.
begin(), DG.
end());
2204 return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup);
2208 Parser::ParseObjCAtEndDeclaration(
SourceRange atEnd) {
2210 "ParseObjCAtEndDeclaration(): Expected @end");
2212 if (CurParsedObjCImpl)
2213 CurParsedObjCImpl->finish(atEnd);
2216 Diag(atEnd.
getBegin(), diag::err_expected_objc_container);
2220 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2222 finish(
P.Tok.getLocation());
2223 if (
P.isEofOrEom()) {
2224 P.Diag(
P.Tok, diag::err_objc_missing_end)
2226 P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
2230 P.CurParsedObjCImpl =
nullptr;
2231 assert(LateParsedObjCMethods.empty());
2234 void Parser::ObjCImplParsingDataRAII::finish(
SourceRange AtEnd) {
2236 P.Actions.DefaultSynthesizeProperties(
P.getCurScope(), Dcl, AtEnd.
getBegin());
2237 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2238 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2241 P.Actions.ActOnAtEnd(
P.getCurScope(), AtEnd);
2244 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2245 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2249 for (LateParsedObjCMethodContainer::iterator
2250 I = LateParsedObjCMethods.begin(),
2251 E = LateParsedObjCMethods.end(); I != E; ++I)
2253 LateParsedObjCMethods.clear();
2263 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2265 if (expectIdentifier())
2269 if (expectIdentifier())
2273 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@compatibility_alias");
2274 return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
2291 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2295 if (Tok.
is(tok::code_completion)) {
2296 Actions.CodeCompleteObjCPropertyDefinition(
getCurScope());
2301 if (Tok.
isNot(tok::identifier)) {
2302 Diag(Tok, diag::err_synthesized_property_name);
2313 if (Tok.
is(tok::code_completion)) {
2314 Actions.CodeCompleteObjCPropertySynthesizeIvar(
getCurScope(), propertyId);
2319 if (expectIdentifier())
2321 propertyIvar = Tok.getIdentifierInfo();
2324 Actions.ActOnPropertyImplDecl(
2326 propertyId, propertyIvar, propertyIvarLoc,
2328 if (Tok.
isNot(tok::comma))
2332 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@synthesize");
2345 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2348 bool isClassProperty =
false;
2349 if (Tok.
is(tok::l_paren)) {
2354 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2358 if (II->
isStr(
"class")) {
2359 isClassProperty =
true;
2360 if (Tok.
isNot(tok::r_paren)) {
2361 Diag(Tok, diag::err_expected) << tok::r_paren;
2366 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2373 if (Tok.
is(tok::code_completion)) {
2374 Actions.CodeCompleteObjCPropertyDefinition(
getCurScope());
2379 if (expectIdentifier()) {
2386 Actions.ActOnPropertyImplDecl(
2392 if (Tok.
isNot(tok::comma))
2396 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@dynamic");
2406 if (Tok.
isNot(tok::semi)) {
2414 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@throw");
2415 return Actions.ActOnObjCAtThrowStmt(atLoc, Res.
get(),
getCurScope());
2424 if (Tok.
isNot(tok::l_paren)) {
2425 Diag(Tok, diag::err_expected_lparen_after) <<
"@synchronized";
2433 if (Tok.
is(tok::r_paren)) {
2437 Diag(Tok, diag::err_expected) << tok::r_paren;
2444 if (Tok.
isNot(tok::l_brace)) {
2446 Diag(Tok, diag::err_expected) << tok::l_brace;
2452 operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.
get());
2456 StmtResult body(ParseCompoundStatementBody());
2464 if (body.isInvalid())
2465 body = Actions.ActOnNullStmt(Tok.getLocation());
2467 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.
get(), body.get());
2482 bool catch_or_finally_seen =
false;
2485 if (Tok.
isNot(tok::l_brace)) {
2486 Diag(Tok, diag::err_expected) << tok::l_brace;
2489 StmtVector CatchStmts;
2492 StmtResult TryBody(ParseCompoundStatementBody());
2494 if (TryBody.isInvalid())
2495 TryBody = Actions.ActOnNullStmt(Tok.getLocation());
2497 while (Tok.
is(tok::at)) {
2501 Token AfterAt = GetLookAheadToken(1);
2508 Decl *FirstPart =
nullptr;
2510 if (Tok.
is(tok::l_paren)) {
2515 if (Tok.
isNot(tok::ellipsis)) {
2517 ParseDeclarationSpecifiers(DS);
2519 ParseDeclarator(ParmDecl);
2523 FirstPart = Actions.ActOnObjCExceptionDecl(
getCurScope(), ParmDecl);
2529 if (Tok.
is(tok::r_paren))
2530 RParenLoc = ConsumeParen();
2535 if (Tok.
is(tok::l_brace))
2536 CatchBody = ParseCompoundStatementBody();
2538 Diag(Tok, diag::err_expected) << tok::l_brace;
2539 if (CatchBody.isInvalid())
2540 CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
2542 StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
2546 if (!Catch.isInvalid())
2547 CatchStmts.push_back(Catch.get());
2550 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2554 catch_or_finally_seen =
true;
2556 assert(Tok.
isObjCAtKeyword(tok::objc_finally) &&
"Lookahead confused?");
2558 ParseScope FinallyScope(
this,
2561 bool ShouldCapture =
2564 Actions.ActOnCapturedRegionStart(Tok.getLocation(),
getCurScope(),
2568 if (Tok.
is(tok::l_brace))
2569 FinallyBody = ParseCompoundStatementBody();
2571 Diag(Tok, diag::err_expected) << tok::l_brace;
2573 if (FinallyBody.isInvalid()) {
2574 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
2576 Actions.ActOnCapturedRegionError();
2577 }
else if (ShouldCapture) {
2578 FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get());
2581 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
2583 catch_or_finally_seen =
true;
2587 if (!catch_or_finally_seen) {
2588 Diag(atLoc, diag::err_missing_catch_finally);
2592 return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(),
2603 if (Tok.
isNot(tok::l_brace)) {
2604 Diag(Tok, diag::err_expected) << tok::l_brace;
2611 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2614 if (AutoreleasePoolBody.isInvalid())
2615 AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
2616 return Actions.ActOnObjCAutoreleasePoolStmt(atLoc,
2617 AutoreleasePoolBody.get());
2622 void Parser::StashAwayMethodOrFunctionBodyTokens(
Decl *MDecl) {
2623 if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
2624 trySkippingFunctionBody()) {
2625 Actions.ActOnSkippedFunctionBody(MDecl);
2629 LexedMethod* LM =
new LexedMethod(
this, MDecl);
2630 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2633 Toks.push_back(Tok);
2634 if (Tok.
is(tok::kw_try)) {
2636 if (Tok.
is(tok::colon)) {
2637 Toks.push_back(Tok);
2639 while (Tok.
isNot(tok::l_brace)) {
2640 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2641 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2644 Toks.push_back(Tok);
2646 else if (Tok.
is(tok::colon)) {
2649 while (Tok.
isNot(tok::l_brace)) {
2650 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2651 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2653 Toks.push_back(Tok);
2657 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2658 while (Tok.
is(tok::kw_catch)) {
2659 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
2660 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2666 Decl *Parser::ParseObjCMethodDefinition() {
2667 Decl *MDecl = ParseObjCMethodPrototype();
2670 "parsing Objective-C method");
2673 if (Tok.
is(tok::semi)) {
2674 if (CurParsedObjCImpl) {
2675 Diag(Tok, diag::warn_semicolon_before_method_body)
2682 if (Tok.
isNot(tok::l_brace)) {
2683 Diag(Tok, diag::err_expected_method_body);
2689 if (Tok.
isNot(tok::l_brace))
2700 Actions.AddAnyMethodToGlobalPool(MDecl);
2701 assert (CurParsedObjCImpl
2702 &&
"ParseObjCMethodDefinition - Method out of @implementation");
2704 StashAwayMethodOrFunctionBodyTokens(MDecl);
2709 if (Tok.
is(tok::code_completion)) {
2710 Actions.CodeCompleteObjCAtStatement(
getCurScope());
2716 return ParseObjCTryStmt(AtLoc);
2719 return ParseObjCThrowStmt(AtLoc);
2722 return ParseObjCSynchronizedStmt(AtLoc);
2725 return ParseObjCAutoreleasePoolStmt(AtLoc);
2730 return Actions.ActOnNullStmt(Tok.getLocation());
2733 ExprStatementTokLoc = AtLoc;
2734 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2744 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2745 return Actions.ActOnExprStmt(Res);
2749 switch (Tok.getKind()) {
2750 case tok::code_completion:
2751 Actions.CodeCompleteObjCAtExpression(
getCurScope());
2760 if (!Tok.
is(tok::numeric_constant)) {
2761 const char *Symbol =
nullptr;
2763 case tok::minus: Symbol =
"-";
break;
2764 case tok::plus: Symbol =
"+";
break;
2765 default: llvm_unreachable(
"missing unary operator case");
2767 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2772 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2773 if (Lit.isInvalid()) {
2778 Lit = Actions.ActOnUnaryOp(
getCurScope(), OpLoc, Kind, Lit.get());
2779 if (Lit.isInvalid())
2782 return ParsePostfixExpressionSuffix(
2783 Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()));
2786 case tok::string_literal:
2787 case tok::wide_string_literal:
2788 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2790 case tok::char_constant:
2791 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2793 case tok::numeric_constant:
2794 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2797 case tok::kw___objc_yes:
2798 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
true));
2800 case tok::kw___objc_no:
2801 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
false));
2805 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2809 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2813 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2816 if (Tok.getIdentifierInfo() ==
nullptr)
2819 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
2820 case tok::objc_encode:
2821 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2822 case tok::objc_protocol:
2823 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2824 case tok::objc_selector:
2825 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2826 case tok::objc_available:
2827 return ParseAvailabilityCheckExpr(AtLoc);
2829 const char *str =
nullptr;
2833 if (GetLookAheadToken(1).is(tok::l_brace) &&
2834 ExprStatementTokLoc == AtLoc) {
2835 char ch = Tok.getIdentifierInfo()->getNameStart()[0];
2838 : (ch ==
'f' ?
"finally" 2839 : (ch ==
'a' ?
"autoreleasepool" :
nullptr));
2875 bool Parser::ParseObjCXXMessageReceiver(
bool &IsExpr,
void *&TypeOrExpr) {
2878 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2879 tok::annot_cxxscope))
2882 if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
2893 TypeOrExpr = Receiver.
get();
2902 ParseCXXSimpleTypeSpecifier(DS);
2904 if (Tok.
is(tok::l_paren)) {
2917 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2919 Receiver = ParsePostfixExpressionSuffix(Receiver.
get());
2921 Receiver = ParseRHSOfBinaryExpression(Receiver.
get(),
prec::Comma);
2926 TypeOrExpr = Receiver.
get();
2939 TypeOrExpr = Type.
get().getAsOpaquePtr();
2948 bool Parser::isSimpleObjCMessageExpression() {
2950 "Incorrect start for isSimpleObjCMessageExpression");
2951 return GetLookAheadToken(1).is(tok::identifier) &&
2952 GetLookAheadToken(2).is(tok::identifier);
2955 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2957 InMessageExpression)
2962 if (Tok.
is(tok::annot_typename))
2964 else if (Tok.
is(tok::identifier))
2965 Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(),
2970 if (!Type.
get().isNull() && Type.
get()->isObjCObjectOrInterfaceType()) {
2971 const Token &AfterNext = GetLookAheadToken(2);
2972 if (AfterNext.
isOneOf(tok::colon, tok::r_square)) {
2973 if (Tok.
is(tok::identifier))
2976 return Tok.
is(tok::annot_typename);
2992 ExprResult Parser::ParseObjCMessageExpression() {
2993 assert(Tok.
is(tok::l_square) &&
"'[' expected");
2996 if (Tok.
is(tok::code_completion)) {
2997 Actions.CodeCompleteObjCMessageReceiver(
getCurScope());
3011 if (Tok.
is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
3013 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3018 void *TypeOrExpr =
nullptr;
3019 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
3025 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3026 static_cast<Expr *>(TypeOrExpr));
3028 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3033 if (Tok.
is(tok::identifier)) {
3037 switch (Actions.getObjCMessageKind(
getCurScope(), Name, NameLoc,
3038 Name == Ident_super,
3042 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3046 if (!ReceiverType) {
3054 if (Tok.
is(tok::less)) {
3057 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3065 ReceiverType = NewReceiverType.
get();
3068 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3069 ReceiverType,
nullptr);
3084 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3130 Expr *ReceiverExpr) {
3133 if (Tok.
is(tok::code_completion)) {
3137 else if (ReceiverType)
3138 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
None,
3141 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3153 ExprVector KeyExprs;
3155 if (Tok.
is(tok::colon)) {
3158 KeyIdents.push_back(selIdent);
3159 KeyLocs.push_back(Loc);
3161 if (ExpectAndConsume(tok::colon)) {
3171 if (Tok.
is(tok::code_completion)) {
3173 Actions.CodeCompleteObjCSuperMessage(
getCurScope(), SuperLoc,
3176 else if (ReceiverType)
3177 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
3181 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3191 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3192 Expr = ParseBraceInitializer();
3206 KeyExprs.push_back(Res.
get());
3209 if (Tok.
is(tok::code_completion)) {
3211 Actions.CodeCompleteObjCSuperMessage(
getCurScope(), SuperLoc,
3214 else if (ReceiverType)
3215 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
3219 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3227 selIdent = ParseObjCSelectorPiece(Loc);
3228 if (!selIdent && Tok.
isNot(tok::colon))
3233 while (Tok.
is(tok::comma)) {
3237 if (Tok.
is(tok::colon))
3238 Res = Actions.CorrectDelayedTyposInExpr(Res);
3240 if (Tok.
is(tok::colon)) {
3241 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3252 KeyExprs.push_back(Res.
get());
3254 }
else if (!selIdent) {
3255 Diag(Tok, diag::err_expected) << tok::identifier;
3264 if (Tok.
isNot(tok::r_square)) {
3265 Diag(Tok, diag::err_expected)
3266 << (Tok.
is(tok::identifier) ? tok::colon : tok::r_square);
3276 unsigned nKeys = KeyIdents.size();
3278 KeyIdents.push_back(selIdent);
3279 KeyLocs.push_back(Loc);
3281 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
3284 return Actions.ActOnSuperMessage(
getCurScope(), SuperLoc, Sel,
3285 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3286 else if (ReceiverType)
3287 return Actions.ActOnClassMessage(
getCurScope(), ReceiverType, Sel,
3288 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3289 return Actions.ActOnInstanceMessage(
getCurScope(), ReceiverExpr, Sel,
3290 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3294 ExprResult Res(ParseStringLiteralExpression());
3301 ExprVector AtStrings;
3302 AtLocs.push_back(AtLoc);
3303 AtStrings.push_back(Res.
get());
3305 while (Tok.
is(tok::at)) {
3309 if (!isTokenStringLiteral())
3312 ExprResult Lit(ParseStringLiteralExpression());
3316 AtStrings.push_back(Lit.
get());
3319 return Actions.ParseObjCStringLiteral(AtLocs.data(), AtStrings);
3330 return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
3337 ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
3338 if (Lit.isInvalid()) {
3342 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3351 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
3352 if (Lit.isInvalid()) {
3356 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3364 if (Tok.
isNot(tok::l_paren))
3365 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@");
3379 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.
get());
3380 return Actions.BuildObjCBoxedExpr(
SourceRange(AtLoc, RPLoc),
3385 ExprVector ElementExprs;
3388 bool HasInvalidEltExpr =
false;
3389 while (Tok.
isNot(tok::r_square)) {
3400 Res = Actions.CorrectDelayedTyposInExpr(Res.
get());
3402 HasInvalidEltExpr =
true;
3405 if (Tok.
is(tok::ellipsis))
3408 HasInvalidEltExpr =
true;
3410 ElementExprs.push_back(Res.
get());
3412 if (Tok.
is(tok::comma))
3414 else if (Tok.
isNot(tok::r_square))
3415 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_square
3420 if (HasInvalidEltExpr)
3424 return Actions.BuildObjCArrayLiteral(
SourceRange(AtLoc, EndLoc), Args);
3430 bool HasInvalidEltExpr =
false;
3431 while (Tok.
isNot(tok::r_brace)) {
3446 if (ExpectAndConsume(tok::colon)) {
3461 KeyExpr = Actions.CorrectDelayedTyposInExpr(KeyExpr.
get());
3462 ValueExpr = Actions.CorrectDelayedTyposInExpr(ValueExpr.
get());
3464 HasInvalidEltExpr =
true;
3476 KeyExpr.
get(), ValueExpr.
get(), EllipsisLoc,
None 3478 Elements.push_back(Element);
3481 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_brace
3486 if (HasInvalidEltExpr)
3490 return Actions.BuildObjCDictionaryLiteral(
SourceRange(AtLoc, EndLoc),
3498 assert(Tok.
isObjCAtKeyword(tok::objc_encode) &&
"Not an @encode expression!");
3502 if (Tok.
isNot(tok::l_paren))
3503 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@encode");
3515 return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.
getOpenLocation(),
3525 if (Tok.
isNot(tok::l_paren))
3526 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@protocol");
3531 if (expectIdentifier())
3539 return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
3549 if (Tok.
isNot(tok::l_paren))
3550 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@selector");
3557 bool HasOptionalParen = Tok.
is(tok::l_paren);
3558 if (HasOptionalParen)
3561 if (Tok.
is(tok::code_completion)) {
3562 Actions.CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3569 Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3570 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3572 KeyIdents.push_back(SelIdent);
3574 unsigned nColons = 0;
3575 if (Tok.
isNot(tok::r_paren)) {
3579 KeyIdents.push_back(
nullptr);
3580 }
else if (ExpectAndConsume(tok::colon))
3584 if (Tok.
is(tok::r_paren))
3587 if (Tok.
is(tok::code_completion)) {
3588 Actions.CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3595 SelIdent = ParseObjCSelectorPiece(Loc);
3596 KeyIdents.push_back(SelIdent);
3597 if (!SelIdent && Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3601 if (HasOptionalParen && Tok.
is(tok::r_paren))
3604 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
3605 return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
3611 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM,
bool parseMethod) {
3613 Decl *MCDecl = LM.D;
3614 bool skip = MCDecl &&
3615 ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
3616 (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
3623 assert(!LM.Toks.empty() &&
"ParseLexedObjCMethodDef - Empty body!");
3629 Eof.setEofData(MCDecl);
3630 Eof.setLocation(OrigLoc);
3631 LM.Toks.push_back(Eof);
3634 LM.Toks.push_back(Tok);
3635 PP.EnterTokenStream(LM.Toks,
true);
3640 assert(Tok.
isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3641 "Inline objective-c method not starting with '{' or 'try' or ':'");
3650 Actions.ActOnStartOfObjCMethodDef(
getCurScope(), MCDecl);
3652 Actions.ActOnStartOfFunctionDef(
getCurScope(), MCDecl);
3653 if (Tok.
is(tok::kw_try))
3654 ParseFunctionTryBlock(MCDecl, BodyScope);
3656 if (Tok.
is(tok::colon))
3657 ParseConstructorInitializer(MCDecl);
3659 Actions.ActOnDefaultCtorInitializers(MCDecl);
3660 ParseFunctionStatementBody(MCDecl, BodyScope);
3663 if (Tok.getLocation() != OrigLoc) {
3669 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
AttributePool & getAttributePool() const
Defines the clang::ASTContext interface.
IdentifierInfo * getNullabilityKeyword(NullabilityKind nullability)
Retrieve the underscored keyword (_Nonnull, _Nullable) that corresponds to the given nullability kind...
Smart pointer class that efficiently represents Objective-C method names.
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
A (possibly-)qualified type.
This is a scope that corresponds to the parameters within a function prototype.
ObjCDeclQualifier getObjCDeclQualifier() const
Class to handle popping type parameters when leaving the scope.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
NullabilityKind
Describes the nullability of a particular type.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
void setPropertyAttributes(ObjCPropertyAttributeKind PRVal)
Decl - This represents one declaration (or definition), e.g.
RAII object used to inform the actions that we're currently parsing a declaration.
Captures information about "declaration specifiers" specific to Objective-C.
The base class of the type hierarchy.
SourceLocation getCloseLocation() const
This indicates that the scope corresponds to a function, which means that labels are set here...
The parameter is covariant, e.g., X<T> is a subtype of X<U> when the type parameter is covariant and ...
Wrapper for void* pointer.
Parser - This implements a parser for the C family of languages.
const ParsedAttributes & getAttributes() const
~ObjCTypeParamListScope()
void setObjCQualifiers(ObjCDeclSpec *quals)
ActionResult< Stmt * > StmtResult
Information about one declarator, including the parsed type information and the identifier.
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body...
void setBegin(SourceLocation b)
Code completion occurs within an Objective-C implementation or category implementation.
friend class ObjCDeclContextSwitch
const IdentifierInfo * getSetterName() const
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed...
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
bool TryConsumeToken(tok::TokenKind Expected)
The message is a class message, and the identifier is a type name.
One of these records is kept for each identifier that is lexed.
An element in an Objective-C dictionary literal.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
The parameter is contravariant, e.g., X<T> is a subtype of X<U> when the type parameter is covariant ...
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
Token - This structure provides full information about a lexed token.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
Code completion occurs where only a type is permitted.
bool isInvalidType() const
Values of this type can be null.
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
ParsedAttributesView ArgAttrs
ArgAttrs - Attribute list for this argument.
static ParsedType getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
Whether values of this type can be null is (explicitly) unspecified.
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
Values of this type can never be null.
Scope - A scope is a transient data structure that is used while parsing the program.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type...
IdentifierInfo * getIdentifier() const
DeclSpec & getMutableDeclSpec()
getMutableDeclSpec - Return a non-const version of the DeclSpec.
Sema - This implements semantic analysis and AST building for C.
bool acceptsObjCTypeParams() const
Determines if this is an ObjC interface type that may accept type parameters.
void setSetterName(IdentifierInfo *name, SourceLocation loc)
const ParsedAttributesView & getAttrs() const
If there are attributes applied to this declaratorchunk, return them.
Expr - This represents one expression.
The message is an instance message.
This file defines the classes used to store parsed information about declaration-specifiers and decla...
ObjCTypeParamListScope(Sema &Actions, Scope *S)
Code completion occurs within an Objective-C interface, protocol, or category.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
This is a compound statement scope.
A class for parsing a field declarator.
static void diagnoseRedundantPropertyNullability(Parser &P, ObjCDeclSpec &DS, NullabilityKind nullability, SourceLocation nullabilityLoc)
Diagnose redundant or conflicting nullability information.
SourceLocation getOpenLocation() const
The result type of a method or function.
Code completion occurs within the list of instance variables in an Objective-C interface, protocol, category, or implementation.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
ObjCTypeParamVariance
Describes the variance of a given generic parameter.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
RAII object that makes '>' behave either as an operator or as the closing angle bracket for a templat...
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
const LangOptions & getLangOpts() const
This is a scope that corresponds to the parameters within a function prototype for a function declara...
NullabilityKind getNullability() const
A class for parsing a DeclSpec.
SourceLocation getLocStart() const LLVM_READONLY
void addAtStart(ParsedAttr *newAttr)
ObjCDeclQualifier
ObjCDeclQualifier - Qualifier used on types in method declarations.
void CodeCompleteObjCAtDirective(Scope *S)
Stop skipping at semicolon.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
bool TryAnnotateTypeOrScopeToken()
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
std::pair< NullabilityKind, bool > DiagNullabilityKind
A nullability kind paired with a bit indicating whether it used a context-sensitive keyword...
This is a scope that corresponds to the Objective-C @catch statement.
IdentifierInfo * getIdentifierInfo() const
ParsedAttr - Represents a syntactic attribute.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
ObjCPropertyAttributeKind getPropertyAttributes() const
The message is sent to 'super'.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
void remove(ParsedAttr *ToBeRemoved)
Scope * getCurScope() const
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList)
The scope of a struct/union/class definition.
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
std::pair< IdentifierInfo *, SourceLocation > IdentifierLocPair
A simple pair of identifier info and location.
bool isValid() const
Return true if this is a valid SourceLocation object.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
void takeAllFrom(AttributePool &pool)
Take the given pool's allocations and add them to this pool.
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
SkipUntilFlags
Control flags for SkipUntil functions.
void setObjCDeclQualifier(ObjCDeclQualifier DQVal)
const TargetInfo & getTargetInfo() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getNullabilityLoc() const
void setNullability(SourceLocation loc, NullabilityKind kind)
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
This is a scope that can contain a declaration.
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getIdentifierLoc() const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Context-sensitive version of a keyword attribute.
Captures information about "declaration specifiers".
void setEnd(SourceLocation e)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
AttributePool & getPool() const
const IdentifierInfo * getGetterName() const
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed...
static void addContextSensitiveTypeNullability(Parser &P, Declarator &D, NullabilityKind nullability, SourceLocation nullabilityLoc, bool &addedToDeclSpec)
Add an attribute for a context-sensitive type nullability to the given declarator.
A trivial tuple used to represent a source range.
static void takeDeclAttributes(ParsedAttributesView &attrs, ParsedAttributesView &from)
Take all the decl attributes out of the given list and add them to the given attribute set...
void setGetterName(IdentifierInfo *name, SourceLocation loc)
void enter(ObjCTypeParamList *P)
static OpaquePtr getFromOpaquePtr(void *P)
AttributePool & getAttributePool() const
SourceLocation getBegin() const
ParsedAttributes - A collection of parsed attributes.
SourceLocation ColonLoc
Location of ':'.
This scope corresponds to an Objective-C method body.
The parameter is invariant: must match exactly.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeNameContext, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
ParsedAttributes & getAttributes()
void startToken()
Reset all flags to cleared.
Stop skipping at specified token, but don't skip the token itself.