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)
181 Diag(Decl->
getBeginLoc(), diag::note_objc_container_start) << (
int)ock;
216 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
217 CheckNestedObjCContexts(AtLoc);
221 if (Tok.
is(tok::code_completion)) {
222 Actions.CodeCompleteObjCInterfaceDecl(
getCurScope());
227 MaybeSkipAttributes(tok::objc_interface);
229 if (expectIdentifier())
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)) {
256 Actions.CodeCompleteObjCInterfaceCategory(
getCurScope(), nameId, nameLoc);
262 if (Tok.
is(tok::identifier)) {
263 categoryId = Tok.getIdentifierInfo();
267 Diag(Tok, diag::err_expected)
277 assert(LAngleLoc.
isInvalid() &&
"Cannot have already parsed protocols");
280 if (Tok.
is(tok::less) &&
281 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
true,
true,
282 LAngleLoc, EndProtoLoc,
286 Decl *CategoryType = Actions.ActOnStartCategoryInterface(
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)) {
311 Actions.CodeCompleteObjCSuperclass(
getCurScope(), nameId, nameLoc);
316 if (expectIdentifier())
318 superClassId = Tok.getIdentifierInfo();
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);
341 Actions.FindProtocolDeclaration(
true,
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))
353 Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
354 superClassId, superClassLoc);
356 Decl *ClsType = Actions.ActOnStartClassInterface(
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) {
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) {
436 DeclResult typeParam = Actions.actOnObjCTypeParam(
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)) {
475 Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
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));
514 DeclResult typeParam = Actions.actOnObjCTypeParam(
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(rAngleLoc,
529 Diag(lAngleLoc, diag::note_matching) <<
"'<'";
530 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
531 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
532 tok::comma, tok::semi },
534 if (Tok.
is(tok::greater))
538 if (mayBeProtocolList) {
543 if (Tok.
isNot(tok::colon) && Tok.
isNot(tok::l_paren)) {
552 makeProtocolIdentsIntoTypeParameters();
567 return invalid ? nullptr : list;
576 ObjCTypeParamListScope Scope(Actions,
getCurScope());
577 return parseObjCTypeParamListOrProtocolRefs(Scope, lAngleLoc, protocolIdents,
604 if (Tok.
isOneOf(tok::minus, tok::plus)) {
605 if (
Decl *methodPrototype =
606 ParseObjCMethodPrototype(MethodImplKind,
false))
607 allMethods.push_back(methodPrototype);
610 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
613 if (Tok.
is(tok::semi))
618 if (Tok.
is(tok::l_paren)) {
619 Diag(Tok, diag::err_expected_minus_or_plus);
620 ParseObjCMethodDecl(Tok.getLocation(),
622 MethodImplKind,
false);
626 if (Tok.
is(tok::semi)) {
636 if (Tok.
is(tok::code_completion)) {
640 return cutOffParsing();
644 if (Tok.
isNot(tok::at)) {
648 if (Tok.
is(tok::r_brace))
650 ParsedAttributesWithRange attrs(AttrFactory);
651 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
657 if (Tok.
is(tok::code_completion)) {
658 Actions.CodeCompleteObjCAtDirective(
getCurScope());
659 return cutOffParsing();
664 if (DirectiveKind == tok::objc_end) {
666 AtEnd.
setEnd(Tok.getLocation());
668 }
else if (DirectiveKind == tok::objc_not_keyword) {
669 Diag(Tok, diag::err_objc_unknown_at);
677 switch (DirectiveKind) {
683 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
688 case tok::objc_implementation:
689 case tok::objc_interface:
690 Diag(AtLoc, diag::err_objc_missing_end)
693 << (
int)Actions.getObjCContainerKind();
697 case tok::objc_required:
698 case tok::objc_optional:
701 if (contextKey != tok::objc_protocol)
702 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
704 MethodImplKind = DirectiveKind;
707 case tok::objc_property:
709 Diag(AtLoc, diag::err_objc_properties_require_objc2);
714 if (Tok.
is(tok::l_paren)) {
715 LParenLoc = Tok.getLocation();
716 ParseObjCPropertyAttribute(OCDS);
719 bool addedToDeclSpec =
false;
721 if (FD.D.getIdentifier() ==
nullptr) {
722 Diag(AtLoc, diag::err_objc_property_requires_field_name)
723 << FD.D.getSourceRange();
726 if (FD.BitfieldSize) {
727 Diag(AtLoc, diag::err_objc_property_bitfield)
728 << FD.D.getSourceRange();
743 Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName);
747 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
750 PP.getIdentifierTable(), PP.getSelectorTable(),
751 FD.D.getIdentifier());
753 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
756 FD.complete(Property);
761 ParseStructDeclaration(DS, ObjCPropertyCallback);
763 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
770 if (Tok.
is(tok::code_completion)) {
771 Actions.CodeCompleteObjCAtDirective(
getCurScope());
772 return cutOffParsing();
776 Diag(Tok, diag::err_objc_missing_end)
779 << (
int)Actions.getObjCContainerKind();
781 AtEnd.
setEnd(Tok.getLocation());
786 Actions.ActOnAtEnd(
getCurScope(), AtEnd, allMethods, allTUVariables);
795 P.
Diag(nullabilityLoc, diag::warn_nullability_duplicate)
801 P.
Diag(nullabilityLoc, diag::err_nullability_conflicting)
832 void Parser::ParseObjCPropertyAttribute(
ObjCDeclSpec &DS) {
833 assert(Tok.getKind() == tok::l_paren);
838 if (Tok.
is(tok::code_completion)) {
839 Actions.CodeCompleteObjCPropertyFlags(
getCurScope(), DS);
840 return cutOffParsing();
852 if (II->
isStr(
"readonly"))
854 else if (II->
isStr(
"assign"))
856 else if (II->
isStr(
"unsafe_unretained"))
858 else if (II->
isStr(
"readwrite"))
860 else if (II->
isStr(
"retain"))
862 else if (II->
isStr(
"strong"))
864 else if (II->
isStr(
"copy"))
866 else if (II->
isStr(
"nonatomic"))
868 else if (II->
isStr(
"atomic"))
870 else if (II->
isStr(
"weak"))
872 else if (II->
isStr(
"getter") || II->
isStr(
"setter")) {
876 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
877 diag::err_objc_expected_equal_for_getter;
879 if (ExpectAndConsume(tok::equal, DiagID)) {
884 if (Tok.
is(tok::code_completion)) {
886 Actions.CodeCompleteObjCPropertySetter(
getCurScope());
888 Actions.CodeCompleteObjCPropertyGetter(
getCurScope());
889 return cutOffParsing();
896 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
906 if (ExpectAndConsume(tok::colon,
907 diag::err_expected_colon_after_setter_name)) {
915 }
else if (II->
isStr(
"nonnull")) {
922 }
else if (II->
isStr(
"nullable")) {
929 }
else if (II->
isStr(
"null_unspecified")) {
936 }
else if (II->
isStr(
"null_resettable")) {
946 }
else if (II->
isStr(
"class")) {
949 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
954 if (Tok.
isNot(tok::comma))
974 bool MethodDefinition) {
975 assert(Tok.
isOneOf(tok::minus, tok::plus) &&
"expected +/-");
979 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
996 switch (Tok.getKind()) {
1001 SelectorLoc = Tok.getLocation();
1009 case tok::exclaimequal:
1011 case tok::pipeequal:
1013 case tok::caretequal: {
1014 std::string ThisTok(PP.getSpelling(Tok));
1017 Tok.setKind(tok::identifier);
1024 case tok::identifier:
1034 case tok::kw_const_cast:
1035 case tok::kw_continue:
1036 case tok::kw_default:
1037 case tok::kw_delete:
1039 case tok::kw_double:
1040 case tok::kw_dynamic_cast:
1043 case tok::kw_explicit:
1044 case tok::kw_export:
1045 case tok::kw_extern:
1049 case tok::kw_friend:
1052 case tok::kw_inline:
1055 case tok::kw_mutable:
1056 case tok::kw_namespace:
1058 case tok::kw_operator:
1059 case tok::kw_private:
1060 case tok::kw_protected:
1061 case tok::kw_public:
1062 case tok::kw_register:
1063 case tok::kw_reinterpret_cast:
1064 case tok::kw_restrict:
1065 case tok::kw_return:
1067 case tok::kw_signed:
1068 case tok::kw_sizeof:
1069 case tok::kw_static:
1070 case tok::kw_static_cast:
1071 case tok::kw_struct:
1072 case tok::kw_switch:
1073 case tok::kw_template:
1078 case tok::kw_typedef:
1079 case tok::kw_typeid:
1080 case tok::kw_typename:
1081 case tok::kw_typeof:
1083 case tok::kw_unsigned:
1085 case tok::kw_virtual:
1087 case tok::kw_volatile:
1088 case tok::kw_wchar_t:
1091 case tok::kw__Complex:
1092 case tok::kw___alignof:
1093 case tok::kw___auto_type:
1102 bool Parser::isTokIdentifier_in()
const {
1107 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
1129 void Parser::ParseObjCTypeQualifierList(
ObjCDeclSpec &DS,
1135 if (Tok.
is(tok::code_completion)) {
1136 Actions.CodeCompleteObjCPassingType(
getCurScope(), DS,
1138 return cutOffParsing();
1141 if (Tok.
isNot(tok::identifier))
1145 for (
unsigned i = 0; i != objc_NumQuals; ++i) {
1146 if (II != ObjCTypeQuals[i] ||
1154 default: llvm_unreachable(
"Unknown decl qualifier");
1172 case objc_null_unspecified:
1197 for (
auto &AL : llvm::reverse(from)) {
1198 if (!AL.isUsedAsTypeAttr()) {
1229 assert((paramAttrs !=
nullptr) ==
1232 assert(Tok.
is(tok::l_paren) &&
"expected (");
1241 ParseObjCTypeQualifierList(DS, context);
1244 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1248 DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
1250 dsContext = DeclSpecContext::DSC_objc_method_result;
1251 ParseSpecifierQualifierList(declSpec,
AS_none, dsContext);
1253 ParseDeclarator(declarator);
1258 bool addedToDeclSpec =
false;
1276 if (Tok.
is(tok::r_paren))
1278 else if (Tok.getLocation() == TypeStartLoc) {
1280 Diag(Tok, diag::err_expected_type);
1321 bool MethodDefinition) {
1324 if (Tok.
is(tok::code_completion)) {
1325 Actions.CodeCompleteObjCMethodDecl(
getCurScope(), mType == tok::minus,
1334 if (Tok.
is(tok::l_paren))
1341 MaybeParseGNUAttributes(methodAttrs);
1342 MaybeParseCXX11Attributes(methodAttrs);
1344 if (Tok.
is(tok::code_completion)) {
1345 Actions.CodeCompleteObjCMethodDecl(
getCurScope(), mType == tok::minus,
1356 if (!SelIdent && Tok.
isNot(tok::colon)) {
1357 Diag(Tok, diag::err_expected_selector_for_method)
1365 if (Tok.
isNot(tok::colon)) {
1368 MaybeParseGNUAttributes(methodAttrs);
1369 MaybeParseCXX11Attributes(methodAttrs);
1371 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
1372 Decl *
Result = Actions.ActOnMethodDeclaration(
1373 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType,
1374 selLoc, Sel,
nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
1375 MethodImplKind,
false, MethodDefinition);
1392 if (ExpectAndConsume(tok::colon))
1395 ArgInfo.
Type =
nullptr;
1396 if (Tok.
is(tok::l_paren))
1404 MaybeParseGNUAttributes(paramAttrs);
1405 MaybeParseCXX11Attributes(paramAttrs);
1409 if (Tok.
is(tok::code_completion)) {
1410 KeyIdents.push_back(SelIdent);
1411 Actions.CodeCompleteObjCMethodDeclSelector(
getCurScope(),
1412 mType == tok::minus,
1414 ReturnType, KeyIdents);
1419 if (expectIdentifier())
1422 ArgInfo.
Name = Tok.getIdentifierInfo();
1423 ArgInfo.
NameLoc = Tok.getLocation();
1426 ArgInfos.push_back(ArgInfo);
1427 KeyIdents.push_back(SelIdent);
1428 KeyLocs.push_back(selLoc);
1434 if (Tok.
is(tok::code_completion)) {
1435 Actions.CodeCompleteObjCMethodDeclSelector(
getCurScope(),
1436 mType == tok::minus,
1438 ReturnType, KeyIdents);
1444 SelIdent = ParseObjCSelectorPiece(selLoc);
1445 if (!SelIdent && Tok.
isNot(tok::colon))
1450 Diag(ArgInfo.
NameLoc, diag::warn_missing_selector_name) << ArgInfo.
Name;
1451 Diag(ArgInfo.
NameLoc, diag::note_missing_selector_name) << ArgInfo.
Name;
1452 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.
Name;
1458 bool isVariadic =
false;
1459 bool cStyleParamWarned =
false;
1461 while (Tok.
is(tok::comma)) {
1463 if (Tok.
is(tok::ellipsis)) {
1468 if (!cStyleParamWarned) {
1469 Diag(Tok, diag::warn_cstyle_param);
1470 cStyleParamWarned =
true;
1473 ParseDeclarationSpecifiers(DS);
1476 ParseDeclarator(ParmDecl);
1488 MaybeParseGNUAttributes(methodAttrs);
1489 MaybeParseCXX11Attributes(methodAttrs);
1491 if (KeyIdents.size() == 0)
1494 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
1496 Decl *
Result = Actions.ActOnMethodDeclaration(
1497 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
1498 Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
1499 MethodImplKind, isVariadic, MethodDefinition);
1511 bool WarnOnDeclarations,
bool ForObjCContainer,
1513 bool consumeLastToken) {
1514 assert(Tok.
is(tok::less) &&
"expected <");
1521 if (Tok.
is(tok::code_completion)) {
1522 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
1527 if (expectIdentifier()) {
1531 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
1532 Tok.getLocation()));
1533 ProtocolLocs.push_back(Tok.getLocation());
1541 if (ParseGreaterThanInTemplateList(EndLoc, consumeLastToken,
1546 Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer,
1547 ProtocolIdents, Protocols);
1552 assert(Tok.
is(tok::less) &&
"Protocol qualifiers start with '<'");
1553 assert(
getLangOpts().ObjC &&
"Protocol qualifiers only exist in Objective-C");
1558 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
false,
false,
1559 lAngleLoc, rAngleLoc,
1561 TypeResult result = Actions.actOnObjCProtocolQualifierType(lAngleLoc,
1566 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1579 void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1588 bool consumeLastToken,
1589 bool warnOnIncompleteProtocols) {
1590 assert(Tok.
is(tok::less) &&
"Not at the start of type args or protocols");
1595 bool allSingleIdentifiers =
true;
1603 if (Tok.
is(tok::identifier) &&
1607 identifiers.push_back(Tok.getIdentifierInfo());
1612 if (Tok.
is(tok::code_completion)) {
1615 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1617 identifierLocs[i]));
1620 QualType BaseT = Actions.GetTypeFromParser(baseType);
1624 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
1630 allSingleIdentifiers =
false;
1636 if (allSingleIdentifiers) {
1639 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1643 Actions.actOnObjCTypeArgsOrProtocolQualifiers(
getCurScope(),
1655 warnOnIncompleteProtocols);
1665 bool invalid =
false;
1666 IdentifierInfo *foundProtocolId =
nullptr, *foundValidTypeId =
nullptr;
1671 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1673 = Actions.getTypeName(*identifiers[i], identifierLocs[i],
getCurScope());
1676 const char *prevSpec =
nullptr;
1679 typeArg, Actions.getASTContext().getPrintingPolicy());
1685 typeArgs.push_back(fullTypeArg.
get());
1686 if (!foundValidTypeId) {
1687 foundValidTypeId = identifiers[i];
1688 foundValidTypeSrcLoc = identifierLocs[i];
1692 unknownTypeArgs.push_back(identifiers[i]);
1693 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1697 if (!Actions.LookupProtocol(identifiers[i], identifierLocs[i])) {
1698 unknownTypeArgs.push_back(identifiers[i]);
1699 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1700 }
else if (!foundProtocolId) {
1701 foundProtocolId = identifiers[i];
1702 foundProtocolSrcLoc = identifierLocs[i];
1709 Token CurTypeTok = Tok;
1716 typeArg = Actions.ActOnPackExpansion(typeArg.
get(), ellipsisLoc);
1720 typeArgs.push_back(typeArg.
get());
1721 if (!foundValidTypeId) {
1731 if (foundProtocolId && foundValidTypeId)
1732 Actions.DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc,
1734 foundValidTypeSrcLoc);
1738 if (unknownTypeArgs.size())
1739 for (
unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1740 Actions.DiagnoseUnknownTypeName(unknownTypeArgs[i], unknownTypeArgsLoc[i],
1745 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1754 typeArgsLAngleLoc = lAngleLoc;
1755 typeArgsRAngleLoc = rAngleLoc;
1758 void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1767 bool consumeLastToken) {
1768 assert(Tok.
is(tok::less));
1771 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1787 if ((consumeLastToken && Tok.
is(tok::less)) ||
1788 (!consumeLastToken &&
NextToken().
is(tok::less))) {
1791 if (!consumeLastToken)
1794 if (!protocols.empty()) {
1796 if (!consumeLastToken)
1798 Diag(Tok, diag::err_objc_type_args_after_protocols)
1799 <<
SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1800 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1802 ParseObjCProtocolReferences(protocols, protocolLocs,
1805 protocolLAngleLoc, protocolRAngleLoc,
1811 TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1814 bool consumeLastToken,
1816 assert(Tok.
is(tok::less));
1826 parseObjCTypeArgsAndProtocolQualifiers(type, typeArgsLAngleLoc, typeArgs,
1827 typeArgsRAngleLoc, protocolLAngleLoc,
1828 protocols, protocolLocs,
1829 protocolRAngleLoc, consumeLastToken);
1835 if (consumeLastToken)
1836 endLoc = PrevTokLocation;
1838 endLoc = Tok.getLocation();
1840 return Actions.actOnObjCTypeArgsAndProtocolQualifiers(
1853 void Parser::HelperActionsForIvarDeclarations(
Decl *interfaceDecl,
SourceLocation atLoc,
1856 bool RBraceMissing) {
1860 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1862 Actions.ActOnObjCContainerFinishDefinition();
1865 Actions.ActOnFields(
getCurScope(), atLoc, interfaceDecl, AllIvarDecls,
1890 void Parser::ParseObjCClassInstanceVariables(
Decl *interfaceDecl,
1893 assert(Tok.
is(tok::l_brace) &&
"expected {");
1902 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
1906 if (Tok.
is(tok::semi)) {
1907 ConsumeExtraSemi(InstanceVariableList);
1913 if (Tok.
is(tok::code_completion)) {
1914 Actions.CodeCompleteObjCAtVisibility(
getCurScope());
1915 return cutOffParsing();
1918 switch (Tok.getObjCKeywordID()) {
1919 case tok::objc_private:
1920 case tok::objc_public:
1921 case tok::objc_protected:
1922 case tok::objc_package:
1923 visibility = Tok.getObjCKeywordID();
1928 Diag(Tok, diag::err_objc_unexpected_atend);
1929 Tok.setLocation(Tok.getLocation().getLocWithOffset(-1));
1930 Tok.setKind(tok::at);
1933 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1934 T, AllIvarDecls,
true);
1938 Diag(Tok, diag::err_objc_illegal_visibility_spec);
1943 if (Tok.
is(tok::code_completion)) {
1946 return cutOffParsing();
1950 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1952 FD.D.setObjCIvar(
true);
1953 Decl *Field = Actions.ActOnIvar(
1954 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
1955 FD.BitfieldSize, visibility);
1956 Actions.ActOnObjCContainerFinishDefinition();
1958 AllIvarDecls.push_back(Field);
1964 ParseStructDeclaration(DS, ObjCIvarCallback);
1966 if (Tok.
is(tok::semi)) {
1969 Diag(Tok, diag::err_expected_semi_decl_list);
1974 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1975 T, AllIvarDecls,
false);
1998 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2001 if (Tok.
is(tok::code_completion)) {
2002 Actions.CodeCompleteObjCProtocolDecl(
getCurScope());
2007 MaybeSkipAttributes(tok::objc_protocol);
2009 if (expectIdentifier())
2017 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs);
2020 CheckNestedObjCContexts(AtLoc);
2022 if (Tok.
is(tok::comma)) {
2024 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2029 if (expectIdentifier()) {
2034 Tok.getLocation()));
2037 if (Tok.
isNot(tok::comma))
2041 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@protocol"))
2044 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs);
2052 if (Tok.
is(tok::less) &&
2053 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
false,
true,
2054 LAngleLoc, EndProtoLoc,
2058 Decl *ProtoType = Actions.ActOnStartProtocolInterface(
2059 AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
2060 ProtocolLocs.data(), EndProtoLoc, attrs);
2062 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2063 return Actions.ConvertDeclToDeclGroup(ProtoType);
2077 Parser::ParseObjCAtImplementationDeclaration(
SourceLocation AtLoc) {
2079 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2080 CheckNestedObjCContexts(AtLoc);
2084 if (Tok.
is(tok::code_completion)) {
2085 Actions.CodeCompleteObjCImplementationDecl(
getCurScope());
2090 MaybeSkipAttributes(tok::objc_implementation);
2092 if (expectIdentifier())
2097 Decl *ObjCImpDecl =
nullptr;
2101 if (Tok.
is(tok::less)) {
2105 ObjCTypeParamListScope typeParamScope(Actions,
getCurScope());
2106 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
2107 protocolIdents, rAngleLoc)) {
2108 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2110 }
else if (lAngleLoc.
isValid()) {
2111 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2116 if (Tok.
is(tok::l_paren)) {
2122 if (Tok.
is(tok::code_completion)) {
2123 Actions.CodeCompleteObjCImplementationCategory(
getCurScope(), nameId, nameLoc);
2128 if (Tok.
is(tok::identifier)) {
2129 categoryId = Tok.getIdentifierInfo();
2132 Diag(Tok, diag::err_expected)
2136 if (Tok.
isNot(tok::r_paren)) {
2137 Diag(Tok, diag::err_expected) << tok::r_paren;
2141 rparenLoc = ConsumeParen();
2142 if (Tok.
is(tok::less)) {
2143 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2147 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2150 protocolLAngleLoc, protocolRAngleLoc,
2153 ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
2154 AtLoc, nameId, nameLoc, categoryId,
2163 if (expectIdentifier())
2165 superClassId = Tok.getIdentifierInfo();
2168 ObjCImpDecl = Actions.ActOnStartClassImplementation(
2169 AtLoc, nameId, nameLoc,
2170 superClassId, superClassLoc);
2172 if (Tok.
is(tok::l_brace))
2173 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2174 else if (Tok.
is(tok::less)) {
2175 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2180 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2183 protocolLAngleLoc, protocolRAngleLoc,
2187 assert(ObjCImpDecl);
2192 ObjCImplParsingDataRAII ObjCImplParsing(*
this, ObjCImpDecl);
2193 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2194 ParsedAttributesWithRange attrs(AttrFactory);
2195 MaybeParseCXX11Attributes(attrs);
2198 DeclsInGroup.append(DG.
begin(), DG.
end());
2203 return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup);
2207 Parser::ParseObjCAtEndDeclaration(
SourceRange atEnd) {
2209 "ParseObjCAtEndDeclaration(): Expected @end");
2211 if (CurParsedObjCImpl)
2212 CurParsedObjCImpl->finish(atEnd);
2215 Diag(atEnd.
getBegin(), diag::err_expected_objc_container);
2219 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2221 finish(
P.Tok.getLocation());
2222 if (
P.isEofOrEom()) {
2223 P.Diag(
P.Tok, diag::err_objc_missing_end)
2225 P.Diag(Dcl->getBeginLoc(), diag::note_objc_container_start)
2229 P.CurParsedObjCImpl =
nullptr;
2230 assert(LateParsedObjCMethods.empty());
2233 void Parser::ObjCImplParsingDataRAII::finish(
SourceRange AtEnd) {
2235 P.Actions.DefaultSynthesizeProperties(
P.getCurScope(), Dcl, AtEnd.
getBegin());
2236 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2237 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2240 P.Actions.ActOnAtEnd(
P.getCurScope(), AtEnd);
2243 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2244 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2248 for (LateParsedObjCMethodContainer::iterator
2249 I = LateParsedObjCMethods.begin(),
2250 E = LateParsedObjCMethods.end(); I != E; ++I)
2252 LateParsedObjCMethods.clear();
2262 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2264 if (expectIdentifier())
2268 if (expectIdentifier())
2272 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@compatibility_alias");
2273 return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
2290 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2294 if (Tok.
is(tok::code_completion)) {
2295 Actions.CodeCompleteObjCPropertyDefinition(
getCurScope());
2300 if (Tok.
isNot(tok::identifier)) {
2301 Diag(Tok, diag::err_synthesized_property_name);
2312 if (Tok.
is(tok::code_completion)) {
2313 Actions.CodeCompleteObjCPropertySynthesizeIvar(
getCurScope(), propertyId);
2318 if (expectIdentifier())
2320 propertyIvar = Tok.getIdentifierInfo();
2323 Actions.ActOnPropertyImplDecl(
2325 propertyId, propertyIvar, propertyIvarLoc,
2327 if (Tok.
isNot(tok::comma))
2331 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@synthesize");
2344 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2347 bool isClassProperty =
false;
2348 if (Tok.
is(tok::l_paren)) {
2353 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2357 if (II->
isStr(
"class")) {
2358 isClassProperty =
true;
2359 if (Tok.
isNot(tok::r_paren)) {
2360 Diag(Tok, diag::err_expected) << tok::r_paren;
2365 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2372 if (Tok.
is(tok::code_completion)) {
2373 Actions.CodeCompleteObjCPropertyDefinition(
getCurScope());
2378 if (expectIdentifier()) {
2385 Actions.ActOnPropertyImplDecl(
2391 if (Tok.
isNot(tok::comma))
2395 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@dynamic");
2405 if (Tok.
isNot(tok::semi)) {
2413 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@throw");
2414 return Actions.ActOnObjCAtThrowStmt(atLoc, Res.
get(),
getCurScope());
2423 if (Tok.
isNot(tok::l_paren)) {
2424 Diag(Tok, diag::err_expected_lparen_after) <<
"@synchronized";
2432 if (Tok.
is(tok::r_paren)) {
2436 Diag(Tok, diag::err_expected) << tok::r_paren;
2443 if (Tok.
isNot(tok::l_brace)) {
2445 Diag(Tok, diag::err_expected) << tok::l_brace;
2451 operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.
get());
2455 StmtResult body(ParseCompoundStatementBody());
2463 if (body.isInvalid())
2464 body = Actions.ActOnNullStmt(Tok.getLocation());
2466 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.
get(), body.get());
2481 bool catch_or_finally_seen =
false;
2484 if (Tok.
isNot(tok::l_brace)) {
2485 Diag(Tok, diag::err_expected) << tok::l_brace;
2488 StmtVector CatchStmts;
2491 StmtResult TryBody(ParseCompoundStatementBody());
2493 if (TryBody.isInvalid())
2494 TryBody = Actions.ActOnNullStmt(Tok.getLocation());
2496 while (Tok.
is(tok::at)) {
2500 Token AfterAt = GetLookAheadToken(1);
2507 Decl *FirstPart =
nullptr;
2509 if (Tok.
is(tok::l_paren)) {
2514 if (Tok.
isNot(tok::ellipsis)) {
2516 ParseDeclarationSpecifiers(DS);
2518 ParseDeclarator(ParmDecl);
2522 FirstPart = Actions.ActOnObjCExceptionDecl(
getCurScope(), ParmDecl);
2528 if (Tok.
is(tok::r_paren))
2529 RParenLoc = ConsumeParen();
2534 if (Tok.
is(tok::l_brace))
2535 CatchBody = ParseCompoundStatementBody();
2537 Diag(Tok, diag::err_expected) << tok::l_brace;
2538 if (CatchBody.isInvalid())
2539 CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
2541 StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
2545 if (!Catch.isInvalid())
2546 CatchStmts.push_back(Catch.get());
2549 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2553 catch_or_finally_seen =
true;
2555 assert(Tok.
isObjCAtKeyword(tok::objc_finally) &&
"Lookahead confused?");
2557 ParseScope FinallyScope(
this,
2560 bool ShouldCapture =
2563 Actions.ActOnCapturedRegionStart(Tok.getLocation(),
getCurScope(),
2567 if (Tok.
is(tok::l_brace))
2568 FinallyBody = ParseCompoundStatementBody();
2570 Diag(Tok, diag::err_expected) << tok::l_brace;
2572 if (FinallyBody.isInvalid()) {
2573 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
2575 Actions.ActOnCapturedRegionError();
2576 }
else if (ShouldCapture) {
2577 FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get());
2580 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
2582 catch_or_finally_seen =
true;
2586 if (!catch_or_finally_seen) {
2587 Diag(atLoc, diag::err_missing_catch_finally);
2591 return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(),
2602 if (Tok.
isNot(tok::l_brace)) {
2603 Diag(Tok, diag::err_expected) << tok::l_brace;
2610 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2613 if (AutoreleasePoolBody.isInvalid())
2614 AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
2615 return Actions.ActOnObjCAutoreleasePoolStmt(atLoc,
2616 AutoreleasePoolBody.get());
2621 void Parser::StashAwayMethodOrFunctionBodyTokens(
Decl *MDecl) {
2622 if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
2623 trySkippingFunctionBody()) {
2624 Actions.ActOnSkippedFunctionBody(MDecl);
2628 LexedMethod* LM =
new LexedMethod(
this, MDecl);
2629 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2632 Toks.push_back(Tok);
2633 if (Tok.
is(tok::kw_try)) {
2635 if (Tok.
is(tok::colon)) {
2636 Toks.push_back(Tok);
2638 while (Tok.
isNot(tok::l_brace)) {
2639 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2640 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2643 Toks.push_back(Tok);
2645 else if (Tok.
is(tok::colon)) {
2648 while (Tok.
isNot(tok::l_brace)) {
2649 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2650 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2652 Toks.push_back(Tok);
2656 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2657 while (Tok.
is(tok::kw_catch)) {
2658 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
2659 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2665 Decl *Parser::ParseObjCMethodDefinition() {
2666 Decl *MDecl = ParseObjCMethodPrototype();
2669 "parsing Objective-C method");
2672 if (Tok.
is(tok::semi)) {
2673 if (CurParsedObjCImpl) {
2674 Diag(Tok, diag::warn_semicolon_before_method_body)
2681 if (Tok.
isNot(tok::l_brace)) {
2682 Diag(Tok, diag::err_expected_method_body);
2688 if (Tok.
isNot(tok::l_brace))
2699 Actions.AddAnyMethodToGlobalPool(MDecl);
2700 assert (CurParsedObjCImpl
2701 &&
"ParseObjCMethodDefinition - Method out of @implementation");
2703 StashAwayMethodOrFunctionBodyTokens(MDecl);
2708 if (Tok.
is(tok::code_completion)) {
2709 Actions.CodeCompleteObjCAtStatement(
getCurScope());
2715 return ParseObjCTryStmt(AtLoc);
2718 return ParseObjCThrowStmt(AtLoc);
2721 return ParseObjCSynchronizedStmt(AtLoc);
2724 return ParseObjCAutoreleasePoolStmt(AtLoc);
2729 return Actions.ActOnNullStmt(Tok.getLocation());
2732 ExprStatementTokLoc = AtLoc;
2733 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2743 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2744 return Actions.ActOnExprStmt(Res);
2748 switch (Tok.getKind()) {
2749 case tok::code_completion:
2750 Actions.CodeCompleteObjCAtExpression(
getCurScope());
2759 if (!Tok.
is(tok::numeric_constant)) {
2760 const char *Symbol =
nullptr;
2762 case tok::minus: Symbol =
"-";
break;
2763 case tok::plus: Symbol =
"+";
break;
2764 default: llvm_unreachable(
"missing unary operator case");
2766 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2771 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2772 if (Lit.isInvalid()) {
2777 Lit = Actions.ActOnUnaryOp(
getCurScope(), OpLoc, Kind, Lit.get());
2778 if (Lit.isInvalid())
2781 return ParsePostfixExpressionSuffix(
2782 Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()));
2785 case tok::string_literal:
2786 case tok::wide_string_literal:
2787 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2789 case tok::char_constant:
2790 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2792 case tok::numeric_constant:
2793 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2796 case tok::kw___objc_yes:
2797 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
true));
2799 case tok::kw___objc_no:
2800 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
false));
2804 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2808 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2812 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2815 if (Tok.getIdentifierInfo() ==
nullptr)
2818 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
2819 case tok::objc_encode:
2820 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2821 case tok::objc_protocol:
2822 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2823 case tok::objc_selector:
2824 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2825 case tok::objc_available:
2826 return ParseAvailabilityCheckExpr(AtLoc);
2828 const char *
str =
nullptr;
2832 if (GetLookAheadToken(1).is(tok::l_brace) &&
2833 ExprStatementTokLoc == AtLoc) {
2834 char ch = Tok.getIdentifierInfo()->getNameStart()[0];
2837 : (ch ==
'f' ?
"finally" 2838 : (ch ==
'a' ?
"autoreleasepool" :
nullptr));
2874 bool Parser::ParseObjCXXMessageReceiver(
bool &IsExpr,
void *&TypeOrExpr) {
2877 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2878 tok::annot_cxxscope))
2881 if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
2892 TypeOrExpr = Receiver.
get();
2901 ParseCXXSimpleTypeSpecifier(DS);
2903 if (Tok.
is(tok::l_paren)) {
2916 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2918 Receiver = ParsePostfixExpressionSuffix(Receiver.
get());
2920 Receiver = ParseRHSOfBinaryExpression(Receiver.
get(),
prec::Comma);
2925 TypeOrExpr = Receiver.
get();
2938 TypeOrExpr = Type.
get().getAsOpaquePtr();
2947 bool Parser::isSimpleObjCMessageExpression() {
2949 "Incorrect start for isSimpleObjCMessageExpression");
2950 return GetLookAheadToken(1).is(tok::identifier) &&
2951 GetLookAheadToken(2).is(tok::identifier);
2954 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2956 InMessageExpression)
2961 if (Tok.
is(tok::annot_typename))
2963 else if (Tok.
is(tok::identifier))
2964 Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(),
2969 if (!Type.
get().isNull() && Type.
get()->isObjCObjectOrInterfaceType()) {
2970 const Token &AfterNext = GetLookAheadToken(2);
2971 if (AfterNext.
isOneOf(tok::colon, tok::r_square)) {
2972 if (Tok.
is(tok::identifier))
2975 return Tok.
is(tok::annot_typename);
2991 ExprResult Parser::ParseObjCMessageExpression() {
2992 assert(Tok.
is(tok::l_square) &&
"'[' expected");
2995 if (Tok.
is(tok::code_completion)) {
2996 Actions.CodeCompleteObjCMessageReceiver(
getCurScope());
3010 if (Tok.
is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
3012 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3017 void *TypeOrExpr =
nullptr;
3018 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
3024 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3025 static_cast<Expr *>(TypeOrExpr));
3027 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3032 if (Tok.
is(tok::identifier)) {
3036 switch (Actions.getObjCMessageKind(
getCurScope(), Name, NameLoc,
3037 Name == Ident_super,
3041 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3045 if (!ReceiverType) {
3053 if (Tok.
is(tok::less)) {
3056 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3064 ReceiverType = NewReceiverType.
get();
3067 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3068 ReceiverType,
nullptr);
3083 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3129 Expr *ReceiverExpr) {
3132 if (Tok.
is(tok::code_completion)) {
3136 else if (ReceiverType)
3137 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
None,
3140 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3152 ExprVector KeyExprs;
3154 if (Tok.
is(tok::colon)) {
3157 KeyIdents.push_back(selIdent);
3158 KeyLocs.push_back(Loc);
3160 if (ExpectAndConsume(tok::colon)) {
3170 if (Tok.
is(tok::code_completion)) {
3172 Actions.CodeCompleteObjCSuperMessage(
getCurScope(), SuperLoc,
3175 else if (ReceiverType)
3176 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
3180 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3190 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3191 Expr = ParseBraceInitializer();
3205 KeyExprs.push_back(Res.
get());
3208 if (Tok.
is(tok::code_completion)) {
3210 Actions.CodeCompleteObjCSuperMessage(
getCurScope(), SuperLoc,
3213 else if (ReceiverType)
3214 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
3218 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3226 selIdent = ParseObjCSelectorPiece(Loc);
3227 if (!selIdent && Tok.
isNot(tok::colon))
3232 while (Tok.
is(tok::comma)) {
3236 if (Tok.
is(tok::colon))
3237 Res = Actions.CorrectDelayedTyposInExpr(Res);
3239 if (Tok.
is(tok::colon)) {
3240 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3251 KeyExprs.push_back(Res.
get());
3253 }
else if (!selIdent) {
3254 Diag(Tok, diag::err_expected) << tok::identifier;
3263 if (Tok.
isNot(tok::r_square)) {
3264 Diag(Tok, diag::err_expected)
3265 << (Tok.
is(tok::identifier) ? tok::colon : tok::r_square);
3275 unsigned nKeys = KeyIdents.size();
3277 KeyIdents.push_back(selIdent);
3278 KeyLocs.push_back(Loc);
3280 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
3283 return Actions.ActOnSuperMessage(
getCurScope(), SuperLoc, Sel,
3284 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3285 else if (ReceiverType)
3286 return Actions.ActOnClassMessage(
getCurScope(), ReceiverType, Sel,
3287 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3288 return Actions.ActOnInstanceMessage(
getCurScope(), ReceiverExpr, Sel,
3289 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3293 ExprResult Res(ParseStringLiteralExpression());
3300 ExprVector AtStrings;
3301 AtLocs.push_back(AtLoc);
3302 AtStrings.push_back(Res.
get());
3304 while (Tok.
is(tok::at)) {
3308 if (!isTokenStringLiteral())
3311 ExprResult Lit(ParseStringLiteralExpression());
3315 AtStrings.push_back(Lit.
get());
3318 return Actions.ParseObjCStringLiteral(AtLocs.data(), AtStrings);
3329 return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
3336 ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
3337 if (Lit.isInvalid()) {
3341 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3350 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
3351 if (Lit.isInvalid()) {
3355 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3363 if (Tok.
isNot(tok::l_paren))
3364 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@");
3378 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.
get());
3379 return Actions.BuildObjCBoxedExpr(
SourceRange(AtLoc, RPLoc),
3384 ExprVector ElementExprs;
3387 bool HasInvalidEltExpr =
false;
3388 while (Tok.
isNot(tok::r_square)) {
3399 Res = Actions.CorrectDelayedTyposInExpr(Res.
get());
3401 HasInvalidEltExpr =
true;
3404 if (Tok.
is(tok::ellipsis))
3407 HasInvalidEltExpr =
true;
3409 ElementExprs.push_back(Res.
get());
3411 if (Tok.
is(tok::comma))
3413 else if (Tok.
isNot(tok::r_square))
3414 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_square
3419 if (HasInvalidEltExpr)
3423 return Actions.BuildObjCArrayLiteral(
SourceRange(AtLoc, EndLoc), Args);
3429 bool HasInvalidEltExpr =
false;
3430 while (Tok.
isNot(tok::r_brace)) {
3445 if (ExpectAndConsume(tok::colon)) {
3460 KeyExpr = Actions.CorrectDelayedTyposInExpr(KeyExpr.
get());
3461 ValueExpr = Actions.CorrectDelayedTyposInExpr(ValueExpr.
get());
3463 HasInvalidEltExpr =
true;
3475 KeyExpr.
get(), ValueExpr.
get(), EllipsisLoc,
None 3477 Elements.push_back(Element);
3480 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_brace
3485 if (HasInvalidEltExpr)
3489 return Actions.BuildObjCDictionaryLiteral(
SourceRange(AtLoc, EndLoc),
3497 assert(Tok.
isObjCAtKeyword(tok::objc_encode) &&
"Not an @encode expression!");
3501 if (Tok.
isNot(tok::l_paren))
3502 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@encode");
3514 return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.
getOpenLocation(),
3524 if (Tok.
isNot(tok::l_paren))
3525 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@protocol");
3530 if (expectIdentifier())
3538 return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
3548 if (Tok.
isNot(tok::l_paren))
3549 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@selector");
3556 bool HasOptionalParen = Tok.
is(tok::l_paren);
3557 if (HasOptionalParen)
3560 if (Tok.
is(tok::code_completion)) {
3561 Actions.CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3568 Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3569 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3571 KeyIdents.push_back(SelIdent);
3573 unsigned nColons = 0;
3574 if (Tok.
isNot(tok::r_paren)) {
3578 KeyIdents.push_back(
nullptr);
3579 }
else if (ExpectAndConsume(tok::colon))
3583 if (Tok.
is(tok::r_paren))
3586 if (Tok.
is(tok::code_completion)) {
3587 Actions.CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3594 SelIdent = ParseObjCSelectorPiece(Loc);
3595 KeyIdents.push_back(SelIdent);
3596 if (!SelIdent && Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3600 if (HasOptionalParen && Tok.
is(tok::r_paren))
3603 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
3604 return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
3610 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM,
bool parseMethod) {
3612 Decl *MCDecl = LM.D;
3613 bool skip = MCDecl &&
3614 ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
3615 (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
3622 assert(!LM.Toks.empty() &&
"ParseLexedObjCMethodDef - Empty body!");
3628 Eof.setEofData(MCDecl);
3629 Eof.setLocation(OrigLoc);
3630 LM.Toks.push_back(Eof);
3633 LM.Toks.push_back(Tok);
3634 PP.EnterTokenStream(LM.Toks,
true);
3639 assert(Tok.
isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3640 "Inline objective-c method not starting with '{' or 'try' or ':'");
3649 Actions.ActOnStartOfObjCMethodDef(
getCurScope(), MCDecl);
3651 Actions.ActOnStartOfFunctionDef(
getCurScope(), MCDecl);
3652 if (Tok.
is(tok::kw_try))
3653 ParseFunctionTryBlock(MCDecl, BodyScope);
3655 if (Tok.
is(tok::colon))
3656 ParseConstructorInitializer(MCDecl);
3658 Actions.ActOnDefaultCtorInitializers(MCDecl);
3659 ParseFunctionStatementBody(MCDecl, BodyScope);
3662 if (Tok.getLocation() != OrigLoc) {
3668 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.
SourceLocation getBeginLoc() const LLVM_READONLY
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...
void addAtEnd(ParsedAttr *newAttr)
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.
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.
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.