22 #include "llvm/ADT/SmallVector.h"
23 #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);
50 if (Tok.
is(tok::code_completion)) {
56 Decl *SingleDecl =
nullptr;
59 return ParseObjCAtClassDeclaration(AtLoc);
60 case tok::objc_interface: {
62 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
65 case tok::objc_protocol: {
67 return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
69 case tok::objc_implementation:
70 return ParseObjCAtImplementationDeclaration(AtLoc);
72 return ParseObjCAtEndDeclaration(AtLoc);
73 case tok::objc_compatibility_alias:
74 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
76 case tok::objc_synthesize:
77 SingleDecl = ParseObjCPropertySynthesize(AtLoc);
79 case tok::objc_dynamic:
80 SingleDecl = ParseObjCPropertyDynamic(AtLoc);
82 case tok::objc_import:
84 return ParseModuleImport(AtLoc);
85 Diag(AtLoc, diag::err_atimport);
89 Diag(AtLoc, diag::err_unexpected_at);
112 MaybeSkipAttributes(tok::objc_class);
113 if (Tok.
isNot(tok::identifier)) {
114 Diag(Tok, diag::err_expected) << tok::identifier;
124 if (Tok.
is(tok::less)) {
125 TypeParams = parseObjCTypeParamList();
129 ClassTypeParams.push_back(TypeParams);
135 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@class"))
151 if (CurParsedObjCImpl) {
152 CurParsedObjCImpl->finish(AtLoc);
156 Diag(AtLoc, diag::err_objc_missing_end)
195 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
196 CheckNestedObjCContexts(AtLoc);
200 if (Tok.
is(tok::code_completion)) {
206 MaybeSkipAttributes(tok::objc_interface);
208 if (Tok.
isNot(tok::identifier)) {
209 Diag(Tok, diag::err_expected)
224 if (Tok.
is(tok::less)) {
225 typeParameterList = parseObjCTypeParamListOrProtocolRefs(LAngleLoc,
230 if (Tok.
is(tok::l_paren) &&
231 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
238 if (Tok.
is(tok::code_completion)) {
245 if (Tok.
is(tok::identifier)) {
250 Diag(Tok, diag::err_expected)
256 if (T.getCloseLocation().isInvalid())
259 if (!attrs.empty()) {
260 Diag(nameLoc, diag::err_objc_no_attributes_on_category);
265 assert(LAngleLoc.
isInvalid() &&
"Cannot have already parsed protocols");
268 if (Tok.
is(tok::less) &&
269 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
true,
true,
270 LAngleLoc, EndProtoLoc,
278 categoryId, categoryLoc,
284 if (Tok.
is(tok::l_brace))
285 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
287 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
289 if (typeParameterList)
302 if (Tok.
is(tok::colon)) {
306 if (Tok.
is(tok::code_completion)) {
312 if (Tok.
isNot(tok::identifier)) {
313 Diag(Tok, diag::err_expected)
321 if (Tok.
is(tok::less)) {
322 parseObjCTypeArgsOrProtocolQualifiers(
ParsedType(),
337 if (!ProtocolIdents.empty()) {
340 for (
const auto &pair : ProtocolIdents) {
341 protocolLocs.push_back(pair.second);
345 &ProtocolIdents[0], ProtocolIdents.size(),
348 }
else if (protocols.empty() && Tok.
is(tok::less) &&
349 ParseObjCProtocolReferences(protocols, protocolLocs,
true,
true,
350 LAngleLoc, EndProtoLoc,
355 if (Tok.
isNot(tok::less))
360 typeParameterList, superClassId,
365 protocols.data(), protocols.size(),
367 EndProtoLoc, attrs.getList());
369 if (Tok.
is(tok::l_brace))
370 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
372 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
374 if (typeParameterList)
386 bool &addedToDeclSpec) {
399 auto nullabilityAttr = getNullabilityAttr();
403 }
else if (!addedToDeclSpec) {
407 addedToDeclSpec =
true;
439 bool mayBeProtocolList) {
440 assert(Tok.
is(tok::less) &&
"Not at the beginning of a type parameter list");
448 auto makeProtocolIdentsIntoTypeParameters = [&]() {
450 for (
const auto &pair : protocolIdents) {
461 typeParams.push_back(typeParam.
get());
464 protocolIdents.clear();
465 mayBeProtocolList =
false;
468 bool invalid =
false;
475 if (Tok.
is(tok::kw___covariant) || Tok.
is(tok::kw___contravariant)) {
476 variance = Tok.
is(tok::kw___covariant)
483 if (mayBeProtocolList) {
486 makeProtocolIdentsIntoTypeParameters();
491 if (!Tok.
is(tok::identifier)) {
493 if (Tok.
is(tok::code_completion)) {
497 protocolIdents.size());
504 Diag(Tok, diag::err_objc_expected_type_parameter);
518 if (mayBeProtocolList) {
521 makeProtocolIdentsIntoTypeParameters();
528 }
else if (mayBeProtocolList) {
531 protocolIdents.push_back(std::make_pair(paramName, paramLoc));
547 typeParams.push_back(typeParam.
get());
553 if (Tok.
is(tok::greater))
555 }
else if (ParseGreaterThanInTemplateList(rAngleLoc,
558 Diag(lAngleLoc, diag::note_matching) <<
"'<'";
559 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
560 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
561 tok::comma, tok::semi },
563 if (Tok.
is(tok::greater))
567 if (mayBeProtocolList) {
572 if (Tok.
isNot(tok::colon) && Tok.
isNot(tok::l_paren)) {
581 makeProtocolIdentsIntoTypeParameters();
603 return parseObjCTypeParamListOrProtocolRefs(lAngleLoc, protocolIdents,
631 if (Tok.
isOneOf(tok::minus, tok::plus)) {
632 if (Decl *methodPrototype =
633 ParseObjCMethodPrototype(MethodImplKind,
false))
634 allMethods.push_back(methodPrototype);
637 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
640 if (Tok.
is(tok::semi))
645 if (Tok.
is(tok::l_paren)) {
646 Diag(Tok, diag::err_expected_minus_or_plus);
649 MethodImplKind,
false);
653 if (Tok.
is(tok::semi)) {
663 if (Tok.
is(tok::code_completion)) {
667 return cutOffParsing();
671 if (Tok.
isNot(tok::at)) {
675 if (Tok.
is(tok::r_brace))
677 ParsedAttributesWithRange attrs(AttrFactory);
678 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
684 if (Tok.
is(tok::code_completion)) {
686 return cutOffParsing();
691 if (DirectiveKind == tok::objc_end) {
695 }
else if (DirectiveKind == tok::objc_not_keyword) {
696 Diag(Tok, diag::err_objc_unknown_at);
704 switch (DirectiveKind) {
710 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
715 case tok::objc_implementation:
716 case tok::objc_interface:
717 Diag(AtLoc, diag::err_objc_missing_end)
720 << (
int) Actions.getObjCContainerKind();
724 case tok::objc_required:
725 case tok::objc_optional:
728 if (contextKey != tok::objc_protocol)
729 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
731 MethodImplKind = DirectiveKind;
734 case tok::objc_property:
736 Diag(AtLoc, diag::err_objc_properties_require_objc2);
741 if (Tok.is(tok::l_paren)) {
743 ParseObjCPropertyAttribute(OCDS);
746 bool addedToDeclSpec =
false;
748 if (FD.D.getIdentifier() ==
nullptr) {
749 Diag(AtLoc, diag::err_objc_property_requires_field_name)
750 << FD.D.getSourceRange();
753 if (FD.BitfieldSize) {
754 Diag(AtLoc, diag::err_objc_property_bitfield)
755 << FD.D.getSourceRange();
778 FD.D.getIdentifier());
779 bool isOverridingProperty =
false;
781 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
782 &isOverridingProperty, MethodImplKind);
783 if (!isOverridingProperty)
784 allProperties.push_back(Property);
786 FD.complete(Property);
791 ParseStructDeclaration(DS, ObjCPropertyCallback);
793 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
800 if (Tok.
is(tok::code_completion)) {
802 return cutOffParsing();
806 Diag(Tok, diag::err_objc_missing_end)
809 << (
int) Actions.getObjCContainerKind();
810 AtEnd.setBegin(Tok.getLocation());
811 AtEnd.setEnd(Tok.getLocation());
816 Actions.ActOnAtEnd(
getCurScope(), AtEnd, allMethods, allTUVariables);
824 if (DS.getNullability() == nullability) {
825 P.Diag(nullabilityLoc, diag::warn_nullability_duplicate)
831 P.Diag(nullabilityLoc, diag::err_nullability_conflicting)
861 void Parser::ParseObjCPropertyAttribute(
ObjCDeclSpec &DS) {
862 assert(Tok.
getKind() == tok::l_paren);
867 if (Tok.
is(tok::code_completion)) {
869 return cutOffParsing();
881 if (II->
isStr(
"readonly"))
883 else if (II->
isStr(
"assign"))
885 else if (II->
isStr(
"unsafe_unretained"))
887 else if (II->
isStr(
"readwrite"))
889 else if (II->
isStr(
"retain"))
891 else if (II->
isStr(
"strong"))
893 else if (II->
isStr(
"copy"))
895 else if (II->
isStr(
"nonatomic"))
897 else if (II->
isStr(
"atomic"))
899 else if (II->
isStr(
"weak"))
901 else if (II->
isStr(
"getter") || II->
isStr(
"setter")) {
905 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
906 diag::err_objc_expected_equal_for_getter;
908 if (ExpectAndConsume(tok::equal, DiagID)) {
913 if (Tok.
is(tok::code_completion)) {
918 return cutOffParsing();
926 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
936 if (ExpectAndConsume(tok::colon,
937 diag::err_expected_colon_after_setter_name)) {
945 }
else if (II->
isStr(
"nonnull")) {
952 }
else if (II->
isStr(
"nullable")) {
959 }
else if (II->
isStr(
"null_unspecified")) {
966 }
else if (II->
isStr(
"null_resettable")) {
977 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
982 if (Tok.
isNot(tok::comma))
1002 bool MethodDefinition) {
1003 assert(Tok.
isOneOf(tok::minus, tok::plus) &&
"expected +/-");
1007 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
1033 case tok::exclaimequal:
1035 case tok::pipeequal:
1037 case tok::caretequal: {
1048 case tok::identifier:
1058 case tok::kw_const_cast:
1059 case tok::kw_continue:
1060 case tok::kw_default:
1061 case tok::kw_delete:
1063 case tok::kw_double:
1064 case tok::kw_dynamic_cast:
1067 case tok::kw_explicit:
1068 case tok::kw_export:
1069 case tok::kw_extern:
1073 case tok::kw_friend:
1076 case tok::kw_inline:
1079 case tok::kw_mutable:
1080 case tok::kw_namespace:
1082 case tok::kw_operator:
1083 case tok::kw_private:
1084 case tok::kw_protected:
1085 case tok::kw_public:
1086 case tok::kw_register:
1087 case tok::kw_reinterpret_cast:
1088 case tok::kw_restrict:
1089 case tok::kw_return:
1091 case tok::kw_signed:
1092 case tok::kw_sizeof:
1093 case tok::kw_static:
1094 case tok::kw_static_cast:
1095 case tok::kw_struct:
1096 case tok::kw_switch:
1097 case tok::kw_template:
1102 case tok::kw_typedef:
1103 case tok::kw_typeid:
1104 case tok::kw_typename:
1105 case tok::kw_typeof:
1107 case tok::kw_unsigned:
1109 case tok::kw_virtual:
1111 case tok::kw_volatile:
1112 case tok::kw_wchar_t:
1115 case tok::kw__Complex:
1116 case tok::kw___alignof:
1125 bool Parser::isTokIdentifier_in()
const {
1152 void Parser::ParseObjCTypeQualifierList(
ObjCDeclSpec &DS,
1158 if (Tok.
is(tok::code_completion)) {
1161 return cutOffParsing();
1164 if (Tok.
isNot(tok::identifier))
1168 for (
unsigned i = 0; i != objc_NumQuals; ++i) {
1169 if (II != ObjCTypeQuals[i] ||
1177 default: llvm_unreachable(
"Unknown decl qualifier");
1195 case objc_null_unspecified:
1259 assert((paramAttrs !=
nullptr) ==
1262 assert(Tok.
is(tok::l_paren) &&
"expected (");
1271 ParseObjCTypeQualifierList(DS, context);
1274 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1277 declSpec.setObjCQualifiers(&DS);
1278 DeclSpecContext dsContext = DSC_normal;
1280 dsContext = DSC_objc_method_result;
1281 ParseSpecifierQualifierList(declSpec,
AS_none, dsContext);
1284 ParseDeclarator(declarator);
1287 if (!declarator.isInvalidType()) {
1289 bool addedToDeclSpec =
false;
1307 if (Tok.
is(tok::r_paren))
1311 Diag(Tok, diag::err_expected_type);
1352 bool MethodDefinition) {
1355 if (Tok.
is(tok::code_completion)) {
1365 if (Tok.
is(tok::l_paren))
1372 MaybeParseGNUAttributes(methodAttrs);
1374 if (Tok.
is(tok::code_completion)) {
1386 if (!SelIdent && Tok.
isNot(tok::colon)) {
1387 Diag(Tok, diag::err_expected_selector_for_method)
1395 if (Tok.
isNot(tok::colon)) {
1398 MaybeParseGNUAttributes(methodAttrs);
1403 mType, DSRet, ReturnType,
1404 selLoc, Sel,
nullptr,
1405 CParamInfo.data(), CParamInfo.size(),
1406 methodAttrs.getList(), MethodImplKind,
1407 false, MethodDefinition);
1408 PD.complete(Result);
1424 if (ExpectAndConsume(tok::colon))
1428 if (Tok.
is(tok::l_paren))
1437 MaybeParseGNUAttributes(paramAttrs);
1442 if (Tok.
is(tok::code_completion)) {
1443 KeyIdents.push_back(SelIdent);
1445 mType == tok::minus,
1447 ReturnType, KeyIdents);
1452 if (Tok.
isNot(tok::identifier)) {
1453 Diag(Tok, diag::err_expected)
1462 ArgInfos.push_back(ArgInfo);
1463 KeyIdents.push_back(SelIdent);
1464 KeyLocs.push_back(selLoc);
1467 allParamAttrs.takeAllFrom(paramAttrs.
getPool());
1470 if (Tok.
is(tok::code_completion)) {
1472 mType == tok::minus,
1474 ReturnType, KeyIdents);
1480 SelIdent = ParseObjCSelectorPiece(selLoc);
1481 if (!SelIdent && Tok.
isNot(tok::colon))
1486 Diag(ArgInfo.
NameLoc, diag::warn_missing_selector_name) << ArgInfo.
Name;
1487 Diag(ArgInfo.
NameLoc, diag::note_missing_selector_name) << ArgInfo.
Name;
1488 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.
Name;
1494 bool isVariadic =
false;
1495 bool cStyleParamWarned =
false;
1497 while (Tok.
is(tok::comma)) {
1499 if (Tok.
is(tok::ellipsis)) {
1504 if (!cStyleParamWarned) {
1505 Diag(Tok, diag::warn_cstyle_param);
1506 cStyleParamWarned =
true;
1509 ParseDeclarationSpecifiers(DS);
1512 ParseDeclarator(ParmDecl);
1516 ParmDecl.getIdentifierLoc(),
1524 MaybeParseGNUAttributes(methodAttrs);
1526 if (KeyIdents.size() == 0)
1533 mType, DSRet, ReturnType,
1534 KeyLocs, Sel, &ArgInfos[0],
1535 CParamInfo.data(), CParamInfo.size(),
1536 methodAttrs.getList(),
1537 MethodImplKind, isVariadic, MethodDefinition);
1539 PD.complete(Result);
1549 bool WarnOnDeclarations,
bool ForObjCContainer,
1551 bool consumeLastToken) {
1552 assert(Tok.
is(tok::less) &&
"expected <");
1559 if (Tok.
is(tok::code_completion)) {
1561 ProtocolIdents.size());
1566 if (Tok.
isNot(tok::identifier)) {
1567 Diag(Tok, diag::err_expected) << tok::identifier;
1581 if (ParseGreaterThanInTemplateList(EndLoc, consumeLastToken,
1587 &ProtocolIdents[0], ProtocolIdents.size(),
1593 assert(Tok.
is(tok::less) &&
"Protocol qualifiers start with '<'");
1594 assert(
getLangOpts().ObjC1 &&
"Protocol qualifiers only exist in Objective-C");
1599 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
false,
false,
1600 lAngleLoc, rAngleLoc,
1607 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1620 void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1629 bool consumeLastToken,
1630 bool warnOnIncompleteProtocols) {
1631 assert(Tok.
is(tok::less) &&
"Not at the start of type args or protocols");
1636 bool allSingleIdentifiers =
true;
1644 if (Tok.
is(tok::identifier) &&
1653 if (Tok.
is(tok::code_completion)) {
1656 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1658 identifierLocs[i]));
1666 identifierLocPairs.size());
1672 allSingleIdentifiers =
false;
1678 if (allSingleIdentifiers) {
1681 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1697 warnOnIncompleteProtocols);
1705 bool invalid =
false;
1706 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1711 const char *prevSpec =
nullptr;
1713 DS.SetTypeSpecType(
TST_typename, identifierLocs[i], prevSpec, diagID,
1720 typeArgs.push_back(fullTypeArg.
get());
1740 typeArgs.push_back(typeArg.
get());
1748 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1757 typeArgsLAngleLoc = lAngleLoc;
1758 typeArgsRAngleLoc = rAngleLoc;
1761 void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1770 bool consumeLastToken) {
1771 assert(Tok.
is(tok::less));
1774 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1788 if ((consumeLastToken && Tok.
is(tok::less)) ||
1789 (!consumeLastToken &&
NextToken().
is(tok::less))) {
1792 if (!consumeLastToken)
1795 if (!protocols.empty()) {
1797 if (!consumeLastToken)
1799 Diag(Tok, diag::err_objc_type_args_after_protocols)
1800 <<
SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1801 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1803 ParseObjCProtocolReferences(protocols, protocolLocs,
1806 protocolLAngleLoc, protocolRAngleLoc,
1812 TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1815 bool consumeLastToken,
1817 assert(Tok.
is(tok::less));
1827 parseObjCTypeArgsAndProtocolQualifiers(type, typeArgsLAngleLoc, typeArgs,
1828 typeArgsRAngleLoc, protocolLAngleLoc,
1829 protocols, protocolLocs,
1830 protocolRAngleLoc, consumeLastToken);
1833 if (consumeLastToken)
1834 endLoc = PrevTokLocation;
1851 void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl,
SourceLocation atLoc,
1854 bool RBraceMissing) {
1888 void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
1891 assert(Tok.
is(tok::l_brace) &&
"expected {");
1900 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
1904 if (Tok.
is(tok::semi)) {
1905 ConsumeExtraSemi(InstanceVariableList);
1911 if (Tok.
is(tok::code_completion)) {
1913 return cutOffParsing();
1917 case tok::objc_private:
1918 case tok::objc_public:
1919 case tok::objc_protected:
1920 case tok::objc_package:
1926 Diag(Tok, diag::err_objc_unexpected_atend);
1931 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1932 T, AllIvarDecls,
true);
1936 Diag(Tok, diag::err_objc_illegal_visibility_spec);
1941 if (Tok.
is(tok::code_completion)) {
1944 return cutOffParsing();
1950 FD.D.setObjCIvar(
true);
1952 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
1953 FD.BitfieldSize, visibility);
1956 AllIvarDecls.push_back(Field);
1962 ParseStructDeclaration(DS, ObjCIvarCallback);
1964 if (Tok.
is(tok::semi)) {
1967 Diag(Tok, diag::err_expected_semi_decl_list);
1972 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1973 T, AllIvarDecls,
false);
1997 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2000 if (Tok.
is(tok::code_completion)) {
2006 MaybeSkipAttributes(tok::objc_protocol);
2008 if (Tok.
isNot(tok::identifier)) {
2009 Diag(Tok, diag::err_expected) << tok::identifier;
2022 CheckNestedObjCContexts(AtLoc);
2024 if (Tok.
is(tok::comma)) {
2026 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2031 if (Tok.
isNot(tok::identifier)) {
2032 Diag(Tok, diag::err_expected) << tok::identifier;
2040 if (Tok.
isNot(tok::comma))
2044 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@protocol"))
2049 ProtocolRefs.size(),
2058 if (Tok.
is(tok::less) &&
2059 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
false,
true,
2060 LAngleLoc, EndProtoLoc,
2066 ProtocolRefs.data(),
2067 ProtocolRefs.size(),
2068 ProtocolLocs.data(),
2069 EndProtoLoc, attrs.
getList());
2071 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2086 Parser::ParseObjCAtImplementationDeclaration(
SourceLocation AtLoc) {
2088 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2089 CheckNestedObjCContexts(AtLoc);
2093 if (Tok.
is(tok::code_completion)) {
2099 MaybeSkipAttributes(tok::objc_implementation);
2101 if (Tok.
isNot(tok::identifier)) {
2102 Diag(Tok, diag::err_expected)
2109 Decl *ObjCImpDecl =
nullptr;
2113 if (Tok.
is(tok::less)) {
2117 if (parseObjCTypeParamListOrProtocolRefs(lAngleLoc, protocolIdents,
2119 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2121 }
else if (lAngleLoc.
isValid()) {
2122 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2127 if (Tok.
is(tok::l_paren)) {
2133 if (Tok.
is(tok::code_completion)) {
2139 if (Tok.
is(tok::identifier)) {
2143 Diag(Tok, diag::err_expected)
2147 if (Tok.
isNot(tok::r_paren)) {
2148 Diag(Tok, diag::err_expected) << tok::r_paren;
2152 rparenLoc = ConsumeParen();
2153 if (Tok.
is(tok::less)) {
2154 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2158 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2161 protocolLAngleLoc, protocolRAngleLoc,
2165 AtLoc, nameId, nameLoc, categoryId,
2174 if (Tok.
isNot(tok::identifier)) {
2175 Diag(Tok, diag::err_expected)
2183 AtLoc, nameId, nameLoc,
2184 superClassId, superClassLoc);
2186 if (Tok.
is(tok::l_brace))
2187 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2188 else if (Tok.
is(tok::less)) {
2189 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2194 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2197 protocolLAngleLoc, protocolRAngleLoc,
2201 assert(ObjCImpDecl);
2206 ObjCImplParsingDataRAII ObjCImplParsing(*
this, ObjCImpDecl);
2207 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2208 ParsedAttributesWithRange attrs(AttrFactory);
2209 MaybeParseCXX11Attributes(attrs);
2210 MaybeParseMicrosoftAttributes(attrs);
2213 DeclsInGroup.append(DG.
begin(), DG.
end());
2222 Parser::ParseObjCAtEndDeclaration(
SourceRange atEnd) {
2224 "ParseObjCAtEndDeclaration(): Expected @end");
2226 if (CurParsedObjCImpl)
2227 CurParsedObjCImpl->finish(atEnd);
2230 Diag(atEnd.
getBegin(), diag::err_expected_objc_container);
2234 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2236 finish(
P.Tok.getLocation());
2237 if (
P.isEofOrEom()) {
2238 P.Diag(
P.Tok, diag::err_objc_missing_end)
2240 P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
2244 P.CurParsedObjCImpl =
nullptr;
2245 assert(LateParsedObjCMethods.empty());
2248 void Parser::ObjCImplParsingDataRAII::finish(
SourceRange AtEnd) {
2250 P.Actions.DefaultSynthesizeProperties(
P.getCurScope(), Dcl);
2251 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2252 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2255 P.Actions.ActOnAtEnd(
P.getCurScope(), AtEnd);
2258 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2259 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2263 for (LateParsedObjCMethodContainer::iterator
2264 I = LateParsedObjCMethods.begin(),
2265 E = LateParsedObjCMethods.end(); I != E; ++I)
2267 LateParsedObjCMethods.clear();
2275 Decl *Parser::ParseObjCAtAliasDeclaration(
SourceLocation atLoc) {
2277 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2279 if (Tok.
isNot(tok::identifier)) {
2280 Diag(Tok, diag::err_expected) << tok::identifier;
2285 if (Tok.
isNot(tok::identifier)) {
2286 Diag(Tok, diag::err_expected) << tok::identifier;
2291 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@compatibility_alias");
2307 Decl *Parser::ParseObjCPropertySynthesize(
SourceLocation atLoc) {
2309 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2313 if (Tok.
is(tok::code_completion)) {
2319 if (Tok.
isNot(tok::identifier)) {
2320 Diag(Tok, diag::err_synthesized_property_name);
2331 if (Tok.
is(tok::code_completion)) {
2337 if (Tok.
isNot(tok::identifier)) {
2338 Diag(Tok, diag::err_expected) << tok::identifier;
2345 propertyId, propertyIvar, propertyIvarLoc);
2346 if (Tok.
isNot(tok::comma))
2350 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@synthesize");
2363 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2366 if (Tok.
is(tok::code_completion)) {
2372 if (Tok.
isNot(tok::identifier)) {
2373 Diag(Tok, diag::err_expected) << tok::identifier;
2383 if (Tok.
isNot(tok::comma))
2387 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@dynamic");
2397 if (Tok.
isNot(tok::semi)) {
2405 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@throw");
2415 if (Tok.
isNot(tok::l_paren)) {
2416 Diag(Tok, diag::err_expected_lparen_after) <<
"@synchronized";
2424 if (Tok.
is(tok::r_paren)) {
2427 if (!operand.isInvalid())
2428 Diag(Tok, diag::err_expected) << tok::r_paren;
2435 if (Tok.
isNot(tok::l_brace)) {
2436 if (!operand.isInvalid())
2437 Diag(Tok, diag::err_expected) << tok::l_brace;
2442 if (!operand.isInvalid())
2447 StmtResult body(ParseCompoundStatementBody());
2452 if (operand.isInvalid())
2455 if (body.isInvalid())
2473 bool catch_or_finally_seen =
false;
2476 if (Tok.
isNot(tok::l_brace)) {
2477 Diag(Tok, diag::err_expected) << tok::l_brace;
2480 StmtVector CatchStmts;
2483 StmtResult TryBody(ParseCompoundStatementBody());
2485 if (TryBody.isInvalid())
2488 while (Tok.
is(tok::at)) {
2492 Token AfterAt = GetLookAheadToken(1);
2499 Decl *FirstPart =
nullptr;
2501 if (Tok.
is(tok::l_paren)) {
2504 if (Tok.
isNot(tok::ellipsis)) {
2506 ParseDeclarationSpecifiers(DS);
2508 ParseDeclarator(ParmDecl);
2518 if (Tok.
is(tok::r_paren))
2519 RParenLoc = ConsumeParen();
2524 if (Tok.
is(tok::l_brace))
2525 CatchBody = ParseCompoundStatementBody();
2527 Diag(Tok, diag::err_expected) << tok::l_brace;
2528 if (CatchBody.isInvalid())
2536 CatchStmts.push_back(Catch.
get());
2539 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2543 catch_or_finally_seen =
true;
2545 assert(Tok.
isObjCAtKeyword(tok::objc_finally) &&
"Lookahead confused?");
2550 if (Tok.
is(tok::l_brace))
2551 FinallyBody = ParseCompoundStatementBody();
2553 Diag(Tok, diag::err_expected) << tok::l_brace;
2554 if (FinallyBody.isInvalid())
2558 catch_or_finally_seen =
true;
2562 if (!catch_or_finally_seen) {
2563 Diag(atLoc, diag::err_missing_catch_finally);
2578 if (Tok.
isNot(tok::l_brace)) {
2579 Diag(Tok, diag::err_expected) << tok::l_brace;
2586 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2589 if (AutoreleasePoolBody.isInvalid())
2592 AutoreleasePoolBody.get());
2597 void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
2598 LexedMethod* LM =
new LexedMethod(
this, MDecl);
2599 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2602 Toks.push_back(Tok);
2603 if (Tok.
is(tok::kw_try)) {
2605 if (Tok.
is(tok::colon)) {
2606 Toks.push_back(Tok);
2608 while (Tok.
isNot(tok::l_brace)) {
2609 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2610 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2613 Toks.push_back(Tok);
2615 else if (Tok.
is(tok::colon)) {
2617 while (Tok.
isNot(tok::l_brace)) {
2618 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2619 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2621 Toks.push_back(Tok);
2625 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2626 while (Tok.
is(tok::kw_catch)) {
2627 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
2628 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2634 Decl *Parser::ParseObjCMethodDefinition() {
2635 Decl *MDecl = ParseObjCMethodPrototype();
2638 "parsing Objective-C method");
2641 if (Tok.
is(tok::semi)) {
2642 if (CurParsedObjCImpl) {
2643 Diag(Tok, diag::warn_semicolon_before_method_body)
2650 if (Tok.
isNot(tok::l_brace)) {
2651 Diag(Tok, diag::err_expected_method_body);
2657 if (Tok.
isNot(tok::l_brace))
2669 assert (CurParsedObjCImpl
2670 &&
"ParseObjCMethodDefinition - Method out of @implementation");
2672 StashAwayMethodOrFunctionBodyTokens(MDecl);
2677 if (Tok.
is(tok::code_completion)) {
2684 return ParseObjCTryStmt(AtLoc);
2687 return ParseObjCThrowStmt(AtLoc);
2690 return ParseObjCSynchronizedStmt(AtLoc);
2693 return ParseObjCAutoreleasePoolStmt(AtLoc);
2701 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2711 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2717 case tok::code_completion:
2727 if (!Tok.
is(tok::numeric_constant)) {
2728 const char *Symbol =
nullptr;
2730 case tok::minus: Symbol =
"-";
break;
2731 case tok::plus: Symbol =
"+";
break;
2732 default: llvm_unreachable(
"missing unary operator case");
2734 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2740 if (Lit.isInvalid()) {
2746 if (Lit.isInvalid())
2749 return ParsePostfixExpressionSuffix(
2753 case tok::string_literal:
2754 case tok::wide_string_literal:
2755 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2757 case tok::char_constant:
2758 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2760 case tok::numeric_constant:
2761 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2764 case tok::kw___objc_yes:
2765 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
true));
2767 case tok::kw___objc_no:
2768 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
false));
2772 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2776 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2780 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2787 case tok::objc_encode:
2788 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2789 case tok::objc_protocol:
2790 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2791 case tok::objc_selector:
2792 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2794 const char *str =
nullptr;
2795 if (GetLookAheadToken(1).is(tok::l_brace)) {
2799 : (ch ==
'f' ?
"finally"
2800 : (ch ==
'a' ?
"autoreleasepool" :
nullptr));
2836 bool Parser::ParseObjCXXMessageReceiver(
bool &IsExpr,
void *&TypeOrExpr) {
2839 if (Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2840 tok::annot_cxxscope))
2854 TypeOrExpr = Receiver.
get();
2863 ParseCXXSimpleTypeSpecifier(DS);
2865 if (Tok.
is(tok::l_paren)) {
2878 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2880 Receiver = ParsePostfixExpressionSuffix(Receiver.
get());
2882 Receiver = ParseRHSOfBinaryExpression(Receiver.
get(),
prec::Comma);
2887 TypeOrExpr = Receiver.
get();
2900 TypeOrExpr = Type.
get().getAsOpaquePtr();
2909 bool Parser::isSimpleObjCMessageExpression() {
2911 "Incorrect start for isSimpleObjCMessageExpression");
2912 return GetLookAheadToken(1).
is(tok::identifier) &&
2913 GetLookAheadToken(2).
is(tok::identifier);
2916 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2918 InMessageExpression)
2924 if (Tok.
is(tok::annot_typename))
2926 else if (Tok.
is(tok::identifier))
2933 const Token &AfterNext = GetLookAheadToken(2);
2934 if (AfterNext.
isOneOf(tok::colon, tok::r_square)) {
2935 if (Tok.
is(tok::identifier))
2938 return Tok.
is(tok::annot_typename);
2954 ExprResult Parser::ParseObjCMessageExpression() {
2955 assert(Tok.
is(tok::l_square) &&
"'[' expected");
2958 if (Tok.
is(tok::code_completion)) {
2975 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
2980 void *TypeOrExpr =
nullptr;
2981 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
2987 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
2989 static_cast<Expr*>(TypeOrExpr));
2991 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
2996 if (Tok.
is(tok::identifier)) {
3001 Name == Ident_super,
3005 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
3009 if (!ReceiverType) {
3017 if (Tok.
is(tok::less)) {
3020 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3028 ReceiverType = NewReceiverType.
get();
3031 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3032 ReceiverType,
nullptr);
3047 return ParseObjCMessageExpressionBody(LBracLoc,
SourceLocation(),
3093 Expr *ReceiverExpr) {
3096 if (Tok.
is(tok::code_completion)) {
3100 else if (ReceiverType)
3116 ExprVector KeyExprs;
3118 if (Tok.
is(tok::colon)) {
3121 KeyIdents.push_back(selIdent);
3122 KeyLocs.push_back(Loc);
3124 if (ExpectAndConsume(tok::colon)) {
3134 if (Tok.
is(tok::code_completion)) {
3139 else if (ReceiverType)
3154 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3155 Expr = ParseBraceInitializer();
3169 KeyExprs.push_back(Res.
get());
3172 if (Tok.
is(tok::code_completion)) {
3177 else if (ReceiverType)
3190 selIdent = ParseObjCSelectorPiece(Loc);
3191 if (!selIdent && Tok.
isNot(tok::colon))
3196 while (Tok.
is(tok::comma)) {
3200 if (Tok.
is(tok::colon))
3203 if (Tok.
is(tok::colon)) {
3204 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3215 KeyExprs.push_back(Res.
get());
3217 }
else if (!selIdent) {
3218 Diag(Tok, diag::err_expected) << tok::identifier;
3227 if (Tok.
isNot(tok::r_square)) {
3228 Diag(Tok, diag::err_expected)
3229 << (Tok.
is(tok::identifier) ? tok::colon : tok::r_square);
3239 unsigned nKeys = KeyIdents.size();
3241 KeyIdents.push_back(selIdent);
3242 KeyLocs.push_back(Loc);
3248 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3249 else if (ReceiverType)
3251 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3253 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3257 ExprResult Res(ParseStringLiteralExpression());
3264 ExprVector AtStrings;
3265 AtLocs.push_back(AtLoc);
3266 AtStrings.push_back(Res.
get());
3268 while (Tok.
is(tok::at)) {
3272 if (!isTokenStringLiteral())
3275 ExprResult Lit(ParseStringLiteralExpression());
3276 if (Lit.isInvalid())
3279 AtStrings.push_back(Lit.get());
3302 if (Lit.isInvalid()) {
3316 if (Lit.isInvalid()) {
3328 if (Tok.
isNot(tok::l_paren))
3329 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@");
3337 if (ValueExpr.isInvalid())
3343 ValueExpr = Actions.
ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
3349 ExprVector ElementExprs;
3352 while (Tok.
isNot(tok::r_square)) {
3364 if (Tok.
is(tok::ellipsis))
3369 ElementExprs.push_back(Res.
get());
3371 if (Tok.
is(tok::comma))
3373 else if (Tok.
isNot(tok::r_square))
3374 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_square
3385 while (Tok.
isNot(tok::r_brace)) {
3400 if (ExpectAndConsume(tok::colon)) {
3406 if (ValueExpr.isInvalid()) {
3422 KeyExpr.
get(), ValueExpr.get(), EllipsisLoc,
None
3424 Elements.push_back(Element);
3427 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_brace
3434 Elements.data(), Elements.size());
3441 assert(Tok.
isObjCAtKeyword(tok::objc_encode) &&
"Not an @encode expression!");
3445 if (Tok.
isNot(tok::l_paren))
3446 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@encode");
3468 if (Tok.
isNot(tok::l_paren))
3469 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@protocol");
3474 if (Tok.
isNot(tok::identifier))
3475 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3492 if (Tok.
isNot(tok::l_paren))
3493 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@selector");
3500 bool HasOptionalParen = Tok.
is(tok::l_paren);
3501 if (HasOptionalParen)
3504 if (Tok.
is(tok::code_completion)) {
3512 Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3513 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3515 KeyIdents.push_back(SelIdent);
3517 unsigned nColons = 0;
3518 if (Tok.
isNot(tok::r_paren)) {
3522 KeyIdents.push_back(
nullptr);
3523 }
else if (ExpectAndConsume(tok::colon))
3527 if (Tok.
is(tok::r_paren))
3530 if (Tok.
is(tok::code_completion)) {
3538 SelIdent = ParseObjCSelectorPiece(Loc);
3539 KeyIdents.push_back(SelIdent);
3540 if (!SelIdent && Tok.
isNot(tok::colon) && Tok.
isNot(tok::coloncolon))
3544 if (HasOptionalParen && Tok.
is(tok::r_paren))
3554 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM,
bool parseMethod) {
3556 Decl *MCDecl = LM.D;
3557 bool skip = MCDecl &&
3566 assert(!LM.Toks.empty() &&
"ParseLexedObjCMethodDef - Empty body!");
3569 LM.Toks.push_back(Tok);
3573 ConsumeAnyToken(
true);
3575 assert(Tok.
isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3576 "Inline objective-c method not starting with '{' or 'try' or ':'");
3578 ParseScope BodyScope(
this,
3589 if (Tok.
is(tok::kw_try))
3590 ParseFunctionTryBlock(MCDecl, BodyScope);
3592 if (Tok.
is(tok::colon))
3593 ParseConstructorInitializer(MCDecl);
3594 ParseFunctionStatementBody(MCDecl, BodyScope);
SourceManager & getSourceManager() const
bool isObjCObjectOrInterfaceType() const
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
SourceLocation getCloseLocation() const
Defines the clang::ASTContext interface.
void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, IdentifierInfo *PropertyName)
AttributeList * ArgAttrs
ArgAttrs - Attribute list for this argument.
IdentifierInfo * getNullabilityKeyword(NullabilityKind nullability)
Smart pointer class that efficiently represents Objective-C method names.
SelectorTable & getSelectorTable()
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
Decl * ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth, tok::ObjCKeywordKind visibility)
This is a scope that corresponds to the parameters within a function prototype.
const AttributeList * getAttrs() const
If there are attributes applied to this declaratorchunk, return them.
TypeResult actOnObjCTypeArgsAndProtocolQualifiers(Scope *S, SourceLocation Loc, ParsedType BaseType, SourceLocation TypeArgsLAngleLoc, ArrayRef< ParsedType > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< Decl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc)
Build a specialized and/or protocol-qualified Objective-C type.
static void takeDeclAttributes(ParsedAttributes &attrs, AttributeList *list)
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, const IdentifierLocPair *ProtocolId, unsigned NumProtocols, SmallVectorImpl< Decl * > &Protocols)
const LangOptions & getLangOpts() const
NullabilityKind
Describes the nullability of a particular type.
StmtResult ActOnExprStmt(ExprResult Arg)
void setPropertyAttributes(ObjCPropertyAttributeKind PRVal)
static LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
RAII object used to inform the actions that we're currently parsing a declaration. This is active when parsing a variable's initializer, but not when parsing the body of a class or function definition.
Captures information about "declaration specifiers" specific to Objective-C.
AttributePool & getAttributePool() const
This indicates that the scope corresponds to a function, which means that labels are set here...
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, ObjCDictionaryElement *Elements, unsigned NumElements)
One instance of this struct is used for each type in a declarator that is parsed. ...
std::pair< IdentifierInfo *, SourceLocation > IdentifierLocPair
A simple pair of identifier info and location.
StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, Decl *Parm, Stmt *Body)
Wrapper for void* pointer.
void CodeCompleteObjCMessageReceiver(Scope *S)
void CodeCompleteObjCPropertyGetter(Scope *S)
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
Information about one declarator, including the parsed type information and the identifier.
StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, MultiStmtArg Catch, Stmt *Finally)
bool isUsedAsTypeAttr() const
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, Expr **Strings, unsigned NumStrings)
void setBegin(SourceLocation b)
Code completion occurs within an Objective-C implementation or category implementation.
Decl * ActOnParamDeclarator(Scope *S, Declarator &D)
friend class ObjCDeclContextSwitch
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
Decl * ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef< Decl * > allMethods=None, ArrayRef< DeclGroupPtrTy > allTUVars=None)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
const Token & NextToken()
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
bool TryConsumeToken(tok::TokenKind Expected)
The message is a class message, and the identifier is a type name.
OpaquePtr< QualType > ParsedType
An element in an Objective-C dictionary literal.
void CodeCompleteObjCInterfaceDecl(Scope *S)
DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, ArrayRef< ObjCTypeParamList * > TypeParamLists, unsigned NumElts)
AttributeList * getList() const
DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, const IdentifierLocPair *IdentList, unsigned NumElts, AttributeList *attrList)
ActOnForwardProtocolDeclaration - Handle @protocol foo;.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
void CodeCompleteObjCInterfaceCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
void setKind(tok::TokenKind K)
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)
ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
std::pair< NullabilityKind, bool > DiagNullabilityKind
Code completion occurs where only a type is permitted.
Values of this type can be null.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Selector getNullarySelector(IdentifierInfo *ID)
void addAttributes(AttributeList *AL)
Concatenates two attribute lists.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=ParsedType(), bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type...
bool isObjCMethodDecl(Decl *D)
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
void ActOnTypedefedProtocols(SmallVectorImpl< Decl * > &ProtocolRefs, IdentifierInfo *SuperName, SourceLocation SuperLoc)
void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS)
Decl * ActOnObjCContainerStartDefinition(Decl *IDecl)
Values of this type can never be null.
void CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
const IdentifierInfo * getSetterName() const
Decl * ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList)
tok::TokenKind getKind() const
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
Decl * ActOnObjCExceptionDecl(Scope *S, Declarator &D)
StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, Scope *CurScope)
void CodeCompleteObjCMethodDecl(Scope *S, bool IsInstanceMethod, ParsedType ReturnType)
Decl * ActOnStartOfFunctionDef(Scope *S, Declarator &D)
DeclSpec & getMutableDeclSpec()
void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, ArrayRef< IdentifierInfo * > SelIdents, bool AtArgumentExpression)
ObjCPropertyAttributeKind getPropertyAttributes() const
void AddAnyMethodToGlobalPool(Decl *D)
TypeResult ParseTypeName(SourceRange *Range=nullptr, Declarator::TheContext Context=Declarator::TypeNameContext, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
The message is an instance message.
void CodeCompleteObjCPropertyDefinition(Scope *S)
This file defines the classes used to store parsed information about declaration-specifiers and decla...
TypeResult ActOnTypeName(Scope *S, Declarator &D)
Code completion occurs within an Objective-C interface, protocol, or category.
void ActOnStartOfObjCMethodDef(Scope *S, Decl *D)
void CodeCompleteObjCAtVisibility(Scope *S)
void CodeCompleteObjCImplementationCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
void actOnObjCTypeArgsOrProtocolQualifiers(Scope *S, ParsedType baseType, SourceLocation lAngleLoc, ArrayRef< IdentifierInfo * > identifiers, ArrayRef< SourceLocation > identifierLocs, SourceLocation rAngleLoc, SourceLocation &typeArgsLAngleLoc, SmallVectorImpl< ParsedType > &typeArgs, SourceLocation &typeArgsRAngleLoc, SourceLocation &protocolLAngleLoc, SmallVectorImpl< Decl * > &protocols, SourceLocation &protocolRAngleLoc, bool warnOnIncompleteProtocols)
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
A class for parsing a field declarator.
bool isNot(tok::TokenKind K) const
Decl * ActOnStartClassImplementation(SourceLocation AtClassImplLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperClassname, SourceLocation SuperClassLoc)
static void diagnoseRedundantPropertyNullability(Parser &P, ObjCDeclSpec &DS, NullabilityKind nullability, SourceLocation nullabilityLoc)
Diagnose redundant or conflicting nullability information.
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
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.
ObjCTypeParamVariance
Describes the variance of a given generic parameter.
DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef< Decl * > Decls)
AttributeList * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion...
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
SourceLocation getNullabilityLoc() const
RAII object that makes '>' behave either as an operator or as the closing angle bracket for a temp...
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
const clang::PrintingPolicy & getPrintingPolicy() const
void CodeCompleteObjCPropertySetter(Scope *S)
void CodeCompleteObjCAtExpression(Scope *S)
This is a scope that corresponds to the parameters within a function prototype for a function declara...
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
AttributePool & getAttributePool() const
A class for parsing a DeclSpec.
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
Context-sensitive version of a keyword attribute.
SourceLocation getLocStart() const LLVM_READONLY
Decl * ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, bool ImplKind, IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, SourceLocation PropertyIvarLoc)
void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, ArrayRef< IdentifierInfo * > SelIdents, bool AtArgumentExpression, ObjCInterfaceDecl *Super=nullptr)
void CodeCompleteObjCAtDirective(Scope *S)
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
void setLength(unsigned Len)
bool isValid() const
Return true if this is a valid SourceLocation object.
This is a scope that corresponds to the Objective-C @catch statement.
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
ASTContext & getASTContext() const
IdentifierTable & getIdentifierTable()
Scope * getCurScope() const
void EnterTokenStream(const Token *Toks, unsigned NumToks, bool DisableMacroExpansion, bool OwnsTokens)
Add a "macro" context to the top of the include stack, which will cause the lexer to start returning ...
ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope=nullptr)
void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, ArrayRef< IdentifierInfo * > SelIdents, bool AtArgumentExpression, bool IsSuper=false)
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
ObjCTypeParamList * actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, ArrayRef< Decl * > typeParams, SourceLocation rAngleLoc)
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
The message is sent to 'super'.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool acceptsObjCTypeParams() const
SourceLocation getBegin() const
AttributeList *& getAttrListRef()
bool is(tok::TokenKind K) const
void ActOnLastBitfield(SourceLocation DeclStart, SmallVectorImpl< Decl * > &AllIvarDecls)
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList)
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, AttributeList *AttrList)
StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, Stmt *SynchBody)
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
SourceLocation getOpenLocation() const
The scope of a struct/union/class definition.
ObjCDeclQualifier getObjCDeclQualifier() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
ObjCContainerKind getObjCContainerKind() const
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Decl * ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, IdentifierInfo *SuperName, SourceLocation SuperLoc, ArrayRef< ParsedType > SuperTypeArgs, SourceRange SuperTypeArgsRange, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList)
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.
SkipUntilFlags
Control flags for SkipUntil functions.
void setObjCDeclQualifier(ObjCDeclQualifier DQVal)
bool isSimpleTypeSpecifier(tok::TokenKind Kind) const
Determine whether the token kind starts a simple-type-specifier.
void add(AttributeList *newAttr)
TypeResult actOnObjCProtocolQualifierType(SourceLocation lAngleLoc, ArrayRef< Decl * > protocols, ArrayRef< SourceLocation > protocolLocs, SourceLocation rAngleLoc)
bool isInObjcMethodScope() const
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
void setNullability(SourceLocation loc, NullabilityKind kind)
void CodeCompleteObjCSelector(Scope *S, ArrayRef< IdentifierInfo * > SelIdents)
void setSetterName(IdentifierInfo *name)
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
void setNext(AttributeList *N)
tok::ObjCKeywordKind getObjCKeywordID() const
Return the Objective-C keyword ID for the this identifier.
void CodeCompleteObjCAtStatement(Scope *S)
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)
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.
void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, bool IsParameter)
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
This is a scope that can contain a declaration. Some scopes just contain loop constructs but don't co...
static ParsedType getTypeAnnotation(Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
AttributePool & getPool() const
Captures information about "declaration specifiers".
void setEnd(SourceLocation e)
SourceLocation ConsumeToken()
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
void CodeCompleteObjCMethodDeclSelector(Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnType, ArrayRef< IdentifierInfo * > SelIdents)
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult{return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
bool TryAnnotateTypeOrScopeToken(bool EnteringContext=false, bool NeedType=false)
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
Decl * ActOnMethodDeclaration(Scope *S, SourceLocation BeginLoc, SourceLocation EndLoc, tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, ArrayRef< SourceLocation > SelectorLocs, Selector Sel, ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind, bool isVariadic, bool MethodDefinition)
void setGetterName(IdentifierInfo *name)
ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)
void ActOnObjCContainerFinishDefinition()
void CodeCompleteObjCImplementationDecl(Scope *S)
const DeclaratorChunk & getTypeObject(unsigned i) const
void setLocation(SourceLocation L)
AttributeList * getNext() const
static void addContextSensitiveTypeNullability(Parser &P, Declarator &D, NullabilityKind nullability, SourceLocation nullabilityLoc, bool &addedToDeclSpec)
A trivial tuple used to represent a source range.
NullabilityKind getNullability() const
Decl * ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *CatName, SourceLocation CatLoc)
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
DeclResult actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, IdentifierInfo *paramName, SourceLocation paramLoc, SourceLocation colonLoc, ParsedType typeBound)
Decl * getObjCDeclContext() const
const IdentifierInfo * getGetterName() const
Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, bool *OverridingProperty, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
static OpaquePtr getFromOpaquePtr(void *P)
SourceLocation ColonLoc
Location of ':'.
This scope corresponds to an Objective-C method body. It always has FnScope and DeclScope set as well...
The parameter is invariant: must match exactly.
void CodeCompleteObjCProtocolDecl(Scope *S)
void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols, unsigned NumProtocols)
Decl * ActOnCompatibilityAlias(SourceLocation AtCompatibilityAliasLoc, IdentifierInfo *AliasName, SourceLocation AliasLocation, IdentifierInfo *ClassName, SourceLocation ClassLocation)
ParsedAttributes & getAttributes()
const DeclSpec & getDeclSpec() const
Decl * ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, IdentifierInfo *CategoryName, SourceLocation CategoryLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc)
Stop skipping at specified token, but don't skip the token itself.
IdentifierInfo * getIdentifierInfo() const
const AttributeList * getAttributes() const