22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/StringExtras.h" 25 using namespace clang;
30 if (Tok.
is(tok::kw___attribute)) {
31 if (Kind == tok::objc_interface || Kind == tok::objc_protocol)
32 Diag(Tok, diag::err_objc_postfix_attribute_hint)
33 << (Kind == tok::objc_protocol);
35 Diag(Tok, diag::err_objc_postfix_attribute);
36 ParseGNUAttributes(attrs);
51 if (Tok.
is(tok::code_completion)) {
57 Decl *SingleDecl =
nullptr;
60 return ParseObjCAtClassDeclaration(AtLoc);
61 case tok::objc_interface: {
63 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
66 case tok::objc_protocol: {
68 return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
70 case tok::objc_implementation:
71 return ParseObjCAtImplementationDeclaration(AtLoc);
73 return ParseObjCAtEndDeclaration(AtLoc);
74 case tok::objc_compatibility_alias:
75 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
77 case tok::objc_synthesize:
78 SingleDecl = ParseObjCPropertySynthesize(AtLoc);
80 case tok::objc_dynamic:
81 SingleDecl = ParseObjCPropertyDynamic(AtLoc);
83 case tok::objc_import:
85 SingleDecl = ParseModuleImport(AtLoc);
88 Diag(AtLoc, diag::err_atimport);
92 Diag(AtLoc, diag::err_unexpected_at);
108 : Actions(Actions), S(S), Params(nullptr) {}
141 MaybeSkipAttributes(tok::objc_class);
142 if (expectIdentifier()) {
144 return Actions.ConvertDeclToDeclGroup(
nullptr);
146 ClassNames.push_back(Tok.getIdentifierInfo());
147 ClassLocs.push_back(Tok.getLocation());
152 if (Tok.
is(tok::less))
153 TypeParams = parseObjCTypeParamList();
154 ClassTypeParams.push_back(TypeParams);
160 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@class"))
161 return Actions.ConvertDeclToDeclGroup(
nullptr);
163 return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
175 Decl *
Decl = Actions.getObjCDeclContext();
176 if (CurParsedObjCImpl) {
177 CurParsedObjCImpl->finish(AtLoc);
181 Diag(AtLoc, diag::err_objc_missing_end)
220 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
221 CheckNestedObjCContexts(AtLoc);
225 if (Tok.
is(tok::code_completion)) {
226 Actions.CodeCompleteObjCInterfaceDecl(
getCurScope());
231 MaybeSkipAttributes(tok::objc_interface);
233 if (expectIdentifier())
247 if (Tok.
is(tok::less))
248 typeParameterList = parseObjCTypeParamListOrProtocolRefs(
249 typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
251 if (Tok.
is(tok::l_paren) &&
252 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
259 if (Tok.
is(tok::code_completion)) {
260 Actions.CodeCompleteObjCInterfaceCategory(
getCurScope(), nameId, nameLoc);
266 if (Tok.
is(tok::identifier)) {
267 categoryId = Tok.getIdentifierInfo();
271 Diag(Tok, diag::err_expected)
281 assert(LAngleLoc.
isInvalid() &&
"Cannot have already parsed protocols");
284 if (Tok.
is(tok::less) &&
285 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
true,
true,
286 LAngleLoc, EndProtoLoc,
290 Decl *CategoryType = Actions.ActOnStartCategoryInterface(
291 AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
292 ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
295 if (Tok.
is(tok::l_brace))
296 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
298 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
310 if (Tok.
is(tok::colon)) {
314 if (Tok.
is(tok::code_completion)) {
315 Actions.CodeCompleteObjCSuperclass(
getCurScope(), nameId, nameLoc);
320 if (expectIdentifier())
322 superClassId = Tok.getIdentifierInfo();
326 if (Tok.
is(tok::less)) {
327 parseObjCTypeArgsOrProtocolQualifiers(
328 nullptr, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, LAngleLoc,
329 protocols, protocolLocs, EndProtoLoc,
339 if (!ProtocolIdents.empty()) {
342 for (
const auto &pair : ProtocolIdents) {
343 protocolLocs.push_back(pair.second);
345 Actions.FindProtocolDeclaration(
true,
347 ProtocolIdents, protocols);
349 }
else if (protocols.empty() && Tok.
is(tok::less) &&
350 ParseObjCProtocolReferences(protocols, protocolLocs,
true,
true,
351 LAngleLoc, EndProtoLoc,
356 if (Tok.
isNot(tok::less))
357 Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
358 superClassId, superClassLoc);
361 Actions.ActOnStartClassInterface(
getCurScope(), AtLoc, nameId, nameLoc,
362 typeParameterList, superClassId,
367 protocols.data(), protocols.size(),
371 if (Tok.
is(tok::l_brace))
372 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
374 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
385 bool &addedToDeclSpec) {
398 auto nullabilityAttr = getNullabilityAttr();
402 }
else if (!addedToDeclSpec) {
406 addedToDeclSpec =
true;
438 assert(Tok.
is(tok::less) &&
"Not at the beginning of a type parameter list");
446 auto makeProtocolIdentsIntoTypeParameters = [&]() {
448 for (
const auto &pair : protocolIdents) {
449 DeclResult typeParam = Actions.actOnObjCTypeParam(
453 typeParams.push_back(typeParam.
get());
456 protocolIdents.clear();
457 mayBeProtocolList =
false;
460 bool invalid =
false;
467 if (Tok.
is(tok::kw___covariant) || Tok.
is(tok::kw___contravariant)) {
468 variance = Tok.
is(tok::kw___covariant)
475 if (mayBeProtocolList) {
478 makeProtocolIdentsIntoTypeParameters();
483 if (!Tok.
is(tok::identifier)) {
485 if (Tok.
is(tok::code_completion)) {
488 Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
495 Diag(Tok, diag::err_objc_expected_type_parameter);
509 if (mayBeProtocolList) {
512 makeProtocolIdentsIntoTypeParameters();
519 }
else if (mayBeProtocolList) {
522 protocolIdents.push_back(std::make_pair(paramName, paramLoc));
527 DeclResult typeParam = Actions.actOnObjCTypeParam(
528 getCurScope(), variance, varianceLoc, typeParams.size(), paramName,
529 paramLoc, colonLoc, boundType.
isUsable() ? boundType.
get() :
nullptr);
531 typeParams.push_back(typeParam.
get());
537 if (Tok.
is(tok::greater))
539 }
else if (ParseGreaterThanInTemplateList(rAngleLoc,
542 Diag(lAngleLoc, diag::note_matching) <<
"'<'";
543 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
544 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
545 tok::comma, tok::semi },
547 if (Tok.
is(tok::greater))
551 if (mayBeProtocolList) {
556 if (Tok.
isNot(tok::colon) && Tok.
isNot(tok::l_paren)) {
565 makeProtocolIdentsIntoTypeParameters();
580 return invalid ? nullptr : list;
589 ObjCTypeParamListScope Scope(Actions,
getCurScope());
590 return parseObjCTypeParamListOrProtocolRefs(Scope, lAngleLoc, protocolIdents,
617 if (Tok.
isOneOf(tok::minus, tok::plus)) {
618 if (
Decl *methodPrototype =
619 ParseObjCMethodPrototype(MethodImplKind,
false))
620 allMethods.push_back(methodPrototype);
623 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
626 if (Tok.
is(tok::semi))
631 if (Tok.
is(tok::l_paren)) {
632 Diag(Tok, diag::err_expected_minus_or_plus);
633 ParseObjCMethodDecl(Tok.getLocation(),
635 MethodImplKind,
false);
639 if (Tok.
is(tok::semi)) {
649 if (Tok.
is(tok::code_completion)) {
653 return cutOffParsing();
657 if (Tok.
isNot(tok::at)) {
661 if (Tok.
is(tok::r_brace))
663 ParsedAttributesWithRange attrs(AttrFactory);
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:
714 if (contextKey != tok::objc_protocol)
715 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
717 MethodImplKind = DirectiveKind;
720 case tok::objc_property:
722 Diag(AtLoc, diag::err_objc_properties_require_objc2);
727 if (Tok.
is(tok::l_paren)) {
728 LParenLoc = Tok.getLocation();
729 ParseObjCPropertyAttribute(OCDS);
732 bool addedToDeclSpec =
false;
734 if (FD.D.getIdentifier() ==
nullptr) {
735 Diag(AtLoc, diag::err_objc_property_requires_field_name)
736 << FD.D.getSourceRange();
739 if (FD.BitfieldSize) {
740 Diag(AtLoc, diag::err_objc_property_bitfield)
741 << FD.D.getSourceRange();
756 Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName);
760 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
763 PP.getIdentifierTable(), PP.getSelectorTable(),
764 FD.D.getIdentifier());
766 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
769 FD.complete(Property);
774 ParseStructDeclaration(DS, ObjCPropertyCallback);
776 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
783 if (Tok.
is(tok::code_completion)) {
784 Actions.CodeCompleteObjCAtDirective(
getCurScope());
785 return cutOffParsing();
789 Diag(Tok, diag::err_objc_missing_end)
792 << (
int) Actions.getObjCContainerKind();
794 AtEnd.
setEnd(Tok.getLocation());
799 Actions.ActOnAtEnd(
getCurScope(), AtEnd, allMethods, allTUVariables);
808 P.
Diag(nullabilityLoc, diag::warn_nullability_duplicate)
814 P.
Diag(nullabilityLoc, diag::err_nullability_conflicting)
845 void Parser::ParseObjCPropertyAttribute(
ObjCDeclSpec &DS) {
846 assert(Tok.getKind() == tok::l_paren);
851 if (Tok.
is(tok::code_completion)) {
852 Actions.CodeCompleteObjCPropertyFlags(
getCurScope(), DS);
853 return cutOffParsing();
865 if (II->
isStr(
"readonly"))
867 else if (II->
isStr(
"assign"))
869 else if (II->
isStr(
"unsafe_unretained"))
871 else if (II->
isStr(
"readwrite"))
873 else if (II->
isStr(
"retain"))
875 else if (II->
isStr(
"strong"))
877 else if (II->
isStr(
"copy"))
879 else if (II->
isStr(
"nonatomic"))
881 else if (II->
isStr(
"atomic"))
883 else if (II->
isStr(
"weak"))
885 else if (II->
isStr(
"getter") || II->
isStr(
"setter")) {
889 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
890 diag::err_objc_expected_equal_for_getter;
892 if (ExpectAndConsume(tok::equal, DiagID)) {
897 if (Tok.
is(tok::code_completion)) {
899 Actions.CodeCompleteObjCPropertySetter(
getCurScope());
901 Actions.CodeCompleteObjCPropertyGetter(
getCurScope());
902 return cutOffParsing();
909 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
919 if (ExpectAndConsume(tok::colon,
920 diag::err_expected_colon_after_setter_name)) {
928 }
else if (II->
isStr(
"nonnull")) {
935 }
else if (II->
isStr(
"nullable")) {
942 }
else if (II->
isStr(
"null_unspecified")) {
949 }
else if (II->
isStr(
"null_resettable")) {
959 }
else if (II->
isStr(
"class")) {
962 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
967 if (Tok.
isNot(tok::comma))
987 bool MethodDefinition) {
988 assert(Tok.
isOneOf(tok::minus, tok::plus) &&
"expected +/-");
992 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
1009 switch (Tok.getKind()) {
1014 SelectorLoc = Tok.getLocation();
1022 case tok::exclaimequal:
1024 case tok::pipeequal:
1026 case tok::caretequal: {
1027 std::string ThisTok(PP.getSpelling(Tok));
1030 Tok.setKind(tok::identifier);
1037 case tok::identifier:
1047 case tok::kw_const_cast:
1048 case tok::kw_continue:
1049 case tok::kw_default:
1050 case tok::kw_delete:
1052 case tok::kw_double:
1053 case tok::kw_dynamic_cast:
1056 case tok::kw_explicit:
1057 case tok::kw_export:
1058 case tok::kw_extern:
1062 case tok::kw_friend:
1065 case tok::kw_inline:
1068 case tok::kw_mutable:
1069 case tok::kw_namespace:
1071 case tok::kw_operator:
1072 case tok::kw_private:
1073 case tok::kw_protected:
1074 case tok::kw_public:
1075 case tok::kw_register:
1076 case tok::kw_reinterpret_cast:
1077 case tok::kw_restrict:
1078 case tok::kw_return:
1080 case tok::kw_signed:
1081 case tok::kw_sizeof:
1082 case tok::kw_static:
1083 case tok::kw_static_cast:
1084 case tok::kw_struct:
1085 case tok::kw_switch:
1086 case tok::kw_template:
1091 case tok::kw_typedef:
1092 case tok::kw_typeid:
1093 case tok::kw_typename:
1094 case tok::kw_typeof:
1096 case tok::kw_unsigned:
1098 case tok::kw_virtual:
1100 case tok::kw_volatile:
1101 case tok::kw_wchar_t:
1104 case tok::kw__Complex:
1105 case tok::kw___alignof:
1106 case tok::kw___auto_type:
1115 bool Parser::isTokIdentifier_in()
const {
1120 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
1142 void Parser::ParseObjCTypeQualifierList(
ObjCDeclSpec &DS,
1148 if (Tok.
is(tok::code_completion)) {
1149 Actions.CodeCompleteObjCPassingType(
getCurScope(), DS,
1151 return cutOffParsing();
1154 if (Tok.
isNot(tok::identifier))
1158 for (
unsigned i = 0; i != objc_NumQuals; ++i) {
1159 if (II != ObjCTypeQuals[i] ||
1167 default: llvm_unreachable(
"Unknown decl qualifier");
1185 case objc_null_unspecified:
1249 assert((paramAttrs !=
nullptr) ==
1252 assert(Tok.
is(tok::l_paren) &&
"expected (");
1261 ParseObjCTypeQualifierList(DS, context);
1264 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1268 DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
1270 dsContext = DeclSpecContext::DSC_objc_method_result;
1271 ParseSpecifierQualifierList(declSpec,
AS_none, dsContext);
1273 ParseDeclarator(declarator);
1278 bool addedToDeclSpec =
false;
1296 if (Tok.
is(tok::r_paren))
1298 else if (Tok.getLocation() == TypeStartLoc) {
1300 Diag(Tok, diag::err_expected_type);
1341 bool MethodDefinition) {
1344 if (Tok.
is(tok::code_completion)) {
1345 Actions.CodeCompleteObjCMethodDecl(
getCurScope(), mType == tok::minus,
1354 if (Tok.
is(tok::l_paren))
1361 MaybeParseGNUAttributes(methodAttrs);
1363 if (Tok.
is(tok::code_completion)) {
1364 Actions.CodeCompleteObjCMethodDecl(
getCurScope(), mType == tok::minus,
1375 if (!SelIdent && Tok.
isNot(tok::colon)) {
1376 Diag(Tok, diag::err_expected_selector_for_method)
1384 if (Tok.
isNot(tok::colon)) {
1387 MaybeParseGNUAttributes(methodAttrs);
1389 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
1391 = Actions.ActOnMethodDeclaration(
getCurScope(), mLoc, Tok.getLocation(),
1392 mType, DSRet, ReturnType,
1393 selLoc, Sel,
nullptr,
1394 CParamInfo.data(), CParamInfo.size(),
1395 methodAttrs.
getList(), MethodImplKind,
1396 false, MethodDefinition);
1413 if (ExpectAndConsume(tok::colon))
1416 ArgInfo.
Type =
nullptr;
1417 if (Tok.
is(tok::l_paren))
1426 MaybeParseGNUAttributes(paramAttrs);
1431 if (Tok.
is(tok::code_completion)) {
1432 KeyIdents.push_back(SelIdent);
1433 Actions.CodeCompleteObjCMethodDeclSelector(
getCurScope(),
1434 mType == tok::minus,
1436 ReturnType, KeyIdents);
1441 if (expectIdentifier())
1444 ArgInfo.
Name = Tok.getIdentifierInfo();
1445 ArgInfo.
NameLoc = Tok.getLocation();
1448 ArgInfos.push_back(ArgInfo);
1449 KeyIdents.push_back(SelIdent);
1450 KeyLocs.push_back(selLoc);
1456 if (Tok.
is(tok::code_completion)) {
1457 Actions.CodeCompleteObjCMethodDeclSelector(
getCurScope(),
1458 mType == tok::minus,
1460 ReturnType, KeyIdents);
1466 SelIdent = ParseObjCSelectorPiece(selLoc);
1467 if (!SelIdent && Tok.
isNot(tok::colon))
1472 Diag(ArgInfo.
NameLoc, diag::warn_missing_selector_name) << ArgInfo.
Name;
1473 Diag(ArgInfo.
NameLoc, diag::note_missing_selector_name) << ArgInfo.
Name;
1474 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.
Name;
1480 bool isVariadic =
false;
1481 bool cStyleParamWarned =
false;
1483 while (Tok.
is(tok::comma)) {
1485 if (Tok.
is(tok::ellipsis)) {
1490 if (!cStyleParamWarned) {
1491 Diag(Tok, diag::warn_cstyle_param);
1492 cStyleParamWarned =
true;
1495 ParseDeclarationSpecifiers(DS);
1498 ParseDeclarator(ParmDecl);
1510 MaybeParseGNUAttributes(methodAttrs);
1512 if (KeyIdents.size() == 0)
1515 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
1518 = Actions.ActOnMethodDeclaration(
getCurScope(), mLoc, Tok.getLocation(),
1519 mType, DSRet, ReturnType,
1520 KeyLocs, Sel, &ArgInfos[0],
1521 CParamInfo.data(), CParamInfo.size(),
1523 MethodImplKind, isVariadic, MethodDefinition);
1535 bool WarnOnDeclarations,
bool ForObjCContainer,
1537 bool consumeLastToken) {
1538 assert(Tok.
is(tok::less) &&
"expected <");
1545 if (Tok.
is(tok::code_completion)) {
1546 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
1551 if (expectIdentifier()) {
1555 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
1556 Tok.getLocation()));
1557 ProtocolLocs.push_back(Tok.getLocation());
1565 if (ParseGreaterThanInTemplateList(EndLoc, consumeLastToken,
1570 Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer,
1571 ProtocolIdents, Protocols);
1576 assert(Tok.
is(tok::less) &&
"Protocol qualifiers start with '<'");
1577 assert(
getLangOpts().ObjC1 &&
"Protocol qualifiers only exist in Objective-C");
1582 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
false,
false,
1583 lAngleLoc, rAngleLoc,
1585 TypeResult result = Actions.actOnObjCProtocolQualifierType(lAngleLoc,
1590 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1603 void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1612 bool consumeLastToken,
1613 bool warnOnIncompleteProtocols) {
1614 assert(Tok.
is(tok::less) &&
"Not at the start of type args or protocols");
1619 bool allSingleIdentifiers =
true;
1627 if (Tok.
is(tok::identifier) &&
1631 identifiers.push_back(Tok.getIdentifierInfo());
1636 if (Tok.
is(tok::code_completion)) {
1639 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1641 identifierLocs[i]));
1644 QualType BaseT = Actions.GetTypeFromParser(baseType);
1648 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
1654 allSingleIdentifiers =
false;
1660 if (allSingleIdentifiers) {
1663 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1667 Actions.actOnObjCTypeArgsOrProtocolQualifiers(
getCurScope(),
1679 warnOnIncompleteProtocols);
1689 bool invalid =
false;
1690 IdentifierInfo *foundProtocolId =
nullptr, *foundValidTypeId =
nullptr;
1695 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1697 = Actions.getTypeName(*identifiers[i], identifierLocs[i],
getCurScope());
1700 const char *prevSpec =
nullptr;
1703 typeArg, Actions.getASTContext().getPrintingPolicy());
1709 typeArgs.push_back(fullTypeArg.
get());
1710 if (!foundValidTypeId) {
1711 foundValidTypeId = identifiers[i];
1712 foundValidTypeSrcLoc = identifierLocs[i];
1716 unknownTypeArgs.push_back(identifiers[i]);
1717 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1721 if (!Actions.LookupProtocol(identifiers[i], identifierLocs[i])) {
1722 unknownTypeArgs.push_back(identifiers[i]);
1723 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1724 }
else if (!foundProtocolId) {
1725 foundProtocolId = identifiers[i];
1726 foundProtocolSrcLoc = identifierLocs[i];
1733 Token CurTypeTok = Tok;
1740 typeArg = Actions.ActOnPackExpansion(typeArg.
get(), ellipsisLoc);
1744 typeArgs.push_back(typeArg.
get());
1745 if (!foundValidTypeId) {
1755 if (foundProtocolId && foundValidTypeId)
1756 Actions.DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc,
1758 foundValidTypeSrcLoc);
1762 if (unknownTypeArgs.size())
1763 for (
unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1764 Actions.DiagnoseUnknownTypeName(unknownTypeArgs[i], unknownTypeArgsLoc[i],
1769 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1778 typeArgsLAngleLoc = lAngleLoc;
1779 typeArgsRAngleLoc = rAngleLoc;
1782 void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1791 bool consumeLastToken) {
1792 assert(Tok.
is(tok::less));
1795 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1811 if ((consumeLastToken && Tok.
is(tok::less)) ||
1812 (!consumeLastToken &&
NextToken().
is(tok::less))) {
1815 if (!consumeLastToken)
1818 if (!protocols.empty()) {
1820 if (!consumeLastToken)
1822 Diag(Tok, diag::err_objc_type_args_after_protocols)
1823 <<
SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1824 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1826 ParseObjCProtocolReferences(protocols, protocolLocs,
1829 protocolLAngleLoc, protocolRAngleLoc,
1835 TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1838 bool consumeLastToken,
1840 assert(Tok.
is(tok::less));
1850 parseObjCTypeArgsAndProtocolQualifiers(type, typeArgsLAngleLoc, typeArgs,
1851 typeArgsRAngleLoc, protocolLAngleLoc,
1852 protocols, protocolLocs,
1853 protocolRAngleLoc, consumeLastToken);
1859 if (consumeLastToken)
1860 endLoc = PrevTokLocation;
1862 endLoc = Tok.getLocation();
1864 return Actions.actOnObjCTypeArgsAndProtocolQualifiers(
1877 void Parser::HelperActionsForIvarDeclarations(
Decl *interfaceDecl,
SourceLocation atLoc,
1880 bool RBraceMissing) {
1884 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1886 Actions.ActOnObjCContainerFinishDefinition();
1889 Actions.ActOnFields(
getCurScope(), atLoc, interfaceDecl,
1914 void Parser::ParseObjCClassInstanceVariables(
Decl *interfaceDecl,
1917 assert(Tok.
is(tok::l_brace) &&
"expected {");
1926 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
1930 if (Tok.
is(tok::semi)) {
1931 ConsumeExtraSemi(InstanceVariableList);
1937 if (Tok.
is(tok::code_completion)) {
1938 Actions.CodeCompleteObjCAtVisibility(
getCurScope());
1939 return cutOffParsing();
1942 switch (Tok.getObjCKeywordID()) {
1943 case tok::objc_private:
1944 case tok::objc_public:
1945 case tok::objc_protected:
1946 case tok::objc_package:
1947 visibility = Tok.getObjCKeywordID();
1952 Diag(Tok, diag::err_objc_unexpected_atend);
1953 Tok.setLocation(Tok.getLocation().getLocWithOffset(-1));
1954 Tok.setKind(tok::at);
1957 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1958 T, AllIvarDecls,
true);
1962 Diag(Tok, diag::err_objc_illegal_visibility_spec);
1967 if (Tok.
is(tok::code_completion)) {
1970 return cutOffParsing();
1974 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1976 FD.D.setObjCIvar(
true);
1977 Decl *Field = Actions.ActOnIvar(
1978 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
1979 FD.BitfieldSize, visibility);
1980 Actions.ActOnObjCContainerFinishDefinition();
1982 AllIvarDecls.push_back(Field);
1988 ParseStructDeclaration(DS, ObjCIvarCallback);
1990 if (Tok.
is(tok::semi)) {
1993 Diag(Tok, diag::err_expected_semi_decl_list);
1998 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1999 T, AllIvarDecls,
false);
2022 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2025 if (Tok.
is(tok::code_completion)) {
2026 Actions.CodeCompleteObjCProtocolDecl(
getCurScope());
2031 MaybeSkipAttributes(tok::objc_protocol);
2033 if (expectIdentifier())
2041 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo,
2045 CheckNestedObjCContexts(AtLoc);
2047 if (Tok.
is(tok::comma)) {
2049 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2054 if (expectIdentifier()) {
2059 Tok.getLocation()));
2062 if (Tok.
isNot(tok::comma))
2066 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@protocol"))
2069 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs,
2078 if (Tok.
is(tok::less) &&
2079 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
false,
true,
2080 LAngleLoc, EndProtoLoc,
2085 Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
2086 ProtocolRefs.data(),
2087 ProtocolRefs.size(),
2088 ProtocolLocs.data(),
2089 EndProtoLoc, attrs.
getList());
2091 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2092 return Actions.ConvertDeclToDeclGroup(ProtoType);
2106 Parser::ParseObjCAtImplementationDeclaration(
SourceLocation AtLoc) {
2108 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2109 CheckNestedObjCContexts(AtLoc);
2113 if (Tok.
is(tok::code_completion)) {
2114 Actions.CodeCompleteObjCImplementationDecl(
getCurScope());
2119 MaybeSkipAttributes(tok::objc_implementation);
2121 if (expectIdentifier())
2126 Decl *ObjCImpDecl =
nullptr;
2130 if (Tok.
is(tok::less)) {
2134 ObjCTypeParamListScope typeParamScope(Actions,
getCurScope());
2135 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
2136 protocolIdents, rAngleLoc)) {
2137 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2139 }
else if (lAngleLoc.
isValid()) {
2140 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2145 if (Tok.
is(tok::l_paren)) {
2151 if (Tok.
is(tok::code_completion)) {
2152 Actions.CodeCompleteObjCImplementationCategory(
getCurScope(), nameId, nameLoc);
2157 if (Tok.
is(tok::identifier)) {
2158 categoryId = Tok.getIdentifierInfo();
2161 Diag(Tok, diag::err_expected)
2165 if (Tok.
isNot(tok::r_paren)) {
2166 Diag(Tok, diag::err_expected) << tok::r_paren;
2170 rparenLoc = ConsumeParen();
2171 if (Tok.
is(tok::less)) {
2172 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2176 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2179 protocolLAngleLoc, protocolRAngleLoc,
2182 ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
2183 AtLoc, nameId, nameLoc, categoryId,
2192 if (expectIdentifier())
2194 superClassId = Tok.getIdentifierInfo();
2197 ObjCImpDecl = Actions.ActOnStartClassImplementation(
2198 AtLoc, nameId, nameLoc,
2199 superClassId, superClassLoc);
2201 if (Tok.
is(tok::l_brace))
2202 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2203 else if (Tok.
is(tok::less)) {
2204 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2209 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2212 protocolLAngleLoc, protocolRAngleLoc,
2216 assert(ObjCImpDecl);
2221 ObjCImplParsingDataRAII ObjCImplParsing(*
this, ObjCImpDecl);
2222 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2223 ParsedAttributesWithRange attrs(AttrFactory);
2224 MaybeParseCXX11Attributes(attrs);
2227 DeclsInGroup.append(DG.
begin(), DG.
end());
2232 return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup);
2236 Parser::ParseObjCAtEndDeclaration(
SourceRange atEnd) {
2238 "ParseObjCAtEndDeclaration(): Expected @end");
2240 if (CurParsedObjCImpl)
2241 CurParsedObjCImpl->finish(atEnd);
2244 Diag(atEnd.
getBegin(), diag::err_expected_objc_container);
2248 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2250 finish(
P.Tok.getLocation());
2251 if (
P.isEofOrEom()) {
2252 P.Diag(
P.Tok, diag::err_objc_missing_end)
2254 P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
2258 P.CurParsedObjCImpl =
nullptr;
2259 assert(LateParsedObjCMethods.empty());
2262 void Parser::ObjCImplParsingDataRAII::finish(
SourceRange AtEnd) {
2264 P.Actions.DefaultSynthesizeProperties(
P.getCurScope(), Dcl, AtEnd.
getBegin());
2265 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2266 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2269 P.Actions.ActOnAtEnd(
P.getCurScope(), AtEnd);
2272 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2273 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2277 for (LateParsedObjCMethodContainer::iterator
2278 I = LateParsedObjCMethods.begin(),
2279 E = LateParsedObjCMethods.end(); I != E; ++I)
2281 LateParsedObjCMethods.clear();
2291 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2293 if (expectIdentifier())
2297 if (expectIdentifier())
2301 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@compatibility_alias");
2302 return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
2319 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2323 if (Tok.
is(tok::code_completion)) {
2324 Actions.CodeCompleteObjCPropertyDefinition(
getCurScope());
2329 if (Tok.
isNot(tok::identifier)) {
2330 Diag(Tok, diag::err_synthesized_property_name);
2341 if (Tok.
is(tok::code_completion)) {
2342 Actions.CodeCompleteObjCPropertySynthesizeIvar(
getCurScope(), propertyId);
2347 if (expectIdentifier())
2349 propertyIvar = Tok.getIdentifierInfo();
2352 Actions.ActOnPropertyImplDecl(
2354 propertyId, propertyIvar, propertyIvarLoc,
2356 if (Tok.
isNot(tok::comma))
2360 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@synthesize");
2373 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2376 bool isClassProperty =
false;
2377 if (Tok.
is(tok::l_paren)) {
2382 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2386 if (II->
isStr(
"class")) {
2387 isClassProperty =
true;
2388 if (Tok.
isNot(tok::r_paren)) {
2389 Diag(Tok, diag::err_expected) << tok::r_paren;
2394 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2401 if (Tok.
is(tok::code_completion)) {
2402 Actions.CodeCompleteObjCPropertyDefinition(
getCurScope());
2407 if (expectIdentifier()) {
2414 Actions.ActOnPropertyImplDecl(
2420 if (Tok.
isNot(tok::comma))
2424 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@dynamic");
2434 if (Tok.
isNot(tok::semi)) {
2442 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@throw");
2443 return Actions.ActOnObjCAtThrowStmt(atLoc, Res.
get(),
getCurScope());
2452 if (Tok.
isNot(tok::l_paren)) {
2453 Diag(Tok, diag::err_expected_lparen_after) <<
"@synchronized";
2461 if (Tok.
is(tok::r_paren)) {
2465 Diag(Tok, diag::err_expected) << tok::r_paren;
2472 if (Tok.
isNot(tok::l_brace)) {
2474 Diag(Tok, diag::err_expected) << tok::l_brace;
2480 operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.
get());
2484 StmtResult body(ParseCompoundStatementBody());
2492 if (body.isInvalid())
2493 body = Actions.ActOnNullStmt(Tok.getLocation());
2495 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.
get(), body.get());
2510 bool catch_or_finally_seen =
false;
2513 if (Tok.
isNot(tok::l_brace)) {
2514 Diag(Tok, diag::err_expected) << tok::l_brace;
2517 StmtVector CatchStmts;
2520 StmtResult TryBody(ParseCompoundStatementBody());
2522 if (TryBody.isInvalid())
2523 TryBody = Actions.ActOnNullStmt(Tok.getLocation());
2525 while (Tok.
is(tok::at)) {
2529 Token AfterAt = GetLookAheadToken(1);
2536 Decl *FirstPart =
nullptr;
2538 if (Tok.
is(tok::l_paren)) {
2543 if (Tok.
isNot(tok::ellipsis)) {
2545 ParseDeclarationSpecifiers(DS);
2547 ParseDeclarator(ParmDecl);
2551 FirstPart = Actions.ActOnObjCExceptionDecl(
getCurScope(), ParmDecl);
2557 if (Tok.
is(tok::r_paren))
2558 RParenLoc = ConsumeParen();
2563 if (Tok.
is(tok::l_brace))
2564 CatchBody = ParseCompoundStatementBody();
2566 Diag(Tok, diag::err_expected) << tok::l_brace;
2567 if (CatchBody.isInvalid())
2568 CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
2570 StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
2574 if (!Catch.isInvalid())
2575 CatchStmts.push_back(Catch.get());
2578 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2582 catch_or_finally_seen =
true;
2584 assert(Tok.
isObjCAtKeyword(tok::objc_finally) &&
"Lookahead confused?");
2586 ParseScope FinallyScope(
this,
2590 if (Tok.
is(tok::l_brace))
2591 FinallyBody = ParseCompoundStatementBody();
2593 Diag(Tok, diag::err_expected) << tok::l_brace;
2594 if (FinallyBody.isInvalid())
2595 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
2596 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
2598 catch_or_finally_seen =
true;
2602 if (!catch_or_finally_seen) {
2603 Diag(atLoc, diag::err_missing_catch_finally);
2607 return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(),
2618 if (Tok.
isNot(tok::l_brace)) {
2619 Diag(Tok, diag::err_expected) << tok::l_brace;
2626 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2629 if (AutoreleasePoolBody.isInvalid())
2630 AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
2631 return Actions.ActOnObjCAutoreleasePoolStmt(atLoc,
2632 AutoreleasePoolBody.get());
2637 void Parser::StashAwayMethodOrFunctionBodyTokens(
Decl *MDecl) {
2638 if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
2639 trySkippingFunctionBody()) {
2640 Actions.ActOnSkippedFunctionBody(MDecl);
2644 LexedMethod* LM =
new LexedMethod(
this, MDecl);
2645 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2648 Toks.push_back(Tok);
2649 if (Tok.
is(tok::kw_try)) {
2651 if (Tok.
is(tok::colon)) {
2652 Toks.push_back(Tok);
2654 while (Tok.
isNot(tok::l_brace)) {
2655 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2656 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2659 Toks.push_back(Tok);
2661 else if (Tok.
is(tok::colon)) {
2664 while (Tok.
isNot(tok::l_brace)) {
2665 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2666 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2668 Toks.push_back(Tok);
2672 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2673 while (Tok.
is(tok::kw_catch)) {
2674 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
2675 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2681 Decl *Parser::ParseObjCMethodDefinition() {
2682 Decl *MDecl = ParseObjCMethodPrototype();
2685 "parsing Objective-C method");
2688 if (Tok.
is(tok::semi)) {
2689 if (CurParsedObjCImpl) {
2690 Diag(Tok, diag::warn_semicolon_before_method_body)
2697 if (Tok.
isNot(tok::l_brace)) {
2698 Diag(Tok, diag::err_expected_method_body);
2704 if (Tok.
isNot(tok::l_brace))
2715 Actions.AddAnyMethodToGlobalPool(MDecl);
2716 assert (CurParsedObjCImpl
2717 &&
"ParseObjCMethodDefinition - Method out of @implementation");
2719 StashAwayMethodOrFunctionBodyTokens(MDecl);
2724 if (Tok.
is(tok::code_completion)) {
2725 Actions.CodeCompleteObjCAtStatement(
getCurScope());
2731 return ParseObjCTryStmt(AtLoc);
2734 return ParseObjCThrowStmt(AtLoc);
2737 return ParseObjCSynchronizedStmt(AtLoc);
2740 return ParseObjCAutoreleasePoolStmt(AtLoc);
2745 return Actions.ActOnNullStmt(Tok.getLocation());
2748 ExprStatementTokLoc = AtLoc;
2749 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2759 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2760 return Actions.ActOnExprStmt(Res);
2764 switch (Tok.getKind()) {
2765 case tok::code_completion:
2766 Actions.CodeCompleteObjCAtExpression(
getCurScope());
2775 if (!Tok.
is(tok::numeric_constant)) {
2776 const char *Symbol =
nullptr;
2778 case tok::minus: Symbol =
"-";
break;
2779 case tok::plus: Symbol =
"+";
break;
2780 default: llvm_unreachable(
"missing unary operator case");
2782 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2787 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2788 if (Lit.isInvalid()) {
2793 Lit = Actions.ActOnUnaryOp(
getCurScope(), OpLoc, Kind, Lit.get());
2794 if (Lit.isInvalid())
2797 return ParsePostfixExpressionSuffix(
2798 Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()));
2801 case tok::string_literal:
2802 case tok::wide_string_literal:
2803 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2805 case tok::char_constant:
2806 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2808 case tok::numeric_constant:
2809 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2812 case tok::kw___objc_yes:
2813 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
true));
2815 case tok::kw___objc_no:
2816 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
false));
2820 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2824 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2828 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2831 if (Tok.getIdentifierInfo() ==
nullptr)
2834 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
2835 case tok::objc_encode:
2836 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2837 case tok::objc_protocol:
2838 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2839 case tok::objc_selector:
2840 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2841 case tok::objc_available:
2842 return ParseAvailabilityCheckExpr(AtLoc);
2844 const char *str =
nullptr;
2848 if (GetLookAheadToken(1).is(tok::l_brace) &&
2849 ExprStatementTokLoc == AtLoc) {
2850 char ch = Tok.getIdentifierInfo()->getNameStart()[0];
2853 : (ch ==
'f' ?
"finally" 2854 : (ch ==
'a' ?
"autoreleasepool" :
nullptr));
2890 bool Parser::ParseObjCXXMessageReceiver(
bool &IsExpr,
void *&TypeOrExpr) {
2893 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2894 tok::annot_cxxscope))
2897 if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
2908 TypeOrExpr = Receiver.
get();
2917 ParseCXXSimpleTypeSpecifier(DS);
2919 if (Tok.
is(tok::l_paren)) {
2932 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2934 Receiver = ParsePostfixExpressionSuffix(Receiver.
get());
2936 Receiver = ParseRHSOfBinaryExpression(Receiver.
get(),
prec::Comma);
2941 TypeOrExpr = Receiver.
get();
2954 TypeOrExpr = Type.
get().getAsOpaquePtr();
2963 bool Parser::isSimpleObjCMessageExpression() {
2965 "Incorrect start for isSimpleObjCMessageExpression");
2966 return GetLookAheadToken(1).is(tok::identifier) &&
2967 GetLookAheadToken(2).is(tok::identifier);
2970 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2972 InMessageExpression)
2977 if (Tok.
is(tok::annot_typename))
2979 else if (Tok.
is(tok::identifier))
2980 Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(),
2985 if (!Type.
get().isNull() && Type.
get()->isObjCObjectOrInterfaceType()) {
2986 const Token &AfterNext = GetLookAheadToken(2);
2987 if (AfterNext.
isOneOf(tok::colon, tok::r_square)) {
2988 if (Tok.
is(tok::identifier))
2991 return Tok.
is(tok::annot_typename);
3007 ExprResult Parser::ParseObjCMessageExpression() {
3008 assert(Tok.
is(tok::l_square) &&
"'[' expected");
3011 if (Tok.
is(tok::code_completion)) {
3012 Actions.CodeCompleteObjCMessageReceiver(
getCurScope());
3026 if (Tok.
is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
3028 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3033 void *TypeOrExpr =
nullptr;
3034 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
3040 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3041 static_cast<Expr *>(TypeOrExpr));
3043 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3048 if (Tok.
is(tok::identifier)) {
3052 switch (Actions.getObjCMessageKind(
getCurScope(), Name, NameLoc,
3053 Name == Ident_super,
3057 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
3061 if (!ReceiverType) {
3069 if (Tok.
is(tok::less)) {
3072 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3080 ReceiverType = NewReceiverType.
get();
3083 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3084 ReceiverType,
nullptr);
3099 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
nullptr,
3145 Expr *ReceiverExpr) {
3148 if (Tok.
is(tok::code_completion)) {
3152 else if (ReceiverType)
3153 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
None,
3156 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3168 ExprVector KeyExprs;
3170 if (Tok.
is(tok::colon)) {
3173 KeyIdents.push_back(selIdent);
3174 KeyLocs.push_back(Loc);
3176 if (ExpectAndConsume(tok::colon)) {
3186 if (Tok.
is(tok::code_completion)) {
3188 Actions.CodeCompleteObjCSuperMessage(
getCurScope(), SuperLoc,
3191 else if (ReceiverType)
3192 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
3196 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3206 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3207 Expr = ParseBraceInitializer();
3221 KeyExprs.push_back(Res.
get());
3224 if (Tok.
is(tok::code_completion)) {
3226 Actions.CodeCompleteObjCSuperMessage(
getCurScope(), SuperLoc,
3229 else if (ReceiverType)
3230 Actions.CodeCompleteObjCClassMessage(
getCurScope(), ReceiverType,
3234 Actions.CodeCompleteObjCInstanceMessage(
getCurScope(), ReceiverExpr,
3242 selIdent = ParseObjCSelectorPiece(Loc);
3243 if (!selIdent && Tok.
isNot(tok::colon))
3248 while (Tok.
is(tok::comma)) {
3252 if (Tok.
is(tok::colon))
3253 Res = Actions.CorrectDelayedTyposInExpr(Res);
3255 if (Tok.
is(tok::colon)) {
3256 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3267 KeyExprs.push_back(Res.
get());
3269 }
else if (!selIdent) {
3270 Diag(Tok, diag::err_expected) << tok::identifier;
3279 if (Tok.
isNot(tok::r_square)) {
3280 Diag(Tok, diag::err_expected)
3281 << (Tok.
is(tok::identifier) ? tok::colon : tok::r_square);
3291 unsigned nKeys = KeyIdents.size();
3293 KeyIdents.push_back(selIdent);
3294 KeyLocs.push_back(Loc);
3296 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
3299 return Actions.ActOnSuperMessage(
getCurScope(), SuperLoc, Sel,
3300 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3301 else if (ReceiverType)
3302 return Actions.ActOnClassMessage(
getCurScope(), ReceiverType, Sel,
3303 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3304 return Actions.ActOnInstanceMessage(
getCurScope(), ReceiverExpr, Sel,
3305 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3309 ExprResult Res(ParseStringLiteralExpression());
3316 ExprVector AtStrings;
3317 AtLocs.push_back(AtLoc);
3318 AtStrings.push_back(Res.
get());
3320 while (Tok.
is(tok::at)) {
3324 if (!isTokenStringLiteral())
3327 ExprResult Lit(ParseStringLiteralExpression());
3331 AtStrings.push_back(Lit.
get());
3334 return Actions.ParseObjCStringLiteral(AtLocs.data(), AtStrings);
3345 return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
3352 ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
3353 if (Lit.isInvalid()) {
3357 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3366 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
3367 if (Lit.isInvalid()) {
3371 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3379 if (Tok.
isNot(tok::l_paren))
3380 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@");
3394 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.
get());
3395 return Actions.BuildObjCBoxedExpr(
SourceRange(AtLoc, RPLoc),
3400 ExprVector ElementExprs;
3403 bool HasInvalidEltExpr =
false;
3404 while (Tok.
isNot(tok::r_square)) {
3415 Res = Actions.CorrectDelayedTyposInExpr(Res.
get());
3417 HasInvalidEltExpr =
true;
3420 if (Tok.
is(tok::ellipsis))
3423 HasInvalidEltExpr =
true;
3425 ElementExprs.push_back(Res.
get());
3427 if (Tok.
is(tok::comma))
3429 else if (Tok.
isNot(tok::r_square))
3430 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_square
3435 if (HasInvalidEltExpr)
3439 return Actions.BuildObjCArrayLiteral(
SourceRange(AtLoc, EndLoc), Args);
3445 bool HasInvalidEltExpr =
false;
3446 while (Tok.
isNot(tok::r_brace)) {
3461 if (ExpectAndConsume(tok::colon)) {
3476 KeyExpr = Actions.CorrectDelayedTyposInExpr(KeyExpr.
get());
3477 ValueExpr = Actions.CorrectDelayedTyposInExpr(ValueExpr.
get());
3479 HasInvalidEltExpr =
true;
3491 KeyExpr.
get(), ValueExpr.
get(), EllipsisLoc,
None 3493 Elements.push_back(Element);
3496 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_brace
3501 if (HasInvalidEltExpr)
3505 return Actions.BuildObjCDictionaryLiteral(
SourceRange(AtLoc, EndLoc),
3513 assert(Tok.
isObjCAtKeyword(tok::objc_encode) &&
"Not an @encode expression!");
3517 if (Tok.
isNot(tok::l_paren))
3518 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@encode");
3530 return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.
getOpenLocation(),
3540 if (Tok.
isNot(tok::l_paren))
3541 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@protocol");
3546 if (expectIdentifier())
3554 return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
3564 if (Tok.
isNot(tok::l_paren))
3565 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@selector");
3572 bool HasOptionalParen = Tok.
is(tok::l_paren);
3573 if (HasOptionalParen)
3576 if (Tok.
is(tok::code_completion)) {
3577 Actions.CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3584 Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3585 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3587 KeyIdents.push_back(SelIdent);
3589 unsigned nColons = 0;
3590 if (Tok.
isNot(tok::r_paren)) {
3594 KeyIdents.push_back(
nullptr);
3595 }
else if (ExpectAndConsume(tok::colon))
3599 if (Tok.
is(tok::r_paren))
3602 if (Tok.
is(tok::code_completion)) {
3603 Actions.CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3610 SelIdent = ParseObjCSelectorPiece(Loc);
3611 KeyIdents.push_back(SelIdent);
3612 if (!SelIdent && Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3616 if (HasOptionalParen && Tok.
is(tok::r_paren))
3619 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
3620 return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
3626 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM,
bool parseMethod) {
3628 Decl *MCDecl = LM.D;
3629 bool skip = MCDecl &&
3630 ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
3631 (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
3638 assert(!LM.Toks.empty() &&
"ParseLexedObjCMethodDef - Empty body!");
3644 Eof.setEofData(MCDecl);
3645 Eof.setLocation(OrigLoc);
3646 LM.Toks.push_back(Eof);
3649 LM.Toks.push_back(Tok);
3650 PP.EnterTokenStream(LM.Toks,
true);
3655 assert(Tok.
isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3656 "Inline objective-c method not starting with '{' or 'try' or ':'");
3665 Actions.ActOnStartOfObjCMethodDef(
getCurScope(), MCDecl);
3667 Actions.ActOnStartOfFunctionDef(
getCurScope(), MCDecl);
3668 if (Tok.
is(tok::kw_try))
3669 ParseFunctionTryBlock(MCDecl, BodyScope);
3671 if (Tok.
is(tok::colon))
3672 ParseConstructorInitializer(MCDecl);
3674 Actions.ActOnDefaultCtorInitializers(MCDecl);
3675 ParseFunctionStatementBody(MCDecl, BodyScope);
3678 if (Tok.getLocation() != OrigLoc) {
3684 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
AttributePool & getAttributePool() const
Defines the clang::ASTContext interface.
bool isUsedAsTypeAttr() const
AttributeList * ArgAttrs
ArgAttrs - Attribute list for this argument.
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.
static void takeDeclAttributes(ParsedAttributes &attrs, AttributeList *list)
Take all the decl attributes out of the given list and add them to the given attribute set...
AttributeList * getNext() const
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.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {...
void setPropertyAttributes(ObjCPropertyAttributeKind PRVal)
Decl - This represents one declaration (or definition), e.g.
RAII object used to inform the actions that we're currently parsing a declaration.
Captures information about "declaration specifiers" specific to Objective-C.
The base class of the type hierarchy.
SourceLocation getCloseLocation() const
This indicates that the scope corresponds to a function, which means that labels are set here...
The parameter is covariant, e.g., X<T> is a subtype of X<U> when the type parameter is covariant and ...
One instance of this struct is used for each type in a declarator that is parsed. ...
Wrapper for void* pointer.
Parser - This implements a parser for the C family of languages.
~ObjCTypeParamListScope()
void setObjCQualifiers(ObjCDeclSpec *quals)
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...
AttributeList * getList() const
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 { ...
std::pair< NullabilityKind, bool > DiagNullabilityKind
A nullability kind paired with a bit indicating whether it used a context-sensitive keyword...
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.
static ParsedType getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
void addAttributes(AttributeList *AL)
Concatenates two attribute lists.
Whether values of this type can be null is (explicitly) unspecified.
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
Values of this type can never be null.
Scope - A scope is a transient data structure that is used while parsing the program.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type...
IdentifierInfo * getIdentifier() const
DeclSpec & getMutableDeclSpec()
getMutableDeclSpec - Return a non-const version of the DeclSpec.
Sema - This implements semantic analysis and AST building for C.
bool acceptsObjCTypeParams() const
Determines if this is an ObjC interface type that may accept type parameters.
void setSetterName(IdentifierInfo *name, SourceLocation loc)
Expr - This represents one expression.
const FunctionProtoType * T
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.
AttributeList * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
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.
Context-sensitive version of a keyword attribute.
SourceLocation getLocStart() const LLVM_READONLY
ObjCDeclQualifier
ObjCDeclQualifier - Qualifier used on types in method declarations.
void CodeCompleteObjCAtDirective(Scope *S)
const AttributeList * getAttributes() const
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...
This is a scope that corresponds to the Objective-C @catch statement.
IdentifierInfo * getIdentifierInfo() const
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.
AttributeList *& getAttrListRef()
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.
const AttributeList * getAttrs() const
If there are attributes applied to this declaratorchunk, return them.
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)
void add(AttributeList *newAttr)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getNullabilityLoc() const
void setNullability(SourceLocation loc, NullabilityKind kind)
void setNext(AttributeList *N)
ActionResult< Stmt * > StmtResult
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
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.
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.
AttributeList - Represents a syntactic attribute.
Stop skipping at specified token, but don't skip the token itself.