21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/ADT/StringExtras.h" 24 using namespace clang;
29 if (Tok.
is(tok::kw___attribute)) {
30 if (Kind == tok::objc_interface || Kind == tok::objc_protocol)
31 Diag(Tok, diag::err_objc_postfix_attribute_hint)
32 << (Kind == tok::objc_protocol);
34 Diag(Tok, diag::err_objc_postfix_attribute);
35 ParseGNUAttributes(attrs);
48 Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &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:
81 SingleDecl = ParseModuleImport(AtLoc);
84 Diag(AtLoc, diag::err_atimport);
88 Diag(AtLoc, diag::err_unexpected_at);
104 : Actions(Actions), S(S), Params(nullptr) {}
137 MaybeSkipAttributes(tok::objc_class);
138 if (expectIdentifier()) {
140 return Actions.ConvertDeclToDeclGroup(
nullptr);
142 ClassNames.push_back(Tok.getIdentifierInfo());
143 ClassLocs.push_back(Tok.getLocation());
148 if (Tok.
is(tok::less))
149 TypeParams = parseObjCTypeParamList();
150 ClassTypeParams.push_back(TypeParams);
156 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@class"))
157 return Actions.ConvertDeclToDeclGroup(
nullptr);
159 return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
171 Decl *
Decl = Actions.getObjCDeclContext();
172 if (CurParsedObjCImpl) {
173 CurParsedObjCImpl->finish(AtLoc);
177 Diag(AtLoc, diag::err_objc_missing_end)
180 Diag(Decl->
getBeginLoc(), diag::note_objc_container_start) << (
int)ock;
215 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
216 CheckNestedObjCContexts(AtLoc);
220 if (Tok.
is(tok::code_completion)) {
221 Actions.CodeCompleteObjCInterfaceDecl(
getCurScope());
226 MaybeSkipAttributes(tok::objc_interface);
228 if (expectIdentifier())
242 if (Tok.
is(tok::less))
243 typeParameterList = parseObjCTypeParamListOrProtocolRefs(
244 typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
246 if (Tok.
is(tok::l_paren) &&
247 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
254 if (Tok.
is(tok::code_completion)) {
255 Actions.CodeCompleteObjCInterfaceCategory(
getCurScope(), nameId, nameLoc);
261 if (Tok.
is(tok::identifier)) {
262 categoryId = Tok.getIdentifierInfo();
266 Diag(Tok, diag::err_expected)
276 assert(LAngleLoc.
isInvalid() &&
"Cannot have already parsed protocols");
279 if (Tok.
is(tok::less) &&
280 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
true,
true,
281 LAngleLoc, EndProtoLoc,
285 Decl *CategoryType = Actions.ActOnStartCategoryInterface(
286 AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
287 ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
290 if (Tok.
is(tok::l_brace))
291 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
293 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
305 if (Tok.
is(tok::colon)) {
309 if (Tok.
is(tok::code_completion)) {
310 Actions.CodeCompleteObjCSuperclass(
getCurScope(), nameId, nameLoc);
315 if (expectIdentifier())
317 superClassId = Tok.getIdentifierInfo();
321 if (Tok.
is(tok::less)) {
322 parseObjCTypeArgsOrProtocolQualifiers(
323 nullptr, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, LAngleLoc,
324 protocols, protocolLocs, EndProtoLoc,
334 if (!ProtocolIdents.empty()) {
337 for (
const auto &pair : ProtocolIdents) {
338 protocolLocs.push_back(pair.second);
340 Actions.FindProtocolDeclaration(
true,
342 ProtocolIdents, protocols);
344 }
else if (protocols.empty() && Tok.
is(tok::less) &&
345 ParseObjCProtocolReferences(protocols, protocolLocs,
true,
true,
346 LAngleLoc, EndProtoLoc,
351 if (Tok.
isNot(tok::less))
352 Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
353 superClassId, superClassLoc);
355 Decl *ClsType = Actions.ActOnStartClassInterface(
356 getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
357 superClassLoc, typeArgs,
358 SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(),
359 protocols.size(), protocolLocs.data(), EndProtoLoc, attrs);
361 if (Tok.
is(tok::l_brace))
362 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
364 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
375 bool &addedToDeclSpec) {
387 }
else if (!addedToDeclSpec) {
392 addedToDeclSpec =
true;
424 assert(Tok.
is(tok::less) &&
"Not at the beginning of a type parameter list");
432 auto makeProtocolIdentsIntoTypeParameters = [&]() {
434 for (
const auto &pair : protocolIdents) {
435 DeclResult typeParam = Actions.actOnObjCTypeParam(
439 typeParams.push_back(typeParam.
get());
442 protocolIdents.clear();
443 mayBeProtocolList =
false;
446 bool invalid =
false;
453 if (Tok.
is(tok::kw___covariant) || Tok.
is(tok::kw___contravariant)) {
454 variance = Tok.
is(tok::kw___covariant)
461 if (mayBeProtocolList) {
464 makeProtocolIdentsIntoTypeParameters();
469 if (!Tok.
is(tok::identifier)) {
471 if (Tok.
is(tok::code_completion)) {
474 Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
481 Diag(Tok, diag::err_objc_expected_type_parameter);
495 if (mayBeProtocolList) {
498 makeProtocolIdentsIntoTypeParameters();
505 }
else if (mayBeProtocolList) {
508 protocolIdents.push_back(std::make_pair(paramName, paramLoc));
513 DeclResult typeParam = Actions.actOnObjCTypeParam(
514 getCurScope(), variance, varianceLoc, typeParams.size(), paramName,
515 paramLoc, colonLoc, boundType.
isUsable() ? boundType.
get() :
nullptr);
517 typeParams.push_back(typeParam.
get());
523 if (Tok.
is(tok::greater))
525 }
else if (ParseGreaterThanInTemplateList(rAngleLoc,
528 Diag(lAngleLoc, diag::note_matching) <<
"'<'";
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;
575 ObjCTypeParamListScope Scope(Actions,
getCurScope());
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);
619 ParseObjCMethodDecl(Tok.getLocation(),
621 MethodImplKind,
false);
625 if (Tok.
is(tok::semi)) {
637 if (Tok.
is(tok::code_completion)) {
641 return cutOffParsing();
645 if (Tok.
isNot(tok::at)) {
649 if (Tok.
is(tok::r_brace))
652 ParsedAttributesWithRange attrs(AttrFactory);
657 if (Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
659 allTUVariables.push_back(
664 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
670 if (Tok.
is(tok::code_completion)) {
671 Actions.CodeCompleteObjCAtDirective(
getCurScope());
672 return cutOffParsing();
677 if (DirectiveKind == tok::objc_end) {
679 AtEnd.
setEnd(Tok.getLocation());
681 }
else if (DirectiveKind == tok::objc_not_keyword) {
682 Diag(Tok, diag::err_objc_unknown_at);
690 switch (DirectiveKind) {
696 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
701 case tok::objc_implementation:
702 case tok::objc_interface:
703 Diag(AtLoc, diag::err_objc_missing_end)
706 << (
int)Actions.getObjCContainerKind();
710 case tok::objc_required:
711 case tok::objc_optional:
713 if (contextKey != tok::objc_protocol)
714 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
716 MethodImplKind = DirectiveKind;
719 case tok::objc_property:
723 if (Tok.
is(tok::l_paren)) {
724 LParenLoc = Tok.getLocation();
725 ParseObjCPropertyAttribute(OCDS);
728 bool addedToDeclSpec =
false;
730 if (FD.D.getIdentifier() ==
nullptr) {
731 Diag(AtLoc, diag::err_objc_property_requires_field_name)
732 << FD.D.getSourceRange();
735 if (FD.BitfieldSize) {
736 Diag(AtLoc, diag::err_objc_property_bitfield)
737 << FD.D.getSourceRange();
752 Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName);
756 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
759 PP.getIdentifierTable(), PP.getSelectorTable(),
760 FD.D.getIdentifier());
762 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
765 FD.complete(Property);
770 ParseStructDeclaration(DS, ObjCPropertyCallback);
772 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
779 if (Tok.
is(tok::code_completion)) {
780 Actions.CodeCompleteObjCAtDirective(
getCurScope());
781 return cutOffParsing();
785 Diag(Tok, diag::err_objc_missing_end)
788 << (
int)Actions.getObjCContainerKind();
790 AtEnd.
setEnd(Tok.getLocation());
795 Actions.ActOnAtEnd(
getCurScope(), AtEnd, allMethods, allTUVariables);
804 P.
Diag(nullabilityLoc, diag::warn_nullability_duplicate)
810 P.
Diag(nullabilityLoc, diag::err_nullability_conflicting)
842 void Parser::ParseObjCPropertyAttribute(
ObjCDeclSpec &DS) {
843 assert(Tok.getKind() == tok::l_paren);
848 if (Tok.
is(tok::code_completion)) {
849 Actions.CodeCompleteObjCPropertyFlags(
getCurScope(), DS);
850 return cutOffParsing();
862 if (II->
isStr(
"readonly"))
864 else if (II->
isStr(
"assign"))
866 else if (II->
isStr(
"unsafe_unretained"))
868 else if (II->
isStr(
"readwrite"))
870 else if (II->
isStr(
"retain"))
872 else if (II->
isStr(
"strong"))
874 else if (II->
isStr(
"copy"))
876 else if (II->
isStr(
"nonatomic"))
878 else if (II->
isStr(
"atomic"))
880 else if (II->
isStr(
"weak"))
882 else if (II->
isStr(
"getter") || II->
isStr(
"setter")) {
886 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
887 diag::err_objc_expected_equal_for_getter;
889 if (ExpectAndConsume(tok::equal, DiagID)) {
894 if (Tok.
is(tok::code_completion)) {
896 Actions.CodeCompleteObjCPropertySetter(
getCurScope());
898 Actions.CodeCompleteObjCPropertyGetter(
getCurScope());
899 return cutOffParsing();
906 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
916 if (ExpectAndConsume(tok::colon,
917 diag::err_expected_colon_after_setter_name)) {
925 }
else if (II->
isStr(
"nonnull")) {
932 }
else if (II->
isStr(
"nullable")) {
939 }
else if (II->
isStr(
"null_unspecified")) {
946 }
else if (II->
isStr(
"null_resettable")) {
956 }
else if (II->
isStr(
"class")) {
958 }
else if (II->
isStr(
"direct")) {
961 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
966 if (Tok.
isNot(tok::comma))
986 bool MethodDefinition) {
987 assert(Tok.
isOneOf(tok::minus, tok::plus) &&
"expected +/-");
991 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
1008 switch (Tok.getKind()) {
1013 SelectorLoc = Tok.getLocation();
1021 case tok::exclaimequal:
1023 case tok::pipeequal:
1025 case tok::caretequal: {
1026 std::string ThisTok(PP.getSpelling(Tok));
1029 Tok.setKind(tok::identifier);
1036 case tok::identifier:
1046 case tok::kw_const_cast:
1047 case tok::kw_continue:
1048 case tok::kw_default:
1049 case tok::kw_delete:
1051 case tok::kw_double:
1052 case tok::kw_dynamic_cast:
1055 case tok::kw_explicit:
1056 case tok::kw_export:
1057 case tok::kw_extern:
1061 case tok::kw_friend:
1064 case tok::kw_inline:
1067 case tok::kw_mutable:
1068 case tok::kw_namespace:
1070 case tok::kw_operator:
1071 case tok::kw_private:
1072 case tok::kw_protected:
1073 case tok::kw_public:
1074 case tok::kw_register:
1075 case tok::kw_reinterpret_cast:
1076 case tok::kw_restrict:
1077 case tok::kw_return:
1079 case tok::kw_signed:
1080 case tok::kw_sizeof:
1081 case tok::kw_static:
1082 case tok::kw_static_cast:
1083 case tok::kw_struct:
1084 case tok::kw_switch:
1085 case tok::kw_template:
1090 case tok::kw_typedef:
1091 case tok::kw_typeid:
1092 case tok::kw_typename:
1093 case tok::kw_typeof:
1095 case tok::kw_unsigned:
1097 case tok::kw_virtual:
1099 case tok::kw_volatile:
1100 case tok::kw_wchar_t:
1103 case tok::kw__Complex:
1104 case tok::kw___alignof:
1105 case tok::kw___auto_type:
1114 bool Parser::isTokIdentifier_in()
const {
1119 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
1141 void Parser::ParseObjCTypeQualifierList(
ObjCDeclSpec &DS,
1147 if (Tok.
is(tok::code_completion)) {
1148 Actions.CodeCompleteObjCPassingType(
getCurScope(), DS,
1150 return cutOffParsing();
1153 if (Tok.
isNot(tok::identifier))
1157 for (
unsigned i = 0; i != objc_NumQuals; ++i) {
1158 if (II != ObjCTypeQuals[i] ||
1166 default: llvm_unreachable(
"Unknown decl qualifier");
1184 case objc_null_unspecified:
1209 for (
auto &AL : llvm::reverse(from)) {
1210 if (!AL.isUsedAsTypeAttr()) {
1241 assert((paramAttrs !=
nullptr) ==
1244 assert(Tok.
is(tok::l_paren) &&
"expected (");
1252 ParseObjCTypeQualifierList(DS, context);
1256 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1260 DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
1262 dsContext = DeclSpecContext::DSC_objc_method_result;
1263 ParseSpecifierQualifierList(declSpec,
AS_none, dsContext);
1265 ParseDeclarator(declarator);
1270 bool addedToDeclSpec =
false;
1288 if (Tok.
is(tok::r_paren))
1290 else if (Tok.getLocation() == TypeStartLoc) {
1292 Diag(Tok, diag::err_expected_type);
1333 bool MethodDefinition) {
1336 if (Tok.
is(tok::code_completion)) {
1337 Actions.CodeCompleteObjCMethodDecl(
getCurScope(), mType == tok::minus,
1346 if (Tok.
is(tok::l_paren))
1353 MaybeParseGNUAttributes(methodAttrs);
1354 MaybeParseCXX11Attributes(methodAttrs);
1356 if (Tok.
is(tok::code_completion)) {
1357 Actions.CodeCompleteObjCMethodDecl(
getCurScope(), mType == tok::minus,
1368 if (!SelIdent && Tok.
isNot(tok::colon)) {
1369 Diag(Tok, diag::err_expected_selector_for_method)
1377 if (Tok.
isNot(tok::colon)) {
1380 MaybeParseGNUAttributes(methodAttrs);
1381 MaybeParseCXX11Attributes(methodAttrs);
1383 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
1384 Decl *
Result = Actions.ActOnMethodDeclaration(
1385 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType,
1386 selLoc, Sel,
nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
1387 MethodImplKind,
false, MethodDefinition);
1404 if (ExpectAndConsume(tok::colon))
1407 ArgInfo.
Type =
nullptr;
1408 if (Tok.
is(tok::l_paren))
1416 MaybeParseGNUAttributes(paramAttrs);
1417 MaybeParseCXX11Attributes(paramAttrs);
1421 if (Tok.
is(tok::code_completion)) {
1422 KeyIdents.push_back(SelIdent);
1423 Actions.CodeCompleteObjCMethodDeclSelector(
getCurScope(),
1424 mType == tok::minus,
1426 ReturnType, KeyIdents);
1431 if (expectIdentifier())
1434 ArgInfo.
Name = Tok.getIdentifierInfo();
1435 ArgInfo.
NameLoc = Tok.getLocation();
1438 ArgInfos.push_back(ArgInfo);
1439 KeyIdents.push_back(SelIdent);
1440 KeyLocs.push_back(selLoc);
1446 if (Tok.
is(tok::code_completion)) {
1447 Actions.CodeCompleteObjCMethodDeclSelector(
getCurScope(),
1448 mType == tok::minus,
1450 ReturnType, KeyIdents);
1456 SelIdent = ParseObjCSelectorPiece(selLoc);
1457 if (!SelIdent && Tok.
isNot(tok::colon))
1462 Diag(ArgInfo.
NameLoc, diag::warn_missing_selector_name) << ArgInfo.
Name;
1463 Diag(ArgInfo.
NameLoc, diag::note_missing_selector_name) << ArgInfo.
Name;
1464 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.
Name;
1470 bool isVariadic =
false;
1471 bool cStyleParamWarned =
false;
1473 while (Tok.
is(tok::comma)) {
1475 if (Tok.
is(tok::ellipsis)) {
1480 if (!cStyleParamWarned) {
1481 Diag(Tok, diag::warn_cstyle_param);
1482 cStyleParamWarned =
true;
1485 ParseDeclarationSpecifiers(DS);
1488 ParseDeclarator(ParmDecl);
1500 MaybeParseGNUAttributes(methodAttrs);
1501 MaybeParseCXX11Attributes(methodAttrs);
1503 if (KeyIdents.size() == 0)
1506 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
1508 Decl *
Result = Actions.ActOnMethodDeclaration(
1509 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
1510 Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
1511 MethodImplKind, isVariadic, MethodDefinition);
1523 bool WarnOnDeclarations,
bool ForObjCContainer,
1525 bool consumeLastToken) {
1526 assert(Tok.
is(tok::less) &&
"expected <");
1533 if (Tok.
is(tok::code_completion)) {
1534 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
1539 if (expectIdentifier()) {
1543 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
1544 Tok.getLocation()));
1545 ProtocolLocs.push_back(Tok.getLocation());
1553 if (ParseGreaterThanInTemplateList(EndLoc, consumeLastToken,
1558 Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer,
1559 ProtocolIdents, Protocols);
1564 assert(Tok.
is(tok::less) &&
"Protocol qualifiers start with '<'");
1565 assert(
getLangOpts().
ObjC &&
"Protocol qualifiers only exist in Objective-C");
1570 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
false,
false,
1571 lAngleLoc, rAngleLoc,
1573 TypeResult result = Actions.actOnObjCProtocolQualifierType(lAngleLoc,
1578 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1591 void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1600 bool consumeLastToken,
1601 bool warnOnIncompleteProtocols) {
1602 assert(Tok.
is(tok::less) &&
"Not at the start of type args or protocols");
1607 bool allSingleIdentifiers =
true;
1615 if (Tok.
is(tok::identifier) &&
1619 identifiers.push_back(Tok.getIdentifierInfo());
1624 if (Tok.
is(tok::code_completion)) {
1627 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1629 identifierLocs[i]));
1632 QualType BaseT = Actions.GetTypeFromParser(baseType);
1636 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
1642 allSingleIdentifiers =
false;
1648 if (allSingleIdentifiers) {
1651 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1655 Actions.actOnObjCTypeArgsOrProtocolQualifiers(
getCurScope(),
1667 warnOnIncompleteProtocols);
1677 bool invalid =
false;
1678 IdentifierInfo *foundProtocolId =
nullptr, *foundValidTypeId =
nullptr;
1683 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1685 = Actions.getTypeName(*identifiers[i], identifierLocs[i],
getCurScope());
1688 const char *prevSpec =
nullptr;
1691 typeArg, Actions.getASTContext().getPrintingPolicy());
1697 typeArgs.push_back(fullTypeArg.
get());
1698 if (!foundValidTypeId) {
1699 foundValidTypeId = identifiers[i];
1700 foundValidTypeSrcLoc = identifierLocs[i];
1704 unknownTypeArgs.push_back(identifiers[i]);
1705 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1709 if (!Actions.LookupProtocol(identifiers[i], identifierLocs[i])) {
1710 unknownTypeArgs.push_back(identifiers[i]);
1711 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1712 }
else if (!foundProtocolId) {
1713 foundProtocolId = identifiers[i];
1714 foundProtocolSrcLoc = identifierLocs[i];
1721 Token CurTypeTok = Tok;
1728 typeArg = Actions.ActOnPackExpansion(typeArg.
get(), ellipsisLoc);
1732 typeArgs.push_back(typeArg.
get());
1733 if (!foundValidTypeId) {
1743 if (foundProtocolId && foundValidTypeId)
1744 Actions.DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc,
1746 foundValidTypeSrcLoc);
1750 if (unknownTypeArgs.size())
1751 for (
unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1752 Actions.DiagnoseUnknownTypeName(unknownTypeArgs[i], unknownTypeArgsLoc[i],
1757 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1766 typeArgsLAngleLoc = lAngleLoc;
1767 typeArgsRAngleLoc = rAngleLoc;
1770 void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1779 bool consumeLastToken) {
1780 assert(Tok.
is(tok::less));
1783 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1799 if ((consumeLastToken && Tok.
is(tok::less)) ||
1800 (!consumeLastToken &&
NextToken().
is(tok::less))) {
1803 if (!consumeLastToken)
1806 if (!protocols.empty()) {
1808 if (!consumeLastToken)
1810 Diag(Tok, diag::err_objc_type_args_after_protocols)
1811 <<
SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1812 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1814 ParseObjCProtocolReferences(protocols, protocolLocs,
1817 protocolLAngleLoc, protocolRAngleLoc,
1823 TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1826 bool consumeLastToken,
1828 assert(Tok.
is(tok::less));
1838 parseObjCTypeArgsAndProtocolQualifiers(type, typeArgsLAngleLoc, typeArgs,
1839 typeArgsRAngleLoc, protocolLAngleLoc,
1840 protocols, protocolLocs,
1841 protocolRAngleLoc, consumeLastToken);
1847 if (consumeLastToken)
1848 endLoc = PrevTokLocation;
1850 endLoc = Tok.getLocation();
1852 return Actions.actOnObjCTypeArgsAndProtocolQualifiers(
1865 void Parser::HelperActionsForIvarDeclarations(
Decl *interfaceDecl,
SourceLocation atLoc,
1868 bool RBraceMissing) {
1872 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1874 Actions.ActOnObjCContainerFinishDefinition();
1877 Actions.ActOnFields(
getCurScope(), atLoc, interfaceDecl, AllIvarDecls,
1903 void Parser::ParseObjCClassInstanceVariables(
Decl *interfaceDecl,
1906 assert(Tok.
is(tok::l_brace) &&
"expected {");
1915 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
1919 if (Tok.
is(tok::semi)) {
1920 ConsumeExtraSemi(InstanceVariableList);
1926 if (Tok.
is(tok::code_completion)) {
1927 Actions.CodeCompleteObjCAtVisibility(
getCurScope());
1928 return cutOffParsing();
1931 switch (Tok.getObjCKeywordID()) {
1932 case tok::objc_private:
1933 case tok::objc_public:
1934 case tok::objc_protected:
1935 case tok::objc_package:
1936 visibility = Tok.getObjCKeywordID();
1941 Diag(Tok, diag::err_objc_unexpected_atend);
1942 Tok.setLocation(Tok.getLocation().getLocWithOffset(-1));
1943 Tok.setKind(tok::at);
1945 PP.EnterToken(Tok,
true);
1946 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1947 T, AllIvarDecls,
true);
1951 Diag(Tok, diag::err_objc_illegal_visibility_spec);
1956 if (Tok.
is(tok::code_completion)) {
1959 return cutOffParsing();
1965 if (Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
1967 ParseStaticAssertDeclaration(DeclEnd);
1972 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1974 FD.D.setObjCIvar(
true);
1975 Decl *Field = Actions.ActOnIvar(
1976 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
1977 FD.BitfieldSize, visibility);
1978 Actions.ActOnObjCContainerFinishDefinition();
1980 AllIvarDecls.push_back(Field);
1986 ParseStructDeclaration(DS, ObjCIvarCallback);
1988 if (Tok.
is(tok::semi)) {
1991 Diag(Tok, diag::err_expected_semi_decl_list);
1996 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1997 T, AllIvarDecls,
false);
2020 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2023 if (Tok.
is(tok::code_completion)) {
2024 Actions.CodeCompleteObjCProtocolDecl(
getCurScope());
2029 MaybeSkipAttributes(tok::objc_protocol);
2031 if (expectIdentifier())
2039 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs);
2042 CheckNestedObjCContexts(AtLoc);
2044 if (Tok.
is(tok::comma)) {
2046 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2051 if (expectIdentifier()) {
2056 Tok.getLocation()));
2059 if (Tok.
isNot(tok::comma))
2063 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@protocol"))
2066 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs);
2074 if (Tok.
is(tok::less) &&
2075 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
false,
true,
2076 LAngleLoc, EndProtoLoc,
2080 Decl *ProtoType = Actions.ActOnStartProtocolInterface(
2081 AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
2082 ProtocolLocs.data(), EndProtoLoc, attrs);
2084 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2085 return Actions.ConvertDeclToDeclGroup(ProtoType);
2099 Parser::ParseObjCAtImplementationDeclaration(
SourceLocation AtLoc,
2102 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2103 CheckNestedObjCContexts(AtLoc);
2107 if (Tok.
is(tok::code_completion)) {
2108 Actions.CodeCompleteObjCImplementationDecl(
getCurScope());
2113 MaybeSkipAttributes(tok::objc_implementation);
2115 if (expectIdentifier())
2120 Decl *ObjCImpDecl =
nullptr;
2124 if (Tok.
is(tok::less)) {
2128 ObjCTypeParamListScope typeParamScope(Actions,
getCurScope());
2129 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
2130 protocolIdents, rAngleLoc)) {
2131 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2133 }
else if (lAngleLoc.
isValid()) {
2134 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2139 if (Tok.
is(tok::l_paren)) {
2145 if (Tok.
is(tok::code_completion)) {
2146 Actions.CodeCompleteObjCImplementationCategory(
getCurScope(), nameId, nameLoc);
2151 if (Tok.
is(tok::identifier)) {
2152 categoryId = Tok.getIdentifierInfo();
2155 Diag(Tok, diag::err_expected)
2159 if (Tok.
isNot(tok::r_paren)) {
2160 Diag(Tok, diag::err_expected) << tok::r_paren;
2164 rparenLoc = ConsumeParen();
2165 if (Tok.
is(tok::less)) {
2166 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2170 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2173 protocolLAngleLoc, protocolRAngleLoc,
2176 ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
2177 AtLoc, nameId, nameLoc, categoryId, categoryLoc, Attrs);
2185 if (expectIdentifier())
2187 superClassId = Tok.getIdentifierInfo();
2190 ObjCImpDecl = Actions.ActOnStartClassImplementation(
2191 AtLoc, nameId, nameLoc, superClassId, superClassLoc, Attrs);
2193 if (Tok.
is(tok::l_brace))
2194 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2195 else if (Tok.
is(tok::less)) {
2196 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2201 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2204 protocolLAngleLoc, protocolRAngleLoc,
2208 assert(ObjCImpDecl);
2213 ObjCImplParsingDataRAII ObjCImplParsing(*
this, ObjCImpDecl);
2214 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2215 ParsedAttributesWithRange attrs(AttrFactory);
2216 MaybeParseCXX11Attributes(attrs);
2219 DeclsInGroup.append(DG.
begin(), DG.
end());
2224 return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup);
2228 Parser::ParseObjCAtEndDeclaration(
SourceRange atEnd) {
2230 "ParseObjCAtEndDeclaration(): Expected @end");
2232 if (CurParsedObjCImpl)
2233 CurParsedObjCImpl->finish(atEnd);
2236 Diag(atEnd.
getBegin(), diag::err_expected_objc_container);
2240 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2242 finish(
P.Tok.getLocation());
2243 if (
P.isEofOrEom()) {
2244 P.Diag(
P.Tok, diag::err_objc_missing_end)
2246 P.Diag(Dcl->getBeginLoc(), diag::note_objc_container_start)
2250 P.CurParsedObjCImpl =
nullptr;
2251 assert(LateParsedObjCMethods.empty());
2254 void Parser::ObjCImplParsingDataRAII::finish(
SourceRange AtEnd) {
2256 P.Actions.DefaultSynthesizeProperties(
P.getCurScope(), Dcl, AtEnd.
getBegin());
2257 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2258 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2261 P.Actions.ActOnAtEnd(
P.getCurScope(), AtEnd);
2264 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2265 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2269 for (LateParsedObjCMethodContainer::iterator
2270 I = LateParsedObjCMethods.begin(),
2271 E = LateParsedObjCMethods.end(); I != E; ++I)
2273 LateParsedObjCMethods.clear();
2283 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2285 if (expectIdentifier())
2289 if (expectIdentifier())
2293 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@compatibility_alias");
2294 return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
2311 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2315 if (Tok.
is(tok::code_completion)) {
2316 Actions.CodeCompleteObjCPropertyDefinition(
getCurScope());
2321 if (Tok.
isNot(tok::identifier)) {
2322 Diag(Tok, diag::err_synthesized_property_name);
2333 if (Tok.
is(tok::code_completion)) {
2334 Actions.CodeCompleteObjCPropertySynthesizeIvar(
getCurScope(), propertyId);
2339 if (expectIdentifier())
2341 propertyIvar = Tok.getIdentifierInfo();
2344 Actions.ActOnPropertyImplDecl(
2346 propertyId, propertyIvar, propertyIvarLoc,
2348 if (Tok.
isNot(tok::comma))
2352 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@synthesize");
2365 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2368 bool isClassProperty =
false;
2369 if (Tok.
is(tok::l_paren)) {
2374 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2378 if (II->
isStr(
"class")) {
2379 isClassProperty =
true;
2380 if (Tok.
isNot(tok::r_paren)) {
2381 Diag(Tok, diag::err_expected) << tok::r_paren;
2386 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2393 if (Tok.
is(tok::code_completion)) {
2394 Actions.CodeCompleteObjCPropertyDefinition(
getCurScope());
2399 if (expectIdentifier()) {
2406 Actions.ActOnPropertyImplDecl(
2412 if (Tok.
isNot(tok::comma))
2416 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@dynamic");
2426 if (Tok.
isNot(tok::semi)) {
2434 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@throw");
2435 return Actions.ActOnObjCAtThrowStmt(atLoc, Res.
get(),
getCurScope());
2444 if (Tok.
isNot(tok::l_paren)) {
2445 Diag(Tok, diag::err_expected_lparen_after) <<
"@synchronized";
2453 if (Tok.
is(tok::r_paren)) {
2457 Diag(Tok, diag::err_expected) << tok::r_paren;
2464 if (Tok.
isNot(tok::l_brace)) {
2466 Diag(Tok, diag::err_expected) << tok::l_brace;
2472 operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.
get());
2476 StmtResult body(ParseCompoundStatementBody());
2484 if (body.isInvalid())
2485 body = Actions.ActOnNullStmt(Tok.getLocation());
2487 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.
get(), body.get());
2502 bool catch_or_finally_seen =
false;
2505 if (Tok.
isNot(tok::l_brace)) {
2506 Diag(Tok, diag::err_expected) << tok::l_brace;
2509 StmtVector CatchStmts;
2512 StmtResult TryBody(ParseCompoundStatementBody());
2514 if (TryBody.isInvalid())
2515 TryBody = Actions.ActOnNullStmt(Tok.getLocation());
2517 while (Tok.
is(tok::at)) {
2521 Token AfterAt = GetLookAheadToken(1);
2528 Decl *FirstPart =
nullptr;
2530 if (Tok.
is(tok::l_paren)) {
2535 if (Tok.
isNot(tok::ellipsis)) {
2537 ParseDeclarationSpecifiers(DS);
2539 ParseDeclarator(ParmDecl);
2543 FirstPart = Actions.ActOnObjCExceptionDecl(
getCurScope(), ParmDecl);
2549 if (Tok.
is(tok::r_paren))
2550 RParenLoc = ConsumeParen();
2555 if (Tok.
is(tok::l_brace))
2556 CatchBody = ParseCompoundStatementBody();
2558 Diag(Tok, diag::err_expected) << tok::l_brace;
2559 if (CatchBody.isInvalid())
2560 CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
2562 StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
2566 if (!Catch.isInvalid())
2567 CatchStmts.push_back(Catch.get());
2570 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2574 catch_or_finally_seen =
true;
2576 assert(Tok.
isObjCAtKeyword(tok::objc_finally) &&
"Lookahead confused?");
2578 ParseScope FinallyScope(
this,
2581 bool ShouldCapture =
2584 Actions.ActOnCapturedRegionStart(Tok.getLocation(),
getCurScope(),
2588 if (Tok.
is(tok::l_brace))
2589 FinallyBody = ParseCompoundStatementBody();
2591 Diag(Tok, diag::err_expected) << tok::l_brace;
2593 if (FinallyBody.isInvalid()) {
2594 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
2596 Actions.ActOnCapturedRegionError();
2597 }
else if (ShouldCapture) {
2598 FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get());
2601 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
2603 catch_or_finally_seen =
true;
2607 if (!catch_or_finally_seen) {
2608 Diag(atLoc, diag::err_missing_catch_finally);
2612 return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(),
2623 if (Tok.
isNot(tok::l_brace)) {
2624 Diag(Tok, diag::err_expected) << tok::l_brace;
2631 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2634 if (AutoreleasePoolBody.isInvalid())
2635 AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
2636 return Actions.ActOnObjCAutoreleasePoolStmt(atLoc,
2637 AutoreleasePoolBody.get());
2642 void Parser::StashAwayMethodOrFunctionBodyTokens(
Decl *MDecl) {
2643 if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
2644 trySkippingFunctionBody()) {
2645 Actions.ActOnSkippedFunctionBody(MDecl);
2649 LexedMethod* LM =
new LexedMethod(
this, MDecl);
2650 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2653 Toks.push_back(Tok);
2654 if (Tok.
is(tok::kw_try)) {
2656 if (Tok.
is(tok::colon)) {
2657 Toks.push_back(Tok);
2659 while (Tok.
isNot(tok::l_brace)) {
2660 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2661 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2664 Toks.push_back(Tok);
2666 else if (Tok.
is(tok::colon)) {
2669 while (Tok.
isNot(tok::l_brace)) {
2670 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2671 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2673 Toks.push_back(Tok);
2677 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2678 while (Tok.
is(tok::kw_catch)) {
2679 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
2680 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2686 Decl *Parser::ParseObjCMethodDefinition() {
2687 Decl *MDecl = ParseObjCMethodPrototype();
2690 "parsing Objective-C method");
2693 if (Tok.
is(tok::semi)) {
2694 if (CurParsedObjCImpl) {
2695 Diag(Tok, diag::warn_semicolon_before_method_body)
2702 if (Tok.
isNot(tok::l_brace)) {
2703 Diag(Tok, diag::err_expected_method_body);
2709 if (Tok.
isNot(tok::l_brace))
2720 Actions.AddAnyMethodToGlobalPool(MDecl);
2721 assert (CurParsedObjCImpl
2722 &&
"ParseObjCMethodDefinition - Method out of @implementation");
2724 StashAwayMethodOrFunctionBodyTokens(MDecl);
2729 ParsedStmtContext StmtCtx) {
2730 if (Tok.
is(tok::code_completion)) {
2731 Actions.CodeCompleteObjCAtStatement(
getCurScope());
2737 return ParseObjCTryStmt(AtLoc);
2740 return ParseObjCThrowStmt(AtLoc);
2743 return ParseObjCSynchronizedStmt(AtLoc);
2746 return ParseObjCAutoreleasePoolStmt(AtLoc);
2751 return Actions.ActOnNullStmt(Tok.getLocation());
2754 ExprStatementTokLoc = AtLoc;
2755 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2765 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2766 return handleExprStmt(Res, StmtCtx);
2770 switch (Tok.getKind()) {
2771 case tok::code_completion:
2772 Actions.CodeCompleteObjCAtExpression(
getCurScope());
2781 if (!Tok.
is(tok::numeric_constant)) {
2782 const char *Symbol =
nullptr;
2784 case tok::minus: Symbol =
"-";
break;
2785 case tok::plus: Symbol =
"+";
break;
2786 default: llvm_unreachable(
"missing unary operator case");
2788 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2793 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2794 if (Lit.isInvalid()) {
2799 Lit = Actions.ActOnUnaryOp(
getCurScope(), OpLoc, Kind, Lit.get());
2800 if (Lit.isInvalid())
2803 return ParsePostfixExpressionSuffix(
2804 Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()));
2807 case tok::string_literal:
2808 case tok::wide_string_literal:
2809 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2811 case tok::char_constant:
2812 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2814 case tok::numeric_constant:
2815 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2818 case tok::kw___objc_yes:
2819 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
true));
2821 case tok::kw___objc_no:
2822 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
false));
2826 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2830 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2834 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2837 if (Tok.getIdentifierInfo() ==
nullptr)
2840 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
2841 case tok::objc_encode:
2842 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2843 case tok::objc_protocol:
2844 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2845 case tok::objc_selector:
2846 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2847 case tok::objc_available:
2848 return ParseAvailabilityCheckExpr(AtLoc);
2850 const char *str =
nullptr;
2854 if (GetLookAheadToken(1).is(tok::l_brace) &&
2855 ExprStatementTokLoc == AtLoc) {
2856 char ch = Tok.getIdentifierInfo()->getNameStart()[0];
2859 : (ch ==
'f' ?
"finally" 2860 : (ch ==
'a' ?
"autoreleasepool" :
nullptr));
2896 bool Parser::ParseObjCXXMessageReceiver(
bool &IsExpr,
void *&TypeOrExpr) {
2899 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2900 tok::annot_cxxscope))
2903 if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
2914 TypeOrExpr = Receiver.
get();
2923 ParseCXXSimpleTypeSpecifier(DS);
2925 if (Tok.
is(tok::l_paren)) {
2938 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2940 Receiver = ParsePostfixExpressionSuffix(Receiver.
get());
2942 Receiver = ParseRHSOfBinaryExpression(Receiver.
get(),
prec::Comma);
2947 TypeOrExpr = Receiver.
get();
2960 TypeOrExpr = Type.
get().getAsOpaquePtr();
2969 bool Parser::isSimpleObjCMessageExpression() {
2971 "Incorrect start for isSimpleObjCMessageExpression");
2972 return GetLookAheadToken(1).is(tok::identifier) &&
2973 GetLookAheadToken(2).is(tok::identifier);
2976 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2978 InMessageExpression)
2983 if (Tok.
is(tok::annot_typename))
2985 else if (Tok.
is(tok::identifier))
2986 Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(),
2991 if (!Type.
get().isNull() && Type.
get()->isObjCObjectOrInterfaceType()) {
2992 const Token &AfterNext = GetLookAheadToken(2);
2993 if (AfterNext.
isOneOf(tok::colon, tok::r_square)) {
2994 if (Tok.
is(tok::identifier))
2997 return Tok.
is(tok::annot_typename);
3013 ExprResult Parser::ParseObjCMessageExpression() {
3014 assert(Tok.
is(tok::l_square) &&
"'[' expected");
3017 if (Tok.
is(tok::code_completion)) {
3018 Actions.CodeCompleteObjCMessageReceiver(
getCurScope());
3032 if (Tok.
is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
3034 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3039 void *TypeOrExpr =
nullptr;
3040 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
3046 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3047 static_cast<Expr *>(TypeOrExpr));
3049 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3054 if (Tok.
is(tok::identifier)) {
3058 switch (Actions.getObjCMessageKind(
getCurScope(), Name, NameLoc,
3059 Name == Ident_super,
3063 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3067 if (!ReceiverType) {
3075 if (Tok.
is(tok::less)) {
3078 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3086 ReceiverType = NewReceiverType.
get();
3089 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3090 ReceiverType,
nullptr);
3105 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3151 Expr *ReceiverExpr) {
3154 if (Tok.
is(tok::code_completion)) {
3158 else if (ReceiverType)
3159 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
None,
3162 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3174 ExprVector KeyExprs;
3176 if (Tok.
is(tok::colon)) {
3179 KeyIdents.push_back(selIdent);
3180 KeyLocs.push_back(Loc);
3182 if (ExpectAndConsume(tok::colon)) {
3192 if (Tok.
is(tok::code_completion)) {
3194 Actions.CodeCompleteObjCSuperMessage(
getCurScope(), SuperLoc,
3197 else if (ReceiverType)
3198 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
3202 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3212 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3213 Expr = ParseBraceInitializer();
3227 KeyExprs.push_back(Res.
get());
3230 if (Tok.
is(tok::code_completion)) {
3232 Actions.CodeCompleteObjCSuperMessage(
getCurScope(), SuperLoc,
3235 else if (ReceiverType)
3236 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
3240 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3248 selIdent = ParseObjCSelectorPiece(Loc);
3249 if (!selIdent && Tok.
isNot(tok::colon))
3254 while (Tok.
is(tok::comma)) {
3258 if (Tok.
is(tok::colon))
3259 Res = Actions.CorrectDelayedTyposInExpr(Res);
3261 if (Tok.
is(tok::colon)) {
3262 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3273 KeyExprs.push_back(Res.
get());
3275 }
else if (!selIdent) {
3276 Diag(Tok, diag::err_expected) << tok::identifier;
3285 if (Tok.
isNot(tok::r_square)) {
3286 Diag(Tok, diag::err_expected)
3287 << (Tok.
is(tok::identifier) ? tok::colon : tok::r_square);
3297 unsigned nKeys = KeyIdents.size();
3299 KeyIdents.push_back(selIdent);
3300 KeyLocs.push_back(Loc);
3302 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
3305 return Actions.ActOnSuperMessage(
getCurScope(), SuperLoc, Sel,
3306 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3307 else if (ReceiverType)
3308 return Actions.ActOnClassMessage(
getCurScope(), ReceiverType, Sel,
3309 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3310 return Actions.ActOnInstanceMessage(
getCurScope(), ReceiverExpr, Sel,
3311 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3315 ExprResult Res(ParseStringLiteralExpression());
3322 ExprVector AtStrings;
3323 AtLocs.push_back(AtLoc);
3324 AtStrings.push_back(Res.
get());
3326 while (Tok.
is(tok::at)) {
3330 if (!isTokenStringLiteral())
3333 ExprResult Lit(ParseStringLiteralExpression());
3337 AtStrings.push_back(Lit.
get());
3340 return Actions.ParseObjCStringLiteral(AtLocs.data(), AtStrings);
3351 return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
3358 ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
3359 if (Lit.isInvalid()) {
3363 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3372 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
3373 if (Lit.isInvalid()) {
3377 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3385 if (Tok.
isNot(tok::l_paren))
3386 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@");
3400 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.
get());
3401 return Actions.BuildObjCBoxedExpr(
SourceRange(AtLoc, RPLoc),
3406 ExprVector ElementExprs;
3409 bool HasInvalidEltExpr =
false;
3410 while (Tok.
isNot(tok::r_square)) {
3421 Res = Actions.CorrectDelayedTyposInExpr(Res.
get());
3423 HasInvalidEltExpr =
true;
3426 if (Tok.
is(tok::ellipsis))
3429 HasInvalidEltExpr =
true;
3431 ElementExprs.push_back(Res.
get());
3433 if (Tok.
is(tok::comma))
3435 else if (Tok.
isNot(tok::r_square))
3436 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_square
3441 if (HasInvalidEltExpr)
3445 return Actions.BuildObjCArrayLiteral(
SourceRange(AtLoc, EndLoc), Args);
3451 bool HasInvalidEltExpr =
false;
3452 while (Tok.
isNot(tok::r_brace)) {
3467 if (ExpectAndConsume(tok::colon)) {
3482 KeyExpr = Actions.CorrectDelayedTyposInExpr(KeyExpr.
get());
3483 ValueExpr = Actions.CorrectDelayedTyposInExpr(ValueExpr.
get());
3485 HasInvalidEltExpr =
true;
3497 KeyExpr.
get(), ValueExpr.
get(), EllipsisLoc,
None 3499 Elements.push_back(Element);
3502 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_brace
3507 if (HasInvalidEltExpr)
3511 return Actions.BuildObjCDictionaryLiteral(
SourceRange(AtLoc, EndLoc),
3519 assert(Tok.
isObjCAtKeyword(tok::objc_encode) &&
"Not an @encode expression!");
3523 if (Tok.
isNot(tok::l_paren))
3524 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@encode");
3536 return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.
getOpenLocation(),
3546 if (Tok.
isNot(tok::l_paren))
3547 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@protocol");
3552 if (expectIdentifier())
3560 return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
3570 if (Tok.
isNot(tok::l_paren))
3571 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@selector");
3578 bool HasOptionalParen = Tok.
is(tok::l_paren);
3579 if (HasOptionalParen)
3582 if (Tok.
is(tok::code_completion)) {
3583 Actions.CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3590 Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3591 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3593 KeyIdents.push_back(SelIdent);
3595 unsigned nColons = 0;
3596 if (Tok.
isNot(tok::r_paren)) {
3600 KeyIdents.push_back(
nullptr);
3601 }
else if (ExpectAndConsume(tok::colon))
3605 if (Tok.
is(tok::r_paren))
3608 if (Tok.
is(tok::code_completion)) {
3609 Actions.CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3616 SelIdent = ParseObjCSelectorPiece(Loc);
3617 KeyIdents.push_back(SelIdent);
3618 if (!SelIdent && Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3622 if (HasOptionalParen && Tok.
is(tok::r_paren))
3625 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
3626 return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
3632 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM,
bool parseMethod) {
3634 Decl *MCDecl = LM.D;
3635 bool skip = MCDecl &&
3636 ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
3637 (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
3644 assert(!LM.Toks.empty() &&
"ParseLexedObjCMethodDef - Empty body!");
3650 Eof.setEofData(MCDecl);
3651 Eof.setLocation(OrigLoc);
3652 LM.Toks.push_back(Eof);
3655 LM.Toks.push_back(Tok);
3656 PP.EnterTokenStream(LM.Toks,
true,
true);
3661 assert(Tok.
isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3662 "Inline objective-c method not starting with '{' or 'try' or ':'");
3671 Actions.ActOnStartOfObjCMethodDef(
getCurScope(), MCDecl);
3673 Actions.ActOnStartOfFunctionDef(
getCurScope(), MCDecl);
3674 if (Tok.
is(tok::kw_try))
3675 ParseFunctionTryBlock(MCDecl, BodyScope);
3677 if (Tok.
is(tok::colon))
3678 ParseConstructorInitializer(MCDecl);
3680 Actions.ActOnDefaultCtorInitializers(MCDecl);
3681 ParseFunctionStatementBody(MCDecl, BodyScope);
3684 if (Tok.getLocation() != OrigLoc) {
3690 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 ...
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
Context-sensitive version of a keyword attribute.
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.