26#include "llvm/ADT/STLForwardCompat.h"
27#include "llvm/ADT/SmallVector.h"
32 ParsedAttributes attrs(AttrFactory);
33 if (Tok.is(tok::kw___attribute)) {
34 if (Kind == tok::objc_interface || Kind == tok::objc_protocol)
35 Diag(Tok, diag::err_objc_postfix_attribute_hint)
36 << (
Kind == tok::objc_protocol);
38 Diag(Tok, diag::err_objc_postfix_attribute);
39 ParseGNUAttributes(attrs);
50 if (Tok.is(tok::code_completion)) {
52 Actions.CodeCompletion().CodeCompleteObjCAtDirective(
getCurScope());
56 switch (Tok.getObjCKeywordID()) {
57 case tok::objc_interface:
58 case tok::objc_protocol:
59 case tok::objc_implementation:
62 for (
const auto &Attr : DeclAttrs) {
63 if (Attr.isGNUAttribute())
64 Diag(Tok.getLocation(), diag::err_objc_unexpected_attr);
68 Decl *SingleDecl =
nullptr;
69 switch (Tok.getObjCKeywordID()) {
71 return ParseObjCAtClassDeclaration(AtLoc);
72 case tok::objc_interface:
73 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DeclAttrs);
75 case tok::objc_protocol:
76 return ParseObjCAtProtocolDeclaration(AtLoc, DeclAttrs);
77 case tok::objc_implementation:
78 return ParseObjCAtImplementationDeclaration(AtLoc, DeclAttrs);
80 return ParseObjCAtEndDeclaration(AtLoc);
81 case tok::objc_compatibility_alias:
82 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
84 case tok::objc_synthesize:
85 SingleDecl = ParseObjCPropertySynthesize(AtLoc);
87 case tok::objc_dynamic:
88 SingleDecl = ParseObjCPropertyDynamic(AtLoc);
90 case tok::objc_import:
93 SingleDecl = ParseModuleImport(AtLoc, IS);
96 Diag(AtLoc, diag::err_atimport);
98 return Actions.ConvertDeclToDeclGroup(
nullptr);
100 Diag(AtLoc, diag::err_unexpected_at);
102 SingleDecl =
nullptr;
105 return Actions.ConvertDeclToDeclGroup(SingleDecl);
115 : Actions(Actions), S(S), Params(
nullptr) {}
128 Actions.ObjC().popObjCTypeParamList(S, Params);
141 MaybeSkipAttributes(tok::objc_class);
142 if (
Tok.is(tok::code_completion)) {
147 if (expectIdentifier()) {
151 ClassNames.push_back(Tok.getIdentifierInfo());
152 ClassLocs.push_back(Tok.getLocation());
156 ObjCTypeParamList *TypeParams =
nullptr;
157 if (Tok.is(tok::less))
158 TypeParams = parseObjCTypeParamList();
159 ClassTypeParams.push_back(TypeParams);
165 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@class"))
166 return Actions.ConvertDeclToDeclGroup(
nullptr);
168 return Actions.ObjC().ActOnForwardClassDeclaration(
169 atLoc, ClassNames.data(), ClassLocs.data(), ClassTypeParams,
179 Decl *
Decl = Actions.ObjC().getObjCDeclContext();
180 if (CurParsedObjCImpl) {
181 CurParsedObjCImpl->finish(AtLoc);
185 Diag(AtLoc, diag::err_objc_missing_end)
188 Diag(
Decl->getBeginLoc(), diag::note_objc_container_start) << (
int)ock;
193 assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
194 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
195 CheckNestedObjCContexts(AtLoc);
199 if (Tok.is(tok::code_completion)) {
201 Actions.CodeCompletion().CodeCompleteObjCInterfaceDecl(
getCurScope());
205 MaybeSkipAttributes(tok::objc_interface);
207 if (expectIdentifier())
211 IdentifierInfo *nameId = Tok.getIdentifierInfo();
217 SourceLocation LAngleLoc, EndProtoLoc;
218 SmallVector<IdentifierLoc, 8> ProtocolIdents;
219 ObjCTypeParamList *typeParameterList =
nullptr;
221 if (Tok.is(tok::less))
222 typeParameterList = parseObjCTypeParamListOrProtocolRefs(
223 typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
225 if (Tok.is(tok::l_paren) &&
231 SourceLocation categoryLoc;
232 IdentifierInfo *categoryId =
nullptr;
233 if (Tok.is(tok::code_completion)) {
235 Actions.CodeCompletion().CodeCompleteObjCInterfaceCategory(
241 if (Tok.is(tok::identifier)) {
242 categoryId = Tok.getIdentifierInfo();
246 Diag(Tok, diag::err_expected)
252 if (
T.getCloseLocation().isInvalid())
256 assert(LAngleLoc.
isInvalid() &&
"Cannot have already parsed protocols");
257 SmallVector<Decl *, 8> ProtocolRefs;
258 SmallVector<SourceLocation, 8> ProtocolLocs;
259 if (Tok.is(tok::less) &&
260 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
true,
true,
261 LAngleLoc, EndProtoLoc,
265 ObjCCategoryDecl *CategoryType = Actions.ObjC().ActOnStartCategoryInterface(
266 AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
267 ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
270 if (Tok.is(tok::l_brace))
271 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
273 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
278 IdentifierInfo *superClassId =
nullptr;
279 SourceLocation superClassLoc;
280 SourceLocation typeArgsLAngleLoc;
281 SmallVector<ParsedType, 4> typeArgs;
282 SourceLocation typeArgsRAngleLoc;
283 SmallVector<Decl *, 4> protocols;
284 SmallVector<SourceLocation, 4> protocolLocs;
285 if (Tok.is(tok::colon)) {
289 if (Tok.is(tok::code_completion)) {
291 Actions.CodeCompletion().CodeCompleteObjCSuperclass(
getCurScope(), nameId,
296 if (expectIdentifier())
298 superClassId = Tok.getIdentifierInfo();
302 if (Tok.is(tok::less)) {
303 parseObjCTypeArgsOrProtocolQualifiers(
304 nullptr, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, LAngleLoc,
305 protocols, protocolLocs, EndProtoLoc,
308 if (Tok.is(tok::eof))
315 if (!ProtocolIdents.empty()) {
318 for (
const auto &Loc : ProtocolIdents) {
319 protocolLocs.push_back(Loc.getLoc());
321 Actions.ObjC().FindProtocolDeclaration(
true,
323 ProtocolIdents, protocols);
325 }
else if (protocols.empty() && Tok.is(tok::less) &&
326 ParseObjCProtocolReferences(protocols, protocolLocs,
true,
true,
327 LAngleLoc, EndProtoLoc,
332 if (Tok.isNot(tok::less))
333 Actions.ObjC().ActOnTypedefedProtocols(protocols, protocolLocs,
334 superClassId, superClassLoc);
336 SkipBodyInfo SkipBody;
337 ObjCInterfaceDecl *ClsType = Actions.ObjC().ActOnStartClassInterface(
338 getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
339 superClassLoc, typeArgs,
340 SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(),
341 protocols.size(), protocolLocs.data(), EndProtoLoc, attrs, &SkipBody);
343 if (Tok.is(tok::l_brace))
344 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
346 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
350 if (Actions.ActOnDuplicateODRHashDefinition(ClsType, PreviousDef)) {
353 ODRDiagsEmitter DiagsEmitter(Diags, Actions.getASTContext(),
355 DiagsEmitter.diagnoseMismatch(PreviousDef, ClsType);
369 bool &addedToDeclSpec) {
374 nullptr, 0, ParsedAttr::Form::ContextSensitiveKeyword());
381 }
else if (!addedToDeclSpec) {
386 addedToDeclSpec =
true;
393 bool mayBeProtocolList) {
394 assert(Tok.is(tok::less) &&
"Not at the beginning of a type parameter list");
397 GreaterThanIsOperatorScope G(GreaterThanIsOperator,
false);
401 SmallVector<Decl *, 4> typeParams;
402 auto makeProtocolIdentsIntoTypeParameters = [&]() {
404 for (
const auto &pair : protocolIdents) {
405 DeclResult typeParam = Actions.ObjC().actOnObjCTypeParam(
407 index++, pair.getIdentifierInfo(), pair.getLoc(), SourceLocation(),
410 typeParams.push_back(typeParam.
get());
413 protocolIdents.clear();
414 mayBeProtocolList =
false;
417 bool invalid =
false;
422 SourceLocation varianceLoc;
424 if (Tok.is(tok::kw___covariant) || Tok.is(tok::kw___contravariant)) {
425 variance = Tok.is(tok::kw___covariant)
432 if (mayBeProtocolList) {
435 makeProtocolIdentsIntoTypeParameters();
440 if (!Tok.is(tok::identifier)) {
442 if (Tok.is(tok::code_completion)) {
446 Actions.CodeCompletion().CodeCompleteObjCProtocolReferences(
453 Diag(Tok, diag::err_objc_expected_type_parameter);
458 IdentifierInfo *paramName = Tok.getIdentifierInfo();
462 SourceLocation colonLoc;
467 if (mayBeProtocolList) {
470 makeProtocolIdentsIntoTypeParameters();
477 }
else if (mayBeProtocolList) {
480 protocolIdents.emplace_back(paramLoc, paramName);
485 DeclResult typeParam = Actions.ObjC().actOnObjCTypeParam(
486 getCurScope(), variance, varianceLoc, typeParams.size(), paramName,
487 paramLoc, colonLoc, boundType.
isUsable() ? boundType.
get() :
nullptr);
489 typeParams.push_back(typeParam.
get());
495 if (Tok.is(tok::greater))
497 }
else if (ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc,
500 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
501 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
502 tok::comma, tok::semi },
504 if (Tok.is(tok::greater))
508 if (mayBeProtocolList) {
513 if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_paren)) {
522 makeProtocolIdentsIntoTypeParameters();
526 ObjCTypeParamList *list = Actions.ObjC().actOnObjCTypeParamList(
532 lAngleLoc = SourceLocation();
533 rAngleLoc = SourceLocation();
534 return invalid ?
nullptr : list;
538 SourceLocation lAngleLoc;
539 SmallVector<IdentifierLoc, 1> protocolIdents;
540 SourceLocation rAngleLoc;
543 return parseObjCTypeParamListOrProtocolRefs(Scope, lAngleLoc, protocolIdents,
549 switch (DirectiveKind) {
550 case tok::objc_class:
551 case tok::objc_compatibility_alias:
552 case tok::objc_interface:
553 case tok::objc_implementation:
554 case tok::objc_protocol:
563 SmallVector<Decl *, 32> allMethods;
564 SmallVector<DeclGroupPtrTy, 8> allTUVariables;
571 if (Tok.isOneOf(tok::minus, tok::plus)) {
572 if (Decl *methodPrototype =
573 ParseObjCMethodPrototype(MethodImplKind,
false))
574 allMethods.push_back(methodPrototype);
577 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
580 if (Tok.is(tok::semi))
585 if (Tok.is(tok::l_paren)) {
586 Diag(Tok, diag::err_expected_minus_or_plus);
587 ParseObjCMethodDecl(Tok.getLocation(),
589 MethodImplKind,
false);
593 if (Tok.is(tok::semi)) {
605 if (Tok.is(tok::code_completion)) {
607 Actions.CodeCompletion().CodeCompleteOrdinaryName(
615 if (Tok.isNot(tok::at)) {
619 if (Tok.is(tok::r_brace))
622 ParsedAttributes EmptyDeclAttrs(AttrFactory);
623 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
628 if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
629 SourceLocation DeclEnd;
630 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
632 DeclEnd, EmptyDeclAttrs,
633 EmptyDeclSpecAttrs));
637 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(
638 EmptyDeclAttrs, EmptyDeclSpecAttrs));
643 SourceLocation AtLoc = Tok.getLocation();
645 if (NextTok.is(tok::code_completion)) {
647 Actions.CodeCompletion().CodeCompleteObjCAtDirective(
getCurScope());
652 if (DirectiveKind == tok::objc_end) {
655 AtEnd.
setEnd(Tok.getLocation());
657 }
else if (DirectiveKind == tok::objc_not_keyword) {
658 Diag(NextTok, diag::err_objc_unknown_at);
672 switch (DirectiveKind) {
678 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
683 case tok::objc_required:
684 case tok::objc_optional:
686 if (contextKey != tok::objc_protocol)
687 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
692 case tok::objc_property:
694 SourceLocation LParenLoc;
696 if (Tok.is(tok::l_paren)) {
697 LParenLoc = Tok.getLocation();
698 ParseObjCPropertyAttribute(OCDS);
701 bool addedToDeclSpec =
false;
702 auto ObjCPropertyCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
703 if (FD.D.getIdentifier() ==
nullptr) {
704 Diag(AtLoc, diag::err_objc_property_requires_field_name)
705 << FD.D.getSourceRange();
708 if (FD.BitfieldSize) {
709 Diag(AtLoc, diag::err_objc_property_bitfield)
710 << FD.D.getSourceRange();
723 const IdentifierInfo *SelName =
726 Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName);
730 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
733 PP.getIdentifierTable(), PP.getSelectorTable(),
734 FD.D.getIdentifier());
736 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
744 ParsingDeclSpec DS(*
this);
745 ParseStructDeclaration(DS, ObjCPropertyCallback);
747 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
755 if (Tok.isObjCAtKeyword(tok::objc_end)) {
758 Diag(Tok, diag::err_objc_missing_end)
761 << (
int)Actions.ObjC().getObjCContainerKind();
763 AtEnd.
setEnd(Tok.getLocation());
768 Actions.ObjC().ActOnAtEnd(
getCurScope(), AtEnd, allMethods, allTUVariables);
777 P.
Diag(nullabilityLoc, diag::warn_nullability_duplicate)
783 P.
Diag(nullabilityLoc, diag::err_nullability_conflicting)
789void Parser::ParseObjCPropertyAttribute(
ObjCDeclSpec &DS) {
790 assert(Tok.getKind() == tok::l_paren);
795 if (Tok.is(tok::code_completion)) {
797 Actions.CodeCompletion().CodeCompleteObjCPropertyFlags(
getCurScope(), DS);
800 const IdentifierInfo *II = Tok.getIdentifierInfo();
810 if (II->
isStr(
"readonly"))
812 else if (II->
isStr(
"assign"))
814 else if (II->
isStr(
"unsafe_unretained"))
816 else if (II->
isStr(
"readwrite"))
818 else if (II->
isStr(
"retain"))
820 else if (II->
isStr(
"strong"))
822 else if (II->
isStr(
"copy"))
824 else if (II->
isStr(
"nonatomic"))
826 else if (II->
isStr(
"atomic"))
828 else if (II->
isStr(
"weak"))
830 else if (II->
isStr(
"getter") || II->
isStr(
"setter")) {
834 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
835 diag::err_objc_expected_equal_for_getter;
837 if (ExpectAndConsume(tok::equal, DiagID)) {
842 if (Tok.is(tok::code_completion)) {
845 Actions.CodeCompletion().CodeCompleteObjCPropertySetter(
848 Actions.CodeCompletion().CodeCompleteObjCPropertyGetter(
853 SourceLocation SelLoc;
854 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc);
857 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
867 if (ExpectAndConsume(tok::colon,
868 diag::err_expected_colon_after_setter_name)) {
876 }
else if (II->
isStr(
"nonnull")) {
883 }
else if (II->
isStr(
"nullable")) {
890 }
else if (II->
isStr(
"null_unspecified")) {
897 }
else if (II->
isStr(
"null_resettable")) {
907 }
else if (II->
isStr(
"class")) {
909 }
else if (II->
isStr(
"direct")) {
912 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
917 if (Tok.isNot(tok::comma))
927 bool MethodDefinition) {
928 assert(Tok.isOneOf(tok::minus, tok::plus) &&
"expected +/-");
932 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
941 switch (Tok.getKind()) {
944 SelectorLoc = Tok.getLocation();
952 case tok::exclaimequal:
956 case tok::caretequal: {
957 std::string ThisTok(PP.getSpelling(Tok));
959 IdentifierInfo *II = &PP.getIdentifierTable().get(ThisTok);
960 Tok.setKind(tok::identifier);
967 case tok::kw___attribute:
971 IdentifierInfo *II = Tok.getIdentifierInfo();
979bool Parser::isTokIdentifier_in()
const {
984 Tok.getIdentifierInfo() ==
988void Parser::ParseObjCTypeQualifierList(
ObjCDeclSpec &DS,
994 if (Tok.is(tok::code_completion)) {
996 Actions.CodeCompletion().CodeCompleteObjCPassingType(
1001 if (Tok.isNot(tok::identifier))
1004 const IdentifierInfo *II = Tok.getIdentifierInfo();
1008 if (II != ObjCTypeQuals[llvm::to_underlying(TQ)] ||
1015 default: llvm_unreachable(
"Unknown decl qualifier");
1070 for (
auto &AL : llvm::reverse(from)) {
1071 if (!AL.isUsedAsTypeAttr()) {
1102 assert((paramAttrs !=
nullptr) ==
1105 assert(Tok.is(tok::l_paren) &&
"expected (");
1110 ObjCDeclContextSwitch ObjCDC(*
this);
1113 ParseObjCTypeQualifierList(DS, context);
1114 SourceLocation TypeStartLoc = Tok.getLocation();
1117 if (isTypeSpecifierQualifier(Tok) || isObjCInstancetype()) {
1119 DeclSpec declSpec(AttrFactory);
1120 declSpec.setObjCQualifiers(&DS);
1121 DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
1123 dsContext = DeclSpecContext::DSC_objc_method_result;
1124 ParseSpecifierQualifierList(declSpec,
AS_none, dsContext);
1126 ParseDeclarator(declarator);
1129 if (!declarator.isInvalidType()) {
1131 bool addedToDeclSpec =
false;
1139 if (!
type.isInvalid())
1149 if (Tok.is(tok::r_paren))
1151 else if (Tok.getLocation() == TypeStartLoc) {
1153 Diag(Tok, diag::err_expected_type);
1166 bool MethodDefinition) {
1169 if (Tok.is(tok::code_completion)) {
1171 Actions.CodeCompletion().CodeCompleteObjCMethodDecl(
getCurScope(),
1172 mType == tok::minus,
1180 if (Tok.is(tok::l_paren))
1185 ParsedAttributes methodAttrs(AttrFactory);
1186 MaybeParseAttributes(PAKM_CXX11 | (
getLangOpts().
ObjC ? PAKM_GNU : 0),
1189 if (Tok.is(tok::code_completion)) {
1191 Actions.CodeCompletion().CodeCompleteObjCMethodDecl(
1197 SourceLocation selLoc;
1198 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
1201 if (!SelIdent && Tok.isNot(tok::colon)) {
1202 Diag(Tok, diag::err_expected_selector_for_method)
1203 << SourceRange(mLoc, Tok.getLocation());
1209 SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
1210 if (Tok.isNot(tok::colon)) {
1212 MaybeParseAttributes(PAKM_CXX11 | (
getLangOpts().
ObjC ? PAKM_GNU : 0),
1215 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
1216 Decl *
Result = Actions.ObjC().ActOnMethodDeclaration(
1217 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType,
1218 selLoc, Sel,
nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
1219 MethodImplKind,
false, MethodDefinition);
1224 SmallVector<const IdentifierInfo *, 12> KeyIdents;
1225 SmallVector<SourceLocation, 12> KeyLocs;
1226 SmallVector<SemaObjC::ObjCArgInfo, 12> ArgInfos;
1230 AttributePool allParamAttrs(AttrFactory);
1232 ParsedAttributes paramAttrs(AttrFactory);
1233 SemaObjC::ObjCArgInfo ArgInfo;
1236 if (ExpectAndConsume(tok::colon))
1239 ArgInfo.
Type =
nullptr;
1240 if (Tok.is(tok::l_paren))
1241 ArgInfo.
Type = ParseObjCTypeName(
1246 MaybeParseAttributes(PAKM_CXX11 | (
getLangOpts().
ObjC ? PAKM_GNU : 0),
1251 if (Tok.is(tok::code_completion)) {
1253 KeyIdents.push_back(SelIdent);
1254 Actions.CodeCompletion().CodeCompleteObjCMethodDeclSelector(
1256 true, ReturnType, KeyIdents);
1260 if (expectIdentifier())
1263 ArgInfo.
Name = Tok.getIdentifierInfo();
1264 ArgInfo.
NameLoc = Tok.getLocation();
1267 ArgInfos.push_back(ArgInfo);
1268 KeyIdents.push_back(SelIdent);
1269 KeyLocs.push_back(selLoc);
1272 allParamAttrs.takeAllFrom(paramAttrs.
getPool());
1275 if (Tok.is(tok::code_completion)) {
1277 Actions.CodeCompletion().CodeCompleteObjCMethodDeclSelector(
1279 false, ReturnType, KeyIdents);
1284 SelIdent = ParseObjCSelectorPiece(selLoc);
1285 if (!SelIdent && Tok.isNot(tok::colon))
1288 SourceLocation ColonLoc = Tok.getLocation();
1289 if (PP.getLocForEndOfToken(ArgInfo.
NameLoc) == ColonLoc) {
1290 Diag(ArgInfo.
NameLoc, diag::warn_missing_selector_name) << ArgInfo.
Name;
1291 Diag(ArgInfo.
NameLoc, diag::note_missing_selector_name) << ArgInfo.
Name;
1292 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.
Name;
1298 bool isVariadic =
false;
1299 bool cStyleParamWarned =
false;
1301 while (Tok.is(tok::comma)) {
1303 if (Tok.is(tok::ellipsis)) {
1308 if (!cStyleParamWarned) {
1309 Diag(Tok, diag::warn_cstyle_param);
1310 cStyleParamWarned =
true;
1312 DeclSpec DS(AttrFactory);
1313 ParsedTemplateInfo TemplateInfo;
1314 ParseDeclarationSpecifiers(DS, TemplateInfo);
1318 ParseDeclarator(ParmDecl);
1319 const IdentifierInfo *ParmII = ParmDecl.getIdentifier();
1321 CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
1322 ParmDecl.getIdentifierLoc(),
1331 SmallVector<ParmVarDecl *, 12> ObjCParamInfo;
1332 for (
auto &ArgInfo : ArgInfos) {
1333 ParmVarDecl *Param = Actions.ObjC().ActOnMethodParmDeclaration(
1334 getCurScope(), ArgInfo, ObjCParamInfo.size(), MethodDefinition);
1335 ObjCParamInfo.push_back(Param);
1340 MaybeParseAttributes(PAKM_CXX11 | (
getLangOpts().
ObjC ? PAKM_GNU : 0),
1343 if (KeyIdents.size() == 0)
1346 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
1348 Decl *
Result = Actions.ObjC().ActOnMethodDeclaration(
1349 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
1350 Sel, ObjCParamInfo.data(), CParamInfo.data(), CParamInfo.size(),
1351 methodAttrs, MethodImplKind, isVariadic, MethodDefinition);
1360 bool WarnOnDeclarations,
bool ForObjCContainer,
1362 bool consumeLastToken) {
1363 assert(Tok.is(tok::less) &&
"expected <");
1367 SmallVector<IdentifierLoc, 8> ProtocolIdents;
1370 if (Tok.is(tok::code_completion)) {
1372 Actions.CodeCompletion().CodeCompleteObjCProtocolReferences(
1377 if (expectIdentifier()) {
1381 ProtocolIdents.emplace_back(Tok.getLocation(), Tok.getIdentifierInfo());
1382 ProtocolLocs.push_back(Tok.getLocation());
1390 if (ParseGreaterThanInTemplateList(LAngleLoc, EndLoc, consumeLastToken,
1395 Actions.ObjC().FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer,
1396 ProtocolIdents, Protocols);
1401 assert(Tok.is(tok::less) &&
"Protocol qualifiers start with '<'");
1402 assert(
getLangOpts().
ObjC &&
"Protocol qualifiers only exist in Objective-C");
1404 SourceLocation lAngleLoc;
1405 SmallVector<Decl *, 8> protocols;
1406 SmallVector<SourceLocation, 8> protocolLocs;
1407 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
false,
false,
1408 lAngleLoc, rAngleLoc,
1410 TypeResult result = Actions.ObjC().actOnObjCProtocolQualifierType(
1411 lAngleLoc, protocols, protocolLocs, rAngleLoc);
1413 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1415 << SourceRange(lAngleLoc, rAngleLoc);
1421void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1430 bool consumeLastToken,
1431 bool warnOnIncompleteProtocols) {
1432 assert(Tok.is(tok::less) &&
"Not at the start of type args or protocols");
1437 bool allSingleIdentifiers =
true;
1438 SmallVector<IdentifierInfo *, 4> identifiers;
1439 SmallVectorImpl<SourceLocation> &identifierLocs = protocolLocs;
1445 if (Tok.is(tok::identifier) &&
1449 identifiers.push_back(Tok.getIdentifierInfo());
1454 if (Tok.is(tok::code_completion)) {
1456 SmallVector<IdentifierLoc, 4> identifierLocPairs;
1457 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1458 identifierLocPairs.emplace_back(identifierLocs[i], identifiers[i]);
1461 QualType BaseT = Actions.GetTypeFromParser(baseType);
1464 Actions.CodeCompletion().CodeCompleteOrdinaryName(
1467 Actions.CodeCompletion().CodeCompleteObjCProtocolReferences(
1468 identifierLocPairs);
1473 allSingleIdentifiers =
false;
1479 if (allSingleIdentifiers) {
1481 SourceLocation rAngleLoc;
1482 (void)ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc, consumeLastToken,
1486 Actions.ObjC().actOnObjCTypeArgsOrProtocolQualifiers(
1487 getCurScope(), baseType, lAngleLoc, identifiers, identifierLocs,
1488 rAngleLoc, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc,
1489 protocolLAngleLoc, protocols, protocolRAngleLoc,
1490 warnOnIncompleteProtocols);
1500 bool invalid =
false;
1501 IdentifierInfo *foundProtocolId =
nullptr, *foundValidTypeId =
nullptr;
1502 SourceLocation foundProtocolSrcLoc, foundValidTypeSrcLoc;
1503 SmallVector<IdentifierInfo *, 2> unknownTypeArgs;
1504 SmallVector<SourceLocation, 2> unknownTypeArgsLoc;
1506 for (
unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1508 = Actions.getTypeName(*identifiers[i], identifierLocs[i],
getCurScope());
1510 DeclSpec DS(AttrFactory);
1511 const char *prevSpec =
nullptr;
1513 DS.SetTypeSpecType(
TST_typename, identifierLocs[i], prevSpec, diagID,
1514 typeArg, Actions.getASTContext().getPrintingPolicy());
1519 TypeResult fullTypeArg = Actions.ActOnTypeName(D);
1521 typeArgs.push_back(fullTypeArg.
get());
1522 if (!foundValidTypeId) {
1523 foundValidTypeId = identifiers[i];
1524 foundValidTypeSrcLoc = identifierLocs[i];
1528 unknownTypeArgs.push_back(identifiers[i]);
1529 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1533 if (!Actions.ObjC().LookupProtocol(identifiers[i], identifierLocs[i])) {
1534 unknownTypeArgs.push_back(identifiers[i]);
1535 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1536 }
else if (!foundProtocolId) {
1537 foundProtocolId = identifiers[i];
1538 foundProtocolSrcLoc = identifierLocs[i];
1545 Token CurTypeTok = Tok;
1549 SourceLocation ellipsisLoc;
1552 typeArg = Actions.ActOnPackExpansion(typeArg.
get(), ellipsisLoc);
1556 typeArgs.push_back(typeArg.
get());
1557 if (!foundValidTypeId) {
1567 if (foundProtocolId && foundValidTypeId)
1568 Actions.ObjC().DiagnoseTypeArgsAndProtocols(
1569 foundProtocolId, foundProtocolSrcLoc, foundValidTypeId,
1570 foundValidTypeSrcLoc);
1574 if (unknownTypeArgs.size())
1575 for (
unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1576 Actions.DiagnoseUnknownTypeName(unknownTypeArgs[i], unknownTypeArgsLoc[i],
1580 SourceLocation rAngleLoc;
1581 (void)ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc, consumeLastToken,
1590 typeArgsLAngleLoc = lAngleLoc;
1591 typeArgsRAngleLoc = rAngleLoc;
1594void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1603 bool consumeLastToken) {
1604 assert(Tok.is(tok::less));
1607 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1617 if (Tok.is(tok::eof))
1623 if ((consumeLastToken && Tok.is(tok::less)) ||
1624 (!consumeLastToken &&
NextToken().
is(tok::less))) {
1627 if (!consumeLastToken)
1630 if (!protocols.empty()) {
1632 if (!consumeLastToken)
1634 Diag(Tok, diag::err_objc_type_args_after_protocols)
1635 << SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1636 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1638 ParseObjCProtocolReferences(protocols, protocolLocs,
1641 protocolLAngleLoc, protocolRAngleLoc,
1647TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1650 bool consumeLastToken,
1652 assert(Tok.is(tok::less));
1653 SourceLocation typeArgsLAngleLoc;
1654 SmallVector<ParsedType, 4> typeArgs;
1655 SourceLocation typeArgsRAngleLoc;
1656 SourceLocation protocolLAngleLoc;
1657 SmallVector<Decl *, 4> protocols;
1658 SmallVector<SourceLocation, 4> protocolLocs;
1659 SourceLocation protocolRAngleLoc;
1662 parseObjCTypeArgsAndProtocolQualifiers(
type, typeArgsLAngleLoc, typeArgs,
1663 typeArgsRAngleLoc, protocolLAngleLoc,
1664 protocols, protocolLocs,
1665 protocolRAngleLoc, consumeLastToken);
1667 if (Tok.is(tok::eof))
1671 if (consumeLastToken)
1672 endLoc = PrevTokLocation;
1674 endLoc = Tok.getLocation();
1676 return Actions.ObjC().actOnObjCTypeArgsAndProtocolQualifiers(
1677 getCurScope(), loc,
type, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc,
1678 protocolLAngleLoc, protocols, protocolLocs, protocolRAngleLoc);
1681void Parser::HelperActionsForIvarDeclarations(
1684 bool RBraceMissing) {
1689 "Ivars should have interfaceDecl as their decl context");
1690 Actions.ActOnLastBitfield(
T.getCloseLocation(), AllIvarDecls);
1693 Actions.ActOnFields(
getCurScope(), atLoc, interfaceDecl, AllIvarDecls,
1694 T.getOpenLocation(),
T.getCloseLocation(),
1695 ParsedAttributesView());
1701 assert(Tok.is(tok::l_brace) &&
"expected {");
1702 SmallVector<Decl *, 32> AllIvarDecls;
1709 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1713 if (Tok.is(tok::semi)) {
1720 if (Tok.is(tok::code_completion)) {
1722 Actions.CodeCompletion().CodeCompleteObjCAtVisibility(
getCurScope());
1726 switch (Tok.getObjCKeywordID()) {
1727 case tok::objc_private:
1728 case tok::objc_public:
1729 case tok::objc_protected:
1730 case tok::objc_package:
1731 visibility = Tok.getObjCKeywordID();
1736 Diag(Tok, diag::err_objc_unexpected_atend);
1737 Tok.setLocation(Tok.getLocation().getLocWithOffset(-1));
1738 Tok.setKind(tok::at);
1740 PP.EnterToken(Tok,
true);
1741 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1742 T, AllIvarDecls,
true);
1746 Diag(Tok, diag::err_objc_illegal_visibility_spec);
1751 if (Tok.is(tok::code_completion)) {
1753 Actions.CodeCompletion().CodeCompleteOrdinaryName(
1761 if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
1762 SourceLocation DeclEnd;
1763 ParseStaticAssertDeclaration(DeclEnd);
1767 auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
1769 "Ivar should have interfaceDecl as its decl context");
1771 FD.D.setObjCIvar(
true);
1773 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
1774 FD.BitfieldSize, visibility);
1776 AllIvarDecls.push_back(Field);
1782 ParsingDeclSpec DS(*
this);
1783 ParseStructDeclaration(DS, ObjCIvarCallback);
1785 if (Tok.is(tok::semi)) {
1788 Diag(Tok, diag::err_expected_semi_decl_list);
1793 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1794 T, AllIvarDecls,
false);
1800 assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
1801 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
1804 if (Tok.is(tok::code_completion)) {
1806 Actions.CodeCompletion().CodeCompleteObjCProtocolDecl(
getCurScope());
1810 MaybeSkipAttributes(tok::objc_protocol);
1812 if (expectIdentifier())
1815 IdentifierInfo *protocolName = Tok.getIdentifierInfo();
1819 IdentifierLoc ProtoInfo(nameLoc, protocolName);
1820 return Actions.ObjC().ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo,
1824 CheckNestedObjCContexts(AtLoc);
1826 if (Tok.is(tok::comma)) {
1827 SmallVector<IdentifierLoc, 8> ProtocolRefs;
1828 ProtocolRefs.emplace_back(nameLoc, protocolName);
1833 if (expectIdentifier()) {
1837 ProtocolRefs.emplace_back(Tok.getLocation(), Tok.getIdentifierInfo());
1840 if (Tok.isNot(tok::comma))
1844 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
"@protocol"))
1847 return Actions.ObjC().ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs,
1852 SourceLocation LAngleLoc, EndProtoLoc;
1854 SmallVector<Decl *, 8> ProtocolRefs;
1855 SmallVector<SourceLocation, 8> ProtocolLocs;
1856 if (Tok.is(tok::less) &&
1857 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs,
false,
true,
1858 LAngleLoc, EndProtoLoc,
1862 SkipBodyInfo SkipBody;
1863 ObjCProtocolDecl *ProtoType = Actions.ObjC().ActOnStartProtocolInterface(
1864 AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
1865 ProtocolLocs.data(), EndProtoLoc, attrs, &SkipBody);
1867 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
1870 if (Actions.ActOnDuplicateODRHashDefinition(ProtoType, PreviousDef)) {
1872 PreviousDef->getDefinition());
1874 ODRDiagsEmitter DiagsEmitter(Diags, Actions.getASTContext(),
1876 DiagsEmitter.diagnoseMismatch(PreviousDef, ProtoType);
1879 return Actions.ConvertDeclToDeclGroup(ProtoType);
1883Parser::ParseObjCAtImplementationDeclaration(
SourceLocation AtLoc,
1885 assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
1886 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
1887 CheckNestedObjCContexts(AtLoc);
1891 if (Tok.is(tok::code_completion)) {
1893 Actions.CodeCompletion().CodeCompleteObjCImplementationDecl(
getCurScope());
1897 MaybeSkipAttributes(tok::objc_implementation);
1899 if (expectIdentifier())
1902 IdentifierInfo *nameId = Tok.getIdentifierInfo();
1904 ObjCImplDecl *ObjCImpDecl =
nullptr;
1908 if (Tok.is(tok::less)) {
1909 SourceLocation lAngleLoc, rAngleLoc;
1910 SmallVector<IdentifierLoc, 8> protocolIdents;
1911 SourceLocation diagLoc = Tok.getLocation();
1913 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
1914 protocolIdents, rAngleLoc)) {
1915 Diag(diagLoc, diag::err_objc_parameterized_implementation)
1916 << SourceRange(diagLoc, PrevTokLocation);
1917 }
else if (lAngleLoc.
isValid()) {
1918 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
1923 if (Tok.is(tok::l_paren)) {
1926 SourceLocation categoryLoc, rparenLoc;
1927 IdentifierInfo *categoryId =
nullptr;
1929 if (Tok.is(tok::code_completion)) {
1931 Actions.CodeCompletion().CodeCompleteObjCImplementationCategory(
1936 if (Tok.is(tok::identifier)) {
1937 categoryId = Tok.getIdentifierInfo();
1940 Diag(Tok, diag::err_expected)
1944 if (Tok.isNot(tok::r_paren)) {
1945 Diag(Tok, diag::err_expected) << tok::r_paren;
1949 rparenLoc = ConsumeParen();
1950 if (Tok.is(tok::less)) {
1951 Diag(Tok, diag::err_unexpected_protocol_qualifier);
1952 SourceLocation protocolLAngleLoc, protocolRAngleLoc;
1953 SmallVector<Decl *, 4> protocols;
1954 SmallVector<SourceLocation, 4> protocolLocs;
1955 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
1958 protocolLAngleLoc, protocolRAngleLoc,
1961 ObjCImpDecl = Actions.ObjC().ActOnStartCategoryImplementation(
1962 AtLoc, nameId, nameLoc, categoryId, categoryLoc, Attrs);
1966 SourceLocation superClassLoc;
1967 IdentifierInfo *superClassId =
nullptr;
1970 if (expectIdentifier())
1972 superClassId = Tok.getIdentifierInfo();
1975 ObjCImpDecl = Actions.ObjC().ActOnStartClassImplementation(
1976 AtLoc, nameId, nameLoc, superClassId, superClassLoc, Attrs);
1978 if (Tok.is(tok::l_brace))
1979 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
1980 else if (Tok.is(tok::less)) {
1981 Diag(Tok, diag::err_unexpected_protocol_qualifier);
1983 SourceLocation protocolLAngleLoc, protocolRAngleLoc;
1984 SmallVector<Decl *, 4> protocols;
1985 SmallVector<SourceLocation, 4> protocolLocs;
1986 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
1989 protocolLAngleLoc, protocolRAngleLoc,
1993 assert(ObjCImpDecl);
1995 SmallVector<Decl *, 8> DeclsInGroup;
1998 ObjCImplParsingDataRAII ObjCImplParsing(*
this, ObjCImpDecl);
1999 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2000 ParsedAttributes DeclAttrs(AttrFactory);
2001 MaybeParseCXX11Attributes(DeclAttrs);
2002 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2004 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs)) {
2005 DeclGroupRef DG = DGP.get();
2006 DeclsInGroup.append(DG.
begin(), DG.
end());
2011 return Actions.ObjC().ActOnFinishObjCImplementation(ObjCImpDecl,
2016Parser::ParseObjCAtEndDeclaration(
SourceRange atEnd) {
2017 assert(Tok.isObjCAtKeyword(tok::objc_end) &&
2018 "ParseObjCAtEndDeclaration(): Expected @end");
2020 if (CurParsedObjCImpl)
2021 CurParsedObjCImpl->finish(atEnd);
2024 Diag(atEnd.
getBegin(), diag::err_expected_objc_container);
2028Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2030 finish(P.Tok.getLocation());
2031 if (P.isEofOrEom()) {
2032 P.Diag(P.Tok, diag::err_objc_missing_end)
2034 P.Diag(Dcl->getBeginLoc(), diag::note_objc_container_start)
2038 assert(LateParsedObjCMethods.empty());
2041void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
2043 P.Actions.ObjC().DefaultSynthesizeProperties(P.getCurScope(), Dcl,
2045 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2046 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2049 P.Actions.ObjC().ActOnAtEnd(P.getCurScope(), AtEnd);
2052 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2053 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2057 for (LateParsedObjCMethodContainer::iterator
2058 I = LateParsedObjCMethods.begin(),
2059 E = LateParsedObjCMethods.end(); I != E; ++I)
2061 LateParsedObjCMethods.clear();
2066 P.CurParsedObjCImpl = PrevParsedObjCImpl;
2070Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
2071 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
2072 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2074 if (expectIdentifier())
2076 IdentifierInfo *aliasId = Tok.getIdentifierInfo();
2078 if (expectIdentifier())
2080 IdentifierInfo *classId = Tok.getIdentifierInfo();
2082 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@compatibility_alias");
2083 return Actions.ObjC().ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
2087Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
2088 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
2089 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2093 if (Tok.is(tok::code_completion)) {
2095 Actions.CodeCompletion().CodeCompleteObjCPropertyDefinition(
2100 if (Tok.isNot(tok::identifier)) {
2101 Diag(Tok, diag::err_synthesized_property_name);
2106 IdentifierInfo *propertyIvar =
nullptr;
2107 IdentifierInfo *propertyId = Tok.getIdentifierInfo();
2109 SourceLocation propertyIvarLoc;
2112 if (Tok.is(tok::code_completion)) {
2114 Actions.CodeCompletion().CodeCompleteObjCPropertySynthesizeIvar(
2119 if (expectIdentifier())
2121 propertyIvar = Tok.getIdentifierInfo();
2124 Actions.ObjC().ActOnPropertyImplDecl(
2125 getCurScope(), atLoc, propertyLoc,
true, propertyId, propertyIvar,
2127 if (Tok.isNot(tok::comma))
2131 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@synthesize");
2135Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
2136 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
2137 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2140 bool isClassProperty =
false;
2141 if (Tok.is(tok::l_paren)) {
2143 const IdentifierInfo *II = Tok.getIdentifierInfo();
2146 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2150 if (II->
isStr(
"class")) {
2151 isClassProperty =
true;
2152 if (Tok.isNot(tok::r_paren)) {
2153 Diag(Tok, diag::err_expected) << tok::r_paren;
2158 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2165 if (Tok.is(tok::code_completion)) {
2167 Actions.CodeCompletion().CodeCompleteObjCPropertyDefinition(
2172 if (expectIdentifier()) {
2177 IdentifierInfo *propertyId = Tok.getIdentifierInfo();
2179 Actions.ObjC().ActOnPropertyImplDecl(
2180 getCurScope(), atLoc, propertyLoc,
false, propertyId,
nullptr,
2185 if (Tok.isNot(tok::comma))
2189 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@dynamic");
2193StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
2196 if (Tok.isNot(tok::semi)) {
2204 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@throw");
2205 return Actions.ObjC().ActOnObjCAtThrowStmt(atLoc, Res.
get(),
getCurScope());
2209Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
2211 if (Tok.isNot(tok::l_paren)) {
2212 Diag(Tok, diag::err_expected_lparen_after) <<
"@synchronized";
2220 if (Tok.is(tok::r_paren)) {
2223 if (!operand.isInvalid())
2224 Diag(Tok, diag::err_expected) << tok::r_paren;
2231 if (Tok.isNot(tok::l_brace)) {
2232 if (!operand.isInvalid())
2233 Diag(Tok, diag::err_expected) << tok::l_brace;
2238 if (!operand.isInvalid())
2240 Actions.ObjC().ActOnObjCAtSynchronizedOperand(atLoc, operand.get());
2244 StmtResult body(ParseCompoundStatementBody());
2249 if (operand.isInvalid())
2252 if (body.isInvalid())
2253 body = Actions.ActOnNullStmt(Tok.getLocation());
2255 return Actions.ObjC().ActOnObjCAtSynchronizedStmt(atLoc, operand.get(),
2259StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
2260 bool catch_or_finally_seen =
false;
2263 if (Tok.isNot(tok::l_brace)) {
2264 Diag(Tok, diag::err_expected) << tok::l_brace;
2270 StmtResult TryBody(ParseCompoundStatementBody());
2272 if (TryBody.isInvalid())
2273 TryBody = Actions.ActOnNullStmt(Tok.getLocation());
2275 while (Tok.is(tok::at)) {
2285 if (Tok.isObjCAtKeyword(tok::objc_catch)) {
2286 Decl *FirstPart =
nullptr;
2288 if (Tok.is(tok::l_paren)) {
2293 if (Tok.isNot(tok::ellipsis)) {
2294 DeclSpec DS(AttrFactory);
2295 ParsedTemplateInfo TemplateInfo;
2296 ParseDeclarationSpecifiers(DS, TemplateInfo);
2299 ParseDeclarator(ParmDecl);
2304 Actions.ObjC().ActOnObjCExceptionDecl(
getCurScope(), ParmDecl);
2308 SourceLocation RParenLoc;
2310 if (Tok.is(tok::r_paren))
2311 RParenLoc = ConsumeParen();
2316 if (Tok.is(tok::l_brace))
2317 CatchBody = ParseCompoundStatementBody();
2319 Diag(Tok, diag::err_expected) << tok::l_brace;
2320 if (CatchBody.isInvalid())
2321 CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
2323 StmtResult Catch = Actions.ObjC().ActOnObjCAtCatchStmt(
2324 AtCatchFinallyLoc, RParenLoc, FirstPart, CatchBody.get());
2325 if (!Catch.isInvalid())
2326 CatchStmts.push_back(Catch.get());
2329 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2333 catch_or_finally_seen =
true;
2335 assert(Tok.isObjCAtKeyword(tok::objc_finally) &&
"Lookahead confused?");
2340 bool ShouldCapture =
2343 Actions.ActOnCapturedRegionStart(Tok.getLocation(),
getCurScope(),
2347 if (Tok.is(tok::l_brace))
2348 FinallyBody = ParseCompoundStatementBody();
2350 Diag(Tok, diag::err_expected) << tok::l_brace;
2352 if (FinallyBody.isInvalid()) {
2353 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
2355 Actions.ActOnCapturedRegionError();
2356 }
else if (ShouldCapture) {
2357 FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get());
2360 FinallyStmt = Actions.ObjC().ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
2362 catch_or_finally_seen =
true;
2366 if (!catch_or_finally_seen) {
2367 Diag(atLoc, diag::err_missing_catch_finally);
2371 return Actions.ObjC().ActOnObjCAtTryStmt(atLoc, TryBody.get(), CatchStmts,
2376Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
2378 if (Tok.isNot(tok::l_brace)) {
2379 Diag(Tok, diag::err_expected) << tok::l_brace;
2386 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2389 if (AutoreleasePoolBody.isInvalid())
2390 AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
2391 return Actions.ObjC().ActOnObjCAutoreleasePoolStmt(atLoc,
2392 AutoreleasePoolBody.get());
2395void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
2396 if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
2397 trySkippingFunctionBody()) {
2398 Actions.ActOnSkippedFunctionBody(MDecl);
2402 LexedMethod* LM =
new LexedMethod(
this, MDecl);
2403 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2406 Toks.push_back(Tok);
2407 if (Tok.is(tok::kw_try)) {
2409 if (Tok.is(tok::colon)) {
2410 Toks.push_back(Tok);
2412 while (Tok.isNot(tok::l_brace)) {
2413 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2414 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2417 Toks.push_back(Tok);
2419 else if (Tok.is(tok::colon)) {
2422 while (Tok.isNot(tok::l_brace)) {
2423 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2424 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2426 Toks.push_back(Tok);
2430 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2431 while (Tok.is(tok::kw_catch)) {
2432 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
2433 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2437Decl *Parser::ParseObjCMethodDefinition() {
2438 Decl *MDecl = ParseObjCMethodPrototype();
2440 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, MDecl, Tok.getLocation(),
2441 "parsing Objective-C method");
2444 if (Tok.is(tok::semi)) {
2445 if (CurParsedObjCImpl) {
2446 Diag(Tok, diag::warn_semicolon_before_method_body)
2453 if (Tok.isNot(tok::l_brace)) {
2454 Diag(Tok, diag::err_expected_method_body);
2460 if (Tok.isNot(tok::l_brace))
2471 Actions.ObjC().AddAnyMethodToGlobalPool(MDecl);
2472 assert (CurParsedObjCImpl
2473 &&
"ParseObjCMethodDefinition - Method out of @implementation");
2475 StashAwayMethodOrFunctionBodyTokens(MDecl);
2479StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
2480 ParsedStmtContext StmtCtx) {
2481 if (Tok.is(tok::code_completion)) {
2483 Actions.CodeCompletion().CodeCompleteObjCAtStatement(
getCurScope());
2487 if (Tok.isObjCAtKeyword(tok::objc_try))
2488 return ParseObjCTryStmt(AtLoc);
2490 if (Tok.isObjCAtKeyword(tok::objc_throw))
2491 return ParseObjCThrowStmt(AtLoc);
2493 if (Tok.isObjCAtKeyword(tok::objc_synchronized))
2494 return ParseObjCSynchronizedStmt(AtLoc);
2496 if (Tok.isObjCAtKeyword(tok::objc_autoreleasepool))
2497 return ParseObjCAutoreleasePoolStmt(AtLoc);
2499 if (Tok.isObjCAtKeyword(tok::objc_import) &&
2502 return Actions.ActOnNullStmt(Tok.getLocation());
2505 ExprStatementTokLoc = AtLoc;
2506 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2516 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2517 return handleExprStmt(Res, StmtCtx);
2520ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
2521 switch (Tok.getKind()) {
2522 case tok::code_completion:
2524 Actions.CodeCompletion().CodeCompleteObjCAtExpression(
getCurScope());
2532 if (!Tok.is(tok::numeric_constant)) {
2533 const char *Symbol =
nullptr;
2535 case tok::minus: Symbol =
"-";
break;
2536 case tok::plus: Symbol =
"+";
break;
2537 default: llvm_unreachable(
"missing unary operator case");
2539 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2544 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2545 if (Lit.isInvalid()) {
2550 Lit = Actions.ActOnUnaryOp(
getCurScope(), OpLoc, Kind, Lit.get());
2551 if (Lit.isInvalid())
2554 return ParsePostfixExpressionSuffix(
2555 Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get()));
2558 case tok::string_literal:
2559 case tok::wide_string_literal:
2560 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2562 case tok::char_constant:
2563 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2565 case tok::numeric_constant:
2566 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2569 case tok::kw___objc_yes:
2570 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
true));
2572 case tok::kw___objc_no:
2573 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
false));
2577 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2581 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2585 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2588 if (Tok.getIdentifierInfo() ==
nullptr)
2591 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
2592 case tok::objc_encode:
2593 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2594 case tok::objc_protocol:
2595 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2596 case tok::objc_selector:
2597 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2598 case tok::objc_available:
2599 return ParseAvailabilityCheckExpr(AtLoc);
2601 const char *str =
nullptr;
2606 ExprStatementTokLoc == AtLoc) {
2607 char ch = Tok.getIdentifierInfo()->getNameStart()[0];
2610 : (ch ==
'f' ?
"finally"
2611 : (ch ==
'a' ?
"autoreleasepool" :
nullptr));
2614 SourceLocation kwLoc = Tok.getLocation();
2625bool Parser::ParseObjCXXMessageReceiver(
bool &IsExpr,
void *&TypeOrExpr) {
2628 if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2629 tok::annot_cxxscope))
2640 TypeOrExpr = Receiver.
get();
2648 DeclSpec DS(AttrFactory);
2649 ParseCXXSimpleTypeSpecifier(DS);
2651 if (Tok.is(tok::l_paren)) {
2664 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2666 Receiver = ParsePostfixExpressionSuffix(Receiver.
get());
2668 Receiver = ParseRHSOfBinaryExpression(Receiver.
get(),
prec::Comma);
2673 TypeOrExpr = Receiver.
get();
2683 if (
Type.isInvalid())
2687 TypeOrExpr =
Type.get().getAsOpaquePtr();
2691bool Parser::isSimpleObjCMessageExpression() {
2693 "Incorrect start for isSimpleObjCMessageExpression");
2698bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2700 InMessageExpression)
2705 if (Tok.is(tok::annot_typename))
2707 else if (Tok.is(tok::identifier))
2708 Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(),
2714 if (
Type.isUsable() &&
Type.get().get()->isObjCObjectOrInterfaceType()) {
2716 if (AfterNext.
isOneOf(tok::colon, tok::r_square)) {
2717 if (Tok.is(tok::identifier))
2720 return Tok.is(tok::annot_typename);
2727ExprResult Parser::ParseObjCMessageExpression() {
2728 assert(Tok.is(tok::l_square) &&
"'[' expected");
2729 SourceLocation LBracLoc = ConsumeBracket();
2731 if (Tok.is(tok::code_completion)) {
2733 Actions.CodeCompletion().CodeCompleteObjCMessageReceiver(
getCurScope());
2746 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
2748 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
2753 void *TypeOrExpr =
nullptr;
2754 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
2760 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
nullptr,
2761 static_cast<Expr *
>(TypeOrExpr));
2763 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
2768 if (Tok.is(tok::identifier)) {
2769 IdentifierInfo *Name = Tok.getIdentifierInfo();
2770 SourceLocation NameLoc = Tok.getLocation();
2772 switch (Actions.ObjC().getObjCMessageKind(
2773 getCurScope(), Name, NameLoc, Name == Ident_super,
2776 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
2780 if (!ReceiverType) {
2788 if (Tok.is(tok::less)) {
2789 SourceLocation NewEndLoc;
2791 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
2799 ReceiverType = NewReceiverType.
get();
2802 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
2803 ReceiverType,
nullptr);
2818 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
nullptr,
2823Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
2824 SourceLocation SuperLoc,
2826 Expr *ReceiverExpr) {
2829 if (Tok.is(tok::code_completion)) {
2832 Actions.CodeCompletion().CodeCompleteObjCSuperMessage(
2834 else if (ReceiverType)
2835 Actions.CodeCompletion().CodeCompleteObjCClassMessage(
2838 Actions.CodeCompletion().CodeCompleteObjCInstanceMessage(
2845 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
2847 SmallVector<const IdentifierInfo *, 12> KeyIdents;
2848 SmallVector<SourceLocation, 12> KeyLocs;
2849 ExprVector KeyExprs;
2851 if (Tok.is(tok::colon)) {
2854 KeyIdents.push_back(selIdent);
2855 KeyLocs.push_back(Loc);
2857 if (ExpectAndConsume(tok::colon)) {
2867 if (Tok.is(tok::code_completion)) {
2870 Actions.CodeCompletion().CodeCompleteObjCSuperMessage(
2873 else if (ReceiverType)
2874 Actions.CodeCompletion().CodeCompleteObjCClassMessage(
2878 Actions.CodeCompletion().CodeCompleteObjCInstanceMessage(
2887 Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
2888 Expr = ParseBraceInitializer();
2902 KeyExprs.push_back(Res.
get());
2905 if (Tok.is(tok::code_completion)) {
2908 Actions.CodeCompletion().CodeCompleteObjCSuperMessage(
2911 else if (ReceiverType)
2912 Actions.CodeCompletion().CodeCompleteObjCClassMessage(
2916 Actions.CodeCompletion().CodeCompleteObjCInstanceMessage(
2923 selIdent = ParseObjCSelectorPiece(Loc);
2924 if (!selIdent && Tok.isNot(tok::colon))
2929 while (Tok.is(tok::comma)) {
2934 if (Tok.is(tok::colon)) {
2935 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
2946 KeyExprs.push_back(Res.
get());
2948 }
else if (!selIdent) {
2949 Diag(Tok, diag::err_expected) << tok::identifier;
2958 if (Tok.isNot(tok::r_square)) {
2959 Diag(Tok, diag::err_expected)
2960 << (Tok.is(tok::identifier) ? tok::colon : tok::r_square);
2968 SourceLocation RBracLoc = ConsumeBracket();
2970 unsigned nKeys = KeyIdents.size();
2972 KeyIdents.push_back(selIdent);
2973 KeyLocs.push_back(Loc);
2975 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
2978 return Actions.ObjC().ActOnSuperMessage(
2979 getCurScope(), SuperLoc, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs);
2980 else if (ReceiverType)
2981 return Actions.ObjC().ActOnClassMessage(
getCurScope(), ReceiverType, Sel,
2982 LBracLoc, KeyLocs, RBracLoc,
2984 return Actions.ObjC().ActOnInstanceMessage(
2985 getCurScope(), ReceiverExpr, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs);
2988ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
2995 SmallVector<SourceLocation, 4> AtLocs;
2996 ExprVector AtStrings;
2997 AtLocs.push_back(AtLoc);
2998 AtStrings.push_back(Res.
get());
3000 while (Tok.is(tok::at)) {
3004 if (!isTokenStringLiteral())
3008 if (Lit.isInvalid())
3011 AtStrings.push_back(Lit.get());
3014 return Actions.ObjC().ParseObjCStringLiteral(AtLocs.data(), AtStrings);
3017ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc,
3020 return Actions.ObjC().ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
3023ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {
3024 ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
3025 if (Lit.isInvalid()) {
3029 return Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get());
3032ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {
3033 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
3034 if (Lit.isInvalid()) {
3038 return Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get());
3042Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) {
3043 if (Tok.isNot(tok::l_paren))
3044 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@");
3049 if (
T.consumeClose())
3052 if (ValueExpr.isInvalid())
3057 SourceLocation LPLoc =
T.getOpenLocation(), RPLoc =
T.getCloseLocation();
3058 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
3059 return Actions.ObjC().BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
3063ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
3064 ExprVector ElementExprs;
3067 bool HasInvalidEltExpr =
false;
3068 while (Tok.isNot(tok::r_square)) {
3080 if (Tok.is(tok::ellipsis))
3083 HasInvalidEltExpr =
true;
3085 ElementExprs.push_back(Res.
get());
3087 if (Tok.is(tok::comma))
3089 else if (Tok.isNot(tok::r_square))
3090 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_square
3093 SourceLocation EndLoc = ConsumeBracket();
3095 if (HasInvalidEltExpr)
3099 return Actions.ObjC().BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args);
3102ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
3103 SmallVector<ObjCDictionaryElement, 4> Elements;
3105 while (Tok.isNot(tok::r_brace)) {
3120 if (ExpectAndConsume(tok::colon)) {
3126 if (ValueExpr.isInvalid()) {
3137 SourceLocation EllipsisLoc;
3143 ObjCDictionaryElement Element = {KeyExpr.
get(), ValueExpr.get(),
3144 EllipsisLoc, std::nullopt};
3145 Elements.push_back(Element);
3148 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_brace
3151 SourceLocation EndLoc = ConsumeBrace();
3154 return Actions.ObjC().BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc),
3159Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
3160 assert(Tok.isObjCAtKeyword(tok::objc_encode) &&
"Not an @encode expression!");
3164 if (Tok.isNot(tok::l_paren))
3165 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@encode");
3177 return Actions.ObjC().ParseObjCEncodeExpression(
3178 AtLoc, EncLoc,
T.getOpenLocation(), Ty.
get(),
T.getCloseLocation());
3182Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
3185 if (Tok.isNot(tok::l_paren))
3186 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@protocol");
3191 if (expectIdentifier())
3194 IdentifierInfo *protocolId = Tok.getIdentifierInfo();
3199 return Actions.ObjC().ParseObjCProtocolExpression(
3200 protocolId, AtLoc, ProtoLoc,
T.getOpenLocation(), ProtoIdLoc,
3201 T.getCloseLocation());
3204ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
3207 if (Tok.isNot(tok::l_paren))
3208 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@selector");
3210 SmallVector<const IdentifierInfo *, 12> KeyIdents;
3211 SourceLocation SelectorNameLoc;
3215 bool HasOptionalParen = Tok.is(tok::l_paren);
3216 if (HasOptionalParen)
3219 if (Tok.is(tok::code_completion)) {
3221 Actions.CodeCompletion().CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3225 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelectorNameLoc);
3227 Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3228 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3230 KeyIdents.push_back(SelIdent);
3232 unsigned nColons = 0;
3233 if (Tok.isNot(tok::r_paren)) {
3237 KeyIdents.push_back(
nullptr);
3238 }
else if (ExpectAndConsume(tok::colon))
3242 if (Tok.is(tok::r_paren))
3245 if (Tok.is(tok::code_completion)) {
3247 Actions.CodeCompletion().CodeCompleteObjCSelector(
getCurScope(),
3254 SelIdent = ParseObjCSelectorPiece(Loc);
3255 KeyIdents.push_back(SelIdent);
3256 if (!SelIdent && Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3260 if (HasOptionalParen && Tok.is(tok::r_paren))
3263 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
3264 return Actions.ObjC().ParseObjCSelectorExpression(
3265 Sel, AtLoc, SelectorKeywordLoc, SelectorNameLoc,
T.getOpenLocation(),
3266 T.getCloseLocation(), !HasOptionalParen);
3269void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM,
bool parseMethod) {
3271 Decl *MCDecl = LM.D;
3273 MCDecl && ((parseMethod && !Actions.ObjC().isObjCMethodDecl(MCDecl)) ||
3274 (!parseMethod && Actions.ObjC().isObjCMethodDecl(MCDecl)));
3279 SourceLocation OrigLoc = Tok.getLocation();
3281 assert(!LM.Toks.empty() &&
"ParseLexedObjCMethodDef - Empty body!");
3289 LM.Toks.push_back(Eof);
3292 LM.Toks.push_back(Tok);
3293 PP.EnterTokenStream(LM.Toks,
true,
true);
3298 assert(Tok.isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3299 "Inline objective-c method not starting with '{' or 'try' or ':'");
3304 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
3309 Actions.ObjC().ActOnStartOfObjCMethodDef(
getCurScope(), MCDecl);
3311 Actions.ActOnStartOfFunctionDef(
getCurScope(), MCDecl);
3312 ParseFunctionBody(MCDecl, BodyScope);
3314 if (Tok.getLocation() != OrigLoc) {
3320 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
3322 while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
3327 if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl)
Defines the clang::ASTContext interface.
This file defines the classes used to store parsed information about declaration-specifiers and decla...
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.
static void diagnoseRedundantPropertyNullability(Parser &P, ObjCDeclSpec &DS, NullabilityKind nullability, SourceLocation nullabilityLoc)
Diagnose redundant or conflicting nullability information.
static void takeDeclAttributes(ParsedAttributes &attrs, Declarator &D)
takeDeclAttributes - Take all the decl attributes from the given declarator and add them to the given...
static void takeDeclAttributesAppend(ParsedAttributesView &attrs, ParsedAttributesView &from)
Take all the decl attributes out of the given list and add them to the given attribute set.
static bool isTopLevelObjCKeyword(tok::ObjCKeywordKind DirectiveKind)
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
ObjCTypeParamListScope(Sema &Actions, Scope *S)
void enter(ObjCTypeParamList *P)
~ObjCTypeParamListScope()
void takeAllFrom(AttributePool &pool)
Take the given pool's allocations and add them to this pool.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
ParsedAttributes & getAttributes()
AttributePool & getAttributePool() const
Decl - This represents one declaration (or definition), e.g.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
SourceLocation getBeginLoc() const LLVM_READONLY
Information about one declarator, including the parsed type information and the identifier.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
const ParsedAttributes & getAttributes() const
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
const ParsedAttributesView & getDeclarationAttributes() const
AttributePool & getAttributePool() const
DeclSpec & getMutableDeclSpec()
getMutableDeclSpec - Return a non-const version of the DeclSpec.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
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.
One of these records is kept for each identifier that is lexed.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
ObjCContainerDecl - Represents a container for method declarations.
Captures information about "declaration specifiers" specific to Objective-C.
void setObjCDeclQualifier(ObjCDeclQualifier DQVal)
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCDeclQualifier
ObjCDeclQualifier - Qualifier used on types in method declarations.
void setSetterName(IdentifierInfo *name, SourceLocation loc)
const IdentifierInfo * getSetterName() const
ObjCDeclQualifier getObjCDeclQualifier() const
SourceLocation getNullabilityLoc() const
NullabilityKind getNullability() const
void setGetterName(IdentifierInfo *name, SourceLocation loc)
void setNullability(SourceLocation loc, NullabilityKind kind)
const IdentifierInfo * getGetterName() const
void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal)
void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition)
void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition)
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
static OpaquePtr getFromOpaquePtr(void *P)
ParsedAttr - Represents a syntactic attribute.
static const ParsedAttributesView & none()
void addAtEnd(ParsedAttr *newAttr)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
void takeAllPrependingFrom(ParsedAttributes &Other)
AttributePool & getPool() const
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, bool IsAddressOfOperand=false)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Preprocessor & getPreprocessor() const
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ParseStringLiteralExpression - This handles the various token types that form string literals,...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
friend class ColonProtectionRAIIObject
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
friend class InMessageExpressionRAIIObject
const TargetInfo & getTargetInfo() 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 ...
IdentifierInfo * getNullabilityKeyword(NullabilityKind nullability)
Retrieve the underscored keyword (_Nonnull, _Nullable) that corresponds to the given nullability kind...
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
SkipUntilFlags
Control flags for SkipUntil functions.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Scope - A scope is a transient data structure that is used while parsing the program.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ ObjCMethodScope
This scope corresponds to an Objective-C method body.
@ DeclScope
This is a scope that can contain a declaration.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
void CodeCompleteObjCClassForwardDecl(Scope *S)
@ PCC_Type
Code completion occurs where only a type is permitted.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_ObjCInterface
Code completion occurs within an Objective-C interface, protocol, or category.
@ PCC_ObjCInstanceVariableList
Code completion occurs within the list of instance variables in an Objective-C interface,...
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
@ ObjCInstanceMessage
The message is an instance message.
@ ObjCSuperMessage
The message is sent to 'super'.
Sema - This implements semantic analysis and AST building for C.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
SemaCodeCompletion & CodeCompletion()
ModuleImportState
An enumeration to represent the transition of states in parsing module fragments and imports.
@ NotACXX20Module
Not a C++20 TU, or an invalid state was found.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
void setEnd(SourceLocation e)
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setKind(tok::TokenKind K)
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)) {....
bool isOneOf(Ts... Ks) const
void setEofData(const void *D)
void setLocation(SourceLocation L)
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
bool acceptsObjCTypeParams() const
Determines if this is an ObjC interface type that may accept type parameters.
Defines the clang::TargetInfo interface.
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
DirectiveKind
Represents the kind of preprocessor directive or a module declaration that is tracked by the scanner ...
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Top level wrappers for InstallAPI frontend operations.
NullabilityKind
Describes the nullability of a particular type.
@ Nullable
Values of this type can be null.
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ NonNull
Values of this type can never be null.
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
std::pair< NullabilityKind, bool > DiagNullabilityKind
A nullability kind paired with a bit indicating whether it used a context-sensitive keyword.
MutableArrayRef< Expr * > MultiExprArg
@ Property
The type of a property.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Type
The name was classified as a type.
ObjCTypeParamVariance
Describes the variance of a given generic parameter.
@ Invariant
The parameter is invariant: must match exactly.
@ Contravariant
The parameter is contravariant, e.g., X<T> is a subtype of X when the type parameter is covariant and...
@ Covariant
The parameter is covariant, e.g., X<T> is a subtype of X when the type parameter is covariant and T i...
U cast(CodeGen::Address addr)
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
ActionResult< Stmt * > StmtResult
const ParsedAttributesView & getAttrs() const
If there are attributes applied to this declaratorchunk, return them.
ParsedAttributesView ArgAttrs
ArgAttrs - Attribute list for this argument.