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);
51 if (Tok.
is(tok::code_completion)) {
57 Decl *SingleDecl =
nullptr;
60 return ParseObjCAtClassDeclaration(AtLoc);
61 case tok::objc_interface:
62 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, Attrs);
64 case tok::objc_protocol:
65 return ParseObjCAtProtocolDeclaration(AtLoc, Attrs);
66 case tok::objc_implementation:
67 return ParseObjCAtImplementationDeclaration(AtLoc, Attrs);
69 return ParseObjCAtEndDeclaration(AtLoc);
70 case tok::objc_compatibility_alias:
71 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
73 case tok::objc_synthesize:
74 SingleDecl = ParseObjCPropertySynthesize(AtLoc);
76 case tok::objc_dynamic:
77 SingleDecl = ParseObjCPropertyDynamic(AtLoc);
79 case tok::objc_import:
82 SingleDecl = ParseModuleImport(AtLoc, IS);
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()) {
149 if (Tok.
is(tok::less))
150 TypeParams = parseObjCTypeParamList();
151 ClassTypeParams.push_back(TypeParams);
157 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@class"))
173 if (CurParsedObjCImpl) {
174 CurParsedObjCImpl->finish(AtLoc);
178 Diag(AtLoc, diag::err_objc_missing_end)
216 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
217 CheckNestedObjCContexts(AtLoc);
221 if (Tok.
is(tok::code_completion)) {
227 MaybeSkipAttributes(tok::objc_interface);
229 if (expectIdentifier())
242 ObjCTypeParamListScope typeParamScope(Actions,
getCurScope());
243 if (Tok.
is(tok::less))
244 typeParameterList = parseObjCTypeParamListOrProtocolRefs(
245 typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
247 if (Tok.
is(tok::l_paren) &&
248 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
255 if (Tok.
is(tok::code_completion)) {
262 if (Tok.
is(tok::identifier)) {
267 Diag(Tok, diag::err_expected)
273 if (T.getCloseLocation().isInvalid())
277 assert(LAngleLoc.
isInvalid() &&
"Cannot have already parsed protocols");
280 if (Tok.
is(tok::less) &&
281 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
true,
true,
282 LAngleLoc, EndProtoLoc,
287 AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
288 ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
291 if (Tok.
is(tok::l_brace))
292 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
294 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
306 if (Tok.
is(tok::colon)) {
310 if (Tok.
is(tok::code_completion)) {
316 if (expectIdentifier())
322 if (Tok.
is(tok::less)) {
323 parseObjCTypeArgsOrProtocolQualifiers(
324 nullptr, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, LAngleLoc,
325 protocols, protocolLocs, EndProtoLoc,
335 if (!ProtocolIdents.empty()) {
338 for (
const auto &pair : ProtocolIdents) {
339 protocolLocs.push_back(pair.second);
343 ProtocolIdents, protocols);
345 }
else if (protocols.empty() && Tok.
is(tok::less) &&
346 ParseObjCProtocolReferences(protocols, protocolLocs,
true,
true,
347 LAngleLoc, EndProtoLoc,
352 if (Tok.
isNot(tok::less))
354 superClassId, superClassLoc);
357 getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
358 superClassLoc, typeArgs,
359 SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(),
360 protocols.size(), protocolLocs.data(), EndProtoLoc, attrs);
362 if (Tok.
is(tok::l_brace))
363 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
365 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
376 bool &addedToDeclSpec) {
379 return Pool.create(
P.getNullabilityKeyword(nullability),
388 }
else if (!addedToDeclSpec) {
393 addedToDeclSpec =
true;
425 assert(Tok.
is(tok::less) &&
"Not at the beginning of a type parameter list");
433 auto makeProtocolIdentsIntoTypeParameters = [&]() {
435 for (
const auto &pair : protocolIdents) {
440 typeParams.push_back(typeParam.
get());
443 protocolIdents.clear();
444 mayBeProtocolList =
false;
447 bool invalid =
false;
454 if (Tok.
is(tok::kw___covariant) || Tok.
is(tok::kw___contravariant)) {
455 variance = Tok.
is(tok::kw___covariant)
462 if (mayBeProtocolList) {
465 makeProtocolIdentsIntoTypeParameters();
470 if (!Tok.
is(tok::identifier)) {
472 if (Tok.
is(tok::code_completion)) {
482 Diag(Tok, diag::err_objc_expected_type_parameter);
496 if (mayBeProtocolList) {
499 makeProtocolIdentsIntoTypeParameters();
506 }
else if (mayBeProtocolList) {
509 protocolIdents.push_back(std::make_pair(paramName, paramLoc));
515 getCurScope(), variance, varianceLoc, typeParams.size(), paramName,
516 paramLoc, colonLoc, boundType.
isUsable() ? boundType.
get() :
nullptr);
518 typeParams.push_back(typeParam.
get());
524 if (Tok.
is(tok::greater))
526 }
else if (ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc,
529 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
530 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
531 tok::comma, tok::semi },
533 if (Tok.
is(tok::greater))
537 if (mayBeProtocolList) {
542 if (Tok.
isNot(tok::colon) && Tok.
isNot(tok::l_paren)) {
551 makeProtocolIdentsIntoTypeParameters();
566 return invalid ? nullptr : list;
576 return parseObjCTypeParamListOrProtocolRefs(
Scope, lAngleLoc, protocolIdents,
603 if (Tok.
isOneOf(tok::minus, tok::plus)) {
604 if (
Decl *methodPrototype =
605 ParseObjCMethodPrototype(MethodImplKind,
false))
606 allMethods.push_back(methodPrototype);
609 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
612 if (Tok.
is(tok::semi))
617 if (Tok.
is(tok::l_paren)) {
618 Diag(Tok, diag::err_expected_minus_or_plus);
621 MethodImplKind,
false);
625 if (Tok.
is(tok::semi)) {
637 if (Tok.
is(tok::code_completion)) {
646 if (Tok.
isNot(tok::at)) {
650 if (Tok.
is(tok::r_brace))
658 if (Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
661 allTUVariables.push_back(ParseDeclaration(
666 allTUVariables.push_back(
667 ParseDeclarationOrFunctionDefinition(EmptyAttrs));
673 if (Tok.
is(tok::code_completion)) {
686 Diag(Tok, diag::err_objc_unknown_at);
700 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
705 case tok::objc_implementation:
706 case tok::objc_interface:
707 Diag(AtLoc, diag::err_objc_missing_end)
714 case tok::objc_required:
715 case tok::objc_optional:
717 if (contextKey != tok::objc_protocol)
718 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
723 case tok::objc_property:
727 if (Tok.
is(tok::l_paren)) {
729 ParseObjCPropertyAttribute(OCDS);
732 bool addedToDeclSpec =
false;
734 if (FD.D.getIdentifier() ==
nullptr) {
735 Diag(AtLoc, diag::err_objc_property_requires_field_name)
736 << FD.D.getSourceRange();
739 if (FD.BitfieldSize) {
740 Diag(AtLoc, diag::err_objc_property_bitfield)
741 << FD.D.getSourceRange();
765 FD.D.getIdentifier());
767 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
770 FD.complete(Property);
775 ParseStructDeclaration(DS, ObjCPropertyCallback);
777 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
784 if (Tok.
is(tok::code_completion)) {
791 Diag(Tok, diag::err_objc_missing_end)
810 P.Diag(nullabilityLoc, diag::warn_nullability_duplicate)
816 P.Diag(nullabilityLoc, diag::err_nullability_conflicting)
848 void Parser::ParseObjCPropertyAttribute(
ObjCDeclSpec &DS) {
849 assert(Tok.
getKind() == tok::l_paren);
854 if (Tok.
is(tok::code_completion)) {
869 if (II->
isStr(
"readonly"))
871 else if (II->
isStr(
"assign"))
873 else if (II->
isStr(
"unsafe_unretained"))
875 else if (II->
isStr(
"readwrite"))
877 else if (II->
isStr(
"retain"))
879 else if (II->
isStr(
"strong"))
881 else if (II->
isStr(
"copy"))
883 else if (II->
isStr(
"nonatomic"))
885 else if (II->
isStr(
"atomic"))
887 else if (II->
isStr(
"weak"))
889 else if (II->
isStr(
"getter") || II->
isStr(
"setter")) {
893 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
894 diag::err_objc_expected_equal_for_getter;
896 if (ExpectAndConsume(tok::equal, DiagID)) {
901 if (Tok.
is(tok::code_completion)) {
914 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
924 if (ExpectAndConsume(tok::colon,
925 diag::err_expected_colon_after_setter_name)) {
933 }
else if (II->
isStr(
"nonnull")) {
940 }
else if (II->
isStr(
"nullable")) {
947 }
else if (II->
isStr(
"null_unspecified")) {
954 }
else if (II->
isStr(
"null_resettable")) {
964 }
else if (II->
isStr(
"class")) {
966 }
else if (II->
isStr(
"direct")) {
969 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
974 if (Tok.
isNot(tok::comma))
994 bool MethodDefinition) {
995 assert(Tok.
isOneOf(tok::minus, tok::plus) &&
"expected +/-");
999 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
1029 case tok::exclaimequal:
1031 case tok::pipeequal:
1033 case tok::caretequal: {
1044 case tok::identifier:
1054 case tok::kw_const_cast:
1055 case tok::kw_continue:
1056 case tok::kw_default:
1057 case tok::kw_delete:
1059 case tok::kw_double:
1060 case tok::kw_dynamic_cast:
1063 case tok::kw_explicit:
1064 case tok::kw_export:
1065 case tok::kw_extern:
1069 case tok::kw_friend:
1072 case tok::kw_inline:
1075 case tok::kw_mutable:
1076 case tok::kw_namespace:
1078 case tok::kw_operator:
1079 case tok::kw_private:
1080 case tok::kw_protected:
1081 case tok::kw_public:
1082 case tok::kw_register:
1083 case tok::kw_reinterpret_cast:
1084 case tok::kw_restrict:
1085 case tok::kw_return:
1087 case tok::kw_signed:
1088 case tok::kw_sizeof:
1089 case tok::kw_static:
1090 case tok::kw_static_cast:
1091 case tok::kw_struct:
1092 case tok::kw_switch:
1093 case tok::kw_template:
1098 case tok::kw_typedef:
1099 case tok::kw_typeid:
1100 case tok::kw_typename:
1101 case tok::kw_typeof:
1103 case tok::kw_unsigned:
1105 case tok::kw_virtual:
1107 case tok::kw_volatile:
1108 case tok::kw_wchar_t:
1111 case tok::kw__Complex:
1112 case tok::kw___alignof:
1113 case tok::kw___auto_type:
1122 bool Parser::isTokIdentifier_in()
const {
1149 void Parser::ParseObjCTypeQualifierList(
ObjCDeclSpec &DS,
1155 if (Tok.
is(tok::code_completion)) {
1162 if (Tok.
isNot(tok::identifier))
1166 for (
unsigned i = 0; i != objc_NumQuals; ++i) {
1167 if (II != ObjCTypeQuals[i] ||
1175 default: llvm_unreachable(
"Unknown decl qualifier");
1193 case objc_null_unspecified:
1218 for (
auto &AL : llvm::reverse(from)) {
1219 if (!AL.isUsedAsTypeAttr()) {
1254 assert((paramAttrs !=
nullptr) ==
1257 assert(Tok.
is(tok::l_paren) &&
"expected (");
1265 ParseObjCTypeQualifierList(DS, context);
1269 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1272 declSpec.setObjCQualifiers(&DS);
1273 DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
1275 dsContext = DeclSpecContext::DSC_objc_method_result;
1276 ParseSpecifierQualifierList(declSpec,
AS_none, dsContext);
1278 ParseDeclarator(declarator);
1281 if (!declarator.isInvalidType()) {
1283 bool addedToDeclSpec =
false;
1291 if (!
type.isInvalid())
1301 if (Tok.
is(tok::r_paren))
1305 Diag(Tok, diag::err_expected_type);
1346 bool MethodDefinition) {
1349 if (Tok.
is(tok::code_completion)) {
1359 if (Tok.
is(tok::l_paren))
1365 MaybeParseAttributes(PAKM_CXX11 | (
getLangOpts().ObjC ? PAKM_GNU : 0),
1368 if (Tok.
is(tok::code_completion)) {
1380 if (!SelIdent && Tok.
isNot(tok::colon)) {
1381 Diag(Tok, diag::err_expected_selector_for_method)
1389 if (Tok.
isNot(tok::colon)) {
1391 MaybeParseAttributes(PAKM_CXX11 | (
getLangOpts().ObjC ? PAKM_GNU : 0),
1397 selLoc, Sel,
nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
1398 MethodImplKind,
false, MethodDefinition);
1399 PD.complete(Result);
1415 if (ExpectAndConsume(tok::colon))
1418 ArgInfo.
Type =
nullptr;
1419 if (Tok.
is(tok::l_paren))
1420 ArgInfo.
Type = ParseObjCTypeName(
1425 MaybeParseAttributes(PAKM_CXX11 | (
getLangOpts().ObjC ? PAKM_GNU : 0),
1430 if (Tok.
is(tok::code_completion)) {
1432 KeyIdents.push_back(SelIdent);
1434 mType == tok::minus,
1436 ReturnType, KeyIdents);
1440 if (expectIdentifier())
1447 ArgInfos.push_back(ArgInfo);
1448 KeyIdents.push_back(SelIdent);
1449 KeyLocs.push_back(selLoc);
1452 allParamAttrs.takeAllFrom(paramAttrs.
getPool());
1455 if (Tok.
is(tok::code_completion)) {
1458 mType == tok::minus,
1460 ReturnType, KeyIdents);
1465 SelIdent = ParseObjCSelectorPiece(selLoc);
1466 if (!SelIdent && Tok.
isNot(tok::colon))
1471 Diag(ArgInfo.
NameLoc, diag::warn_missing_selector_name) << ArgInfo.
Name;
1472 Diag(ArgInfo.
NameLoc, diag::note_missing_selector_name) << ArgInfo.
Name;
1473 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.
Name;
1479 bool isVariadic =
false;
1480 bool cStyleParamWarned =
false;
1482 while (Tok.
is(tok::comma)) {
1484 if (Tok.
is(tok::ellipsis)) {
1489 if (!cStyleParamWarned) {
1490 Diag(Tok, diag::warn_cstyle_param);
1491 cStyleParamWarned =
true;
1494 ParseDeclarationSpecifiers(DS);
1498 ParseDeclarator(ParmDecl);
1502 ParmDecl.getIdentifierLoc(),
1509 MaybeParseAttributes(PAKM_CXX11 | (
getLangOpts().ObjC ? PAKM_GNU : 0),
1512 if (KeyIdents.size() == 0)
1519 Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
1520 MethodImplKind, isVariadic, MethodDefinition);
1522 PD.complete(Result);
1532 bool WarnOnDeclarations,
bool ForObjCContainer,
1534 bool consumeLastToken) {
1535 assert(Tok.
is(tok::less) &&
"expected <");
1542 if (Tok.
is(tok::code_completion)) {
1548 if (expectIdentifier()) {
1562 if (ParseGreaterThanInTemplateList(LAngleLoc, EndLoc, consumeLastToken,
1568 ProtocolIdents, Protocols);
1573 assert(Tok.
is(tok::less) &&
"Protocol qualifiers start with '<'");
1574 assert(
getLangOpts().ObjC &&
"Protocol qualifiers only exist in Objective-C");
1579 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
false,
false,
1580 lAngleLoc, rAngleLoc,
1587 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1600 void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1609 bool consumeLastToken,
1610 bool warnOnIncompleteProtocols) {
1611 assert(Tok.
is(tok::less) &&
"Not at the start of type args or protocols");
1616 bool allSingleIdentifiers =
true;
1624 if (Tok.
is(tok::identifier) &&
1633 if (Tok.
is(tok::code_completion)) {
1636 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1638 identifierLocs[i]));
1651 allSingleIdentifiers =
false;
1657 if (allSingleIdentifiers) {
1660 (void)ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc, consumeLastToken,
1676 warnOnIncompleteProtocols);
1686 bool invalid =
false;
1687 IdentifierInfo *foundProtocolId =
nullptr, *foundValidTypeId =
nullptr;
1692 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1697 const char *prevSpec =
nullptr;
1699 DS.SetTypeSpecType(
TST_typename, identifierLocs[i], prevSpec, diagID,
1707 typeArgs.push_back(fullTypeArg.
get());
1708 if (!foundValidTypeId) {
1709 foundValidTypeId = identifiers[i];
1710 foundValidTypeSrcLoc = identifierLocs[i];
1714 unknownTypeArgs.push_back(identifiers[i]);
1715 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1719 if (!Actions.
LookupProtocol(identifiers[i], identifierLocs[i])) {
1720 unknownTypeArgs.push_back(identifiers[i]);
1721 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1722 }
else if (!foundProtocolId) {
1723 foundProtocolId = identifiers[i];
1724 foundProtocolSrcLoc = identifierLocs[i];
1731 Token CurTypeTok = Tok;
1742 typeArgs.push_back(typeArg.
get());
1743 if (!foundValidTypeId) {
1753 if (foundProtocolId && foundValidTypeId)
1756 foundValidTypeSrcLoc);
1760 if (unknownTypeArgs.size())
1761 for (
unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1767 (void)ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc, consumeLastToken,
1776 typeArgsLAngleLoc = lAngleLoc;
1777 typeArgsRAngleLoc = rAngleLoc;
1780 void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1789 bool consumeLastToken) {
1790 assert(Tok.
is(tok::less));
1793 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1809 if ((consumeLastToken && Tok.
is(tok::less)) ||
1810 (!consumeLastToken &&
NextToken().is(tok::less))) {
1813 if (!consumeLastToken)
1816 if (!protocols.empty()) {
1818 if (!consumeLastToken)
1820 Diag(Tok, diag::err_objc_type_args_after_protocols)
1821 <<
SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1822 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1824 ParseObjCProtocolReferences(protocols, protocolLocs,
1827 protocolLAngleLoc, protocolRAngleLoc,
1833 TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1836 bool consumeLastToken,
1838 assert(Tok.
is(tok::less));
1848 parseObjCTypeArgsAndProtocolQualifiers(
type, typeArgsLAngleLoc, typeArgs,
1849 typeArgsRAngleLoc, protocolLAngleLoc,
1850 protocols, protocolLocs,
1851 protocolRAngleLoc, consumeLastToken);
1857 if (consumeLastToken)
1858 endLoc = PrevTokLocation;
1875 void Parser::HelperActionsForIvarDeclarations(
1878 bool RBraceMissing) {
1883 "Ivars should have interfaceDecl as their decl context");
1916 assert(Tok.
is(tok::l_brace) &&
"expected {");
1924 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
1928 if (Tok.
is(tok::semi)) {
1929 ConsumeExtraSemi(InstanceVariableList);
1935 if (Tok.
is(tok::code_completion)) {
1942 case tok::objc_private:
1943 case tok::objc_public:
1944 case tok::objc_protected:
1945 case tok::objc_package:
1951 Diag(Tok, diag::err_objc_unexpected_atend);
1956 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1957 T, AllIvarDecls,
true);
1961 Diag(Tok, diag::err_objc_illegal_visibility_spec);
1966 if (Tok.
is(tok::code_completion)) {
1976 if (Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
1978 ParseStaticAssertDeclaration(DeclEnd);
1984 "Ivar should have interfaceDecl as its decl context");
1986 FD.D.setObjCIvar(
true);
1988 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
1989 FD.BitfieldSize, visibility);
1991 AllIvarDecls.push_back(Field);
1997 ParseStructDeclaration(DS, ObjCIvarCallback);
1999 if (Tok.
is(tok::semi)) {
2002 Diag(Tok, diag::err_expected_semi_decl_list);
2007 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
2008 T, AllIvarDecls,
false);
2031 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2034 if (Tok.
is(tok::code_completion)) {
2040 MaybeSkipAttributes(tok::objc_protocol);
2042 if (expectIdentifier())
2053 CheckNestedObjCContexts(AtLoc);
2055 if (Tok.
is(tok::comma)) {
2057 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2062 if (expectIdentifier()) {
2070 if (Tok.
isNot(tok::comma))
2074 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@protocol"))
2085 if (Tok.
is(tok::less) &&
2086 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
false,
true,
2087 LAngleLoc, EndProtoLoc,
2092 AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
2093 ProtocolLocs.data(), EndProtoLoc, attrs);
2095 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2110 Parser::ParseObjCAtImplementationDeclaration(
SourceLocation AtLoc,
2113 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2114 CheckNestedObjCContexts(AtLoc);
2118 if (Tok.
is(tok::code_completion)) {
2124 MaybeSkipAttributes(tok::objc_implementation);
2126 if (expectIdentifier())
2135 if (Tok.
is(tok::less)) {
2139 ObjCTypeParamListScope typeParamScope(Actions,
getCurScope());
2140 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
2141 protocolIdents, rAngleLoc)) {
2142 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2144 }
else if (lAngleLoc.
isValid()) {
2145 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2150 if (Tok.
is(tok::l_paren)) {
2156 if (Tok.
is(tok::code_completion)) {
2162 if (Tok.
is(tok::identifier)) {
2166 Diag(Tok, diag::err_expected)
2170 if (Tok.
isNot(tok::r_paren)) {
2171 Diag(Tok, diag::err_expected) << tok::r_paren;
2175 rparenLoc = ConsumeParen();
2176 if (Tok.
is(tok::less)) {
2177 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2181 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2184 protocolLAngleLoc, protocolRAngleLoc,
2188 AtLoc, nameId, nameLoc, categoryId, categoryLoc, Attrs);
2196 if (expectIdentifier())
2202 AtLoc, nameId, nameLoc, superClassId, superClassLoc, Attrs);
2204 if (Tok.
is(tok::l_brace))
2205 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2206 else if (Tok.
is(tok::less)) {
2207 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2212 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2215 protocolLAngleLoc, protocolRAngleLoc,
2219 assert(ObjCImpDecl);
2224 ObjCImplParsingDataRAII ObjCImplParsing(*
this, ObjCImpDecl);
2225 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2227 MaybeParseCXX11Attributes(attrs);
2230 DeclsInGroup.append(DG.
begin(), DG.
end());
2239 Parser::ParseObjCAtEndDeclaration(
SourceRange atEnd) {
2241 "ParseObjCAtEndDeclaration(): Expected @end");
2243 if (CurParsedObjCImpl)
2244 CurParsedObjCImpl->finish(atEnd);
2247 Diag(atEnd.
getBegin(), diag::err_expected_objc_container);
2251 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2253 finish(
P.Tok.getLocation());
2254 if (
P.isEofOrEom()) {
2255 P.Diag(
P.Tok, diag::err_objc_missing_end)
2257 P.Diag(Dcl->getBeginLoc(), diag::note_objc_container_start)
2261 P.CurParsedObjCImpl =
nullptr;
2262 assert(LateParsedObjCMethods.empty());
2265 void Parser::ObjCImplParsingDataRAII::finish(
SourceRange AtEnd) {
2267 P.Actions.DefaultSynthesizeProperties(
P.getCurScope(), Dcl, AtEnd.
getBegin());
2268 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2269 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2272 P.Actions.ActOnAtEnd(
P.getCurScope(), AtEnd);
2275 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2276 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2280 for (LateParsedObjCMethodContainer::iterator
2281 I = LateParsedObjCMethods.begin(),
2282 E = LateParsedObjCMethods.end(); I != E; ++I)
2284 LateParsedObjCMethods.clear();
2294 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2296 if (expectIdentifier())
2300 if (expectIdentifier())
2304 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@compatibility_alias");
2322 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2326 if (Tok.
is(tok::code_completion)) {
2332 if (Tok.
isNot(tok::identifier)) {
2333 Diag(Tok, diag::err_synthesized_property_name);
2344 if (Tok.
is(tok::code_completion)) {
2350 if (expectIdentifier())
2357 propertyId, propertyIvar, propertyIvarLoc,
2359 if (Tok.
isNot(tok::comma))
2363 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@synthesize");
2376 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2379 bool isClassProperty =
false;
2380 if (Tok.
is(tok::l_paren)) {
2385 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2389 if (II->
isStr(
"class")) {
2390 isClassProperty =
true;
2391 if (Tok.
isNot(tok::r_paren)) {
2392 Diag(Tok, diag::err_expected) << tok::r_paren;
2397 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2404 if (Tok.
is(tok::code_completion)) {
2410 if (expectIdentifier()) {
2423 if (Tok.
isNot(tok::comma))
2427 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@dynamic");
2437 if (Tok.
isNot(tok::semi)) {
2445 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@throw");
2455 if (Tok.
isNot(tok::l_paren)) {
2456 Diag(Tok, diag::err_expected_lparen_after) <<
"@synchronized";
2464 if (Tok.
is(tok::r_paren)) {
2467 if (!operand.isInvalid())
2468 Diag(Tok, diag::err_expected) << tok::r_paren;
2475 if (Tok.
isNot(tok::l_brace)) {
2476 if (!operand.isInvalid())
2477 Diag(Tok, diag::err_expected) << tok::l_brace;
2482 if (!operand.isInvalid())
2487 StmtResult body(ParseCompoundStatementBody());
2492 if (operand.isInvalid())
2495 if (body.isInvalid())
2513 bool catch_or_finally_seen =
false;
2516 if (Tok.
isNot(tok::l_brace)) {
2517 Diag(Tok, diag::err_expected) << tok::l_brace;
2520 StmtVector CatchStmts;
2523 StmtResult TryBody(ParseCompoundStatementBody());
2525 if (TryBody.isInvalid())
2528 while (Tok.
is(tok::at)) {
2532 Token AfterAt = GetLookAheadToken(1);
2539 Decl *FirstPart =
nullptr;
2541 if (Tok.
is(tok::l_paren)) {
2546 if (Tok.
isNot(tok::ellipsis)) {
2548 ParseDeclarationSpecifiers(DS);
2551 ParseDeclarator(ParmDecl);
2561 if (Tok.
is(tok::r_paren))
2562 RParenLoc = ConsumeParen();
2567 if (Tok.
is(tok::l_brace))
2568 CatchBody = ParseCompoundStatementBody();
2570 Diag(Tok, diag::err_expected) << tok::l_brace;
2571 if (CatchBody.isInvalid())
2578 if (!Catch.isInvalid())
2579 CatchStmts.push_back(Catch.get());
2582 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2586 catch_or_finally_seen =
true;
2588 assert(Tok.
isObjCAtKeyword(tok::objc_finally) &&
"Lookahead confused?");
2590 ParseScope FinallyScope(
this,
2593 bool ShouldCapture =
2600 if (Tok.
is(tok::l_brace))
2601 FinallyBody = ParseCompoundStatementBody();
2603 Diag(Tok, diag::err_expected) << tok::l_brace;
2605 if (FinallyBody.isInvalid()) {
2609 }
else if (ShouldCapture) {
2615 catch_or_finally_seen =
true;
2619 if (!catch_or_finally_seen) {
2620 Diag(atLoc, diag::err_missing_catch_finally);
2635 if (Tok.
isNot(tok::l_brace)) {
2636 Diag(Tok, diag::err_expected) << tok::l_brace;
2643 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2646 if (AutoreleasePoolBody.isInvalid())
2649 AutoreleasePoolBody.get());
2654 void Parser::StashAwayMethodOrFunctionBodyTokens(
Decl *MDecl) {
2656 trySkippingFunctionBody()) {
2661 LexedMethod* LM =
new LexedMethod(
this, MDecl);
2662 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2665 Toks.push_back(Tok);
2666 if (Tok.
is(tok::kw_try)) {
2668 if (Tok.
is(tok::colon)) {
2669 Toks.push_back(Tok);
2671 while (Tok.
isNot(tok::l_brace)) {
2672 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2673 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2676 Toks.push_back(Tok);
2678 else if (Tok.
is(tok::colon)) {
2681 while (Tok.
isNot(tok::l_brace)) {
2682 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2683 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2685 Toks.push_back(Tok);
2689 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2690 while (Tok.
is(tok::kw_catch)) {
2691 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
2692 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2698 Decl *Parser::ParseObjCMethodDefinition() {
2699 Decl *MDecl = ParseObjCMethodPrototype();
2702 "parsing Objective-C method");
2705 if (Tok.
is(tok::semi)) {
2706 if (CurParsedObjCImpl) {
2707 Diag(Tok, diag::warn_semicolon_before_method_body)
2714 if (Tok.
isNot(tok::l_brace)) {
2715 Diag(Tok, diag::err_expected_method_body);
2721 if (Tok.
isNot(tok::l_brace))
2733 assert (CurParsedObjCImpl
2734 &&
"ParseObjCMethodDefinition - Method out of @implementation");
2736 StashAwayMethodOrFunctionBodyTokens(MDecl);
2741 ParsedStmtContext StmtCtx) {
2742 if (Tok.
is(tok::code_completion)) {
2749 return ParseObjCTryStmt(AtLoc);
2752 return ParseObjCThrowStmt(AtLoc);
2755 return ParseObjCSynchronizedStmt(AtLoc);
2758 return ParseObjCAutoreleasePoolStmt(AtLoc);
2766 ExprStatementTokLoc = AtLoc;
2767 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2777 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2778 return handleExprStmt(Res, StmtCtx);
2783 case tok::code_completion:
2793 if (!Tok.
is(tok::numeric_constant)) {
2794 const char *Symbol =
nullptr;
2796 case tok::minus: Symbol =
"-";
break;
2797 case tok::plus: Symbol =
"+";
break;
2798 default: llvm_unreachable(
"missing unary operator case");
2800 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2806 if (Lit.isInvalid()) {
2812 if (Lit.isInvalid())
2815 return ParsePostfixExpressionSuffix(
2819 case tok::string_literal:
2820 case tok::wide_string_literal:
2821 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2823 case tok::char_constant:
2824 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2826 case tok::numeric_constant:
2827 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2830 case tok::kw___objc_yes:
2831 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
true));
2833 case tok::kw___objc_no:
2834 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
false));
2838 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2842 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2846 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2853 case tok::objc_encode:
2854 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2855 case tok::objc_protocol:
2856 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2857 case tok::objc_selector:
2858 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2859 case tok::objc_available:
2860 return ParseAvailabilityCheckExpr(AtLoc);
2862 const char *str =
nullptr;
2866 if (GetLookAheadToken(1).is(tok::l_brace) &&
2867 ExprStatementTokLoc == AtLoc) {
2871 : (ch ==
'f' ?
"finally"
2872 : (ch ==
'a' ?
"autoreleasepool" :
nullptr));
2908 bool Parser::ParseObjCXXMessageReceiver(
bool &IsExpr,
void *&TypeOrExpr) {
2911 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2912 tok::annot_cxxscope))
2926 TypeOrExpr = Receiver.
get();
2935 ParseCXXSimpleTypeSpecifier(DS);
2937 if (Tok.
is(tok::l_paren)) {
2950 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2952 Receiver = ParsePostfixExpressionSuffix(Receiver.
get());
2954 Receiver = ParseRHSOfBinaryExpression(Receiver.
get(),
prec::Comma);
2959 TypeOrExpr = Receiver.
get();
2969 if (
Type.isInvalid())
2973 TypeOrExpr =
Type.get().getAsOpaquePtr();
2982 bool Parser::isSimpleObjCMessageExpression() {
2984 "Incorrect start for isSimpleObjCMessageExpression");
2985 return GetLookAheadToken(1).
is(tok::identifier) &&
2986 GetLookAheadToken(2).
is(tok::identifier);
2989 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2991 InMessageExpression)
2996 if (Tok.
is(tok::annot_typename))
2998 else if (Tok.
is(tok::identifier))
3006 const Token &AfterNext = GetLookAheadToken(2);
3007 if (AfterNext.
isOneOf(tok::colon, tok::r_square)) {
3008 if (Tok.
is(tok::identifier))
3011 return Tok.
is(tok::annot_typename);
3027 ExprResult Parser::ParseObjCMessageExpression() {
3028 assert(Tok.
is(tok::l_square) &&
"'[' expected");
3031 if (Tok.
is(tok::code_completion)) {
3048 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3053 void *TypeOrExpr =
nullptr;
3054 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
3060 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3061 static_cast<Expr *
>(TypeOrExpr));
3063 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3068 if (Tok.
is(tok::identifier)) {
3073 Name == Ident_super,
3077 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3081 if (!ReceiverType) {
3089 if (Tok.
is(tok::less)) {
3092 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3100 ReceiverType = NewReceiverType.
get();
3103 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3104 ReceiverType,
nullptr);
3119 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3165 Expr *ReceiverExpr) {
3168 if (Tok.
is(tok::code_completion)) {
3173 else if (ReceiverType)
3188 ExprVector KeyExprs;
3190 if (Tok.
is(tok::colon)) {
3193 KeyIdents.push_back(selIdent);
3194 KeyLocs.push_back(Loc);
3196 if (ExpectAndConsume(tok::colon)) {
3206 if (Tok.
is(tok::code_completion)) {
3212 else if (ReceiverType)
3226 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3227 Expr = ParseBraceInitializer();
3241 KeyExprs.push_back(Res.
get());
3244 if (Tok.
is(tok::code_completion)) {
3250 else if (ReceiverType)
3262 selIdent = ParseObjCSelectorPiece(Loc);
3263 if (!selIdent && Tok.
isNot(tok::colon))
3268 while (Tok.
is(tok::comma)) {
3272 if (Tok.
is(tok::colon))
3275 if (Tok.
is(tok::colon)) {
3276 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3287 KeyExprs.push_back(Res.
get());
3289 }
else if (!selIdent) {
3290 Diag(Tok, diag::err_expected) << tok::identifier;
3299 if (Tok.
isNot(tok::r_square)) {
3300 Diag(Tok, diag::err_expected)
3301 << (Tok.
is(tok::identifier) ? tok::colon : tok::r_square);
3311 unsigned nKeys = KeyIdents.size();
3313 KeyIdents.push_back(selIdent);
3314 KeyLocs.push_back(Loc);
3320 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3321 else if (ReceiverType)
3323 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3325 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3336 ExprVector AtStrings;
3337 AtLocs.push_back(AtLoc);
3338 AtStrings.push_back(Res.
get());
3340 while (Tok.
is(tok::at)) {
3344 if (!isTokenStringLiteral())
3348 if (Lit.isInvalid())
3351 AtStrings.push_back(Lit.get());
3373 if (Lit.isInvalid()) {
3387 if (Lit.isInvalid()) {
3399 if (Tok.
isNot(tok::l_paren))
3400 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@");
3408 if (ValueExpr.isInvalid())
3414 ValueExpr = Actions.
ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
3420 ExprVector ElementExprs;
3423 bool HasInvalidEltExpr =
false;
3424 while (Tok.
isNot(tok::r_square)) {
3437 HasInvalidEltExpr =
true;
3440 if (Tok.
is(tok::ellipsis))
3443 HasInvalidEltExpr =
true;
3445 ElementExprs.push_back(Res.
get());
3447 if (Tok.
is(tok::comma))
3449 else if (Tok.
isNot(tok::r_square))
3450 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_square
3455 if (HasInvalidEltExpr)
3465 bool HasInvalidEltExpr =
false;
3466 while (Tok.
isNot(tok::r_brace)) {
3481 if (ExpectAndConsume(tok::colon)) {
3487 if (ValueExpr.isInvalid()) {
3498 if (KeyExpr.
isInvalid() || ValueExpr.isInvalid())
3499 HasInvalidEltExpr =
true;
3511 KeyExpr.
get(), ValueExpr.get(), EllipsisLoc,
None
3513 Elements.push_back(Element);
3516 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_brace
3521 if (HasInvalidEltExpr)
3533 assert(Tok.
isObjCAtKeyword(tok::objc_encode) &&
"Not an @encode expression!");
3537 if (Tok.
isNot(tok::l_paren))
3538 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@encode");
3560 if (Tok.
isNot(tok::l_paren))
3561 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@protocol");
3566 if (expectIdentifier())
3584 if (Tok.
isNot(tok::l_paren))
3585 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@selector");
3592 bool HasOptionalParen = Tok.
is(tok::l_paren);
3593 if (HasOptionalParen)
3596 if (Tok.
is(tok::code_completion)) {
3604 Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3605 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3607 KeyIdents.push_back(SelIdent);
3609 unsigned nColons = 0;
3610 if (Tok.
isNot(tok::r_paren)) {
3614 KeyIdents.push_back(
nullptr);
3615 }
else if (ExpectAndConsume(tok::colon))
3619 if (Tok.
is(tok::r_paren))
3622 if (Tok.
is(tok::code_completion)) {
3630 SelIdent = ParseObjCSelectorPiece(Loc);
3631 KeyIdents.push_back(SelIdent);
3632 if (!SelIdent && Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3636 if (HasOptionalParen && Tok.
is(tok::r_paren))
3646 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM,
bool parseMethod) {
3648 Decl *MCDecl = LM.D;
3649 bool skip = MCDecl &&
3658 assert(!LM.Toks.empty() &&
"ParseLexedObjCMethodDef - Empty body!");
3666 LM.Toks.push_back(Eof);
3669 LM.Toks.push_back(Tok);
3670 PP.EnterTokenStream(LM.Toks,
true,
true);
3675 assert(Tok.
isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3676 "Inline objective-c method not starting with '{' or 'try' or ':'");
3688 if (Tok.
is(tok::kw_try))
3689 ParseFunctionTryBlock(MCDecl, BodyScope);
3691 if (Tok.
is(tok::colon))
3692 ParseConstructorInitializer(MCDecl);
3695 ParseFunctionStatementBody(MCDecl, BodyScope);