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() || 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 P.CurParsedObjCImpl =
nullptr;
2039 assert(LateParsedObjCMethods.empty());
2042void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
2044 P.Actions.ObjC().DefaultSynthesizeProperties(P.getCurScope(), Dcl,
2046 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2047 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2050 P.Actions.ObjC().ActOnAtEnd(P.getCurScope(), AtEnd);
2053 for (
size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2054 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2058 for (LateParsedObjCMethodContainer::iterator
2059 I = LateParsedObjCMethods.begin(),
2060 E = LateParsedObjCMethods.end(); I != E; ++I)
2062 LateParsedObjCMethods.clear();
2067Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
2068 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
2069 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2071 if (expectIdentifier())
2073 IdentifierInfo *aliasId = Tok.getIdentifierInfo();
2075 if (expectIdentifier())
2077 IdentifierInfo *classId = Tok.getIdentifierInfo();
2079 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@compatibility_alias");
2080 return Actions.ObjC().ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
2084Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
2085 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
2086 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2090 if (Tok.is(tok::code_completion)) {
2092 Actions.CodeCompletion().CodeCompleteObjCPropertyDefinition(
2097 if (Tok.isNot(tok::identifier)) {
2098 Diag(Tok, diag::err_synthesized_property_name);
2103 IdentifierInfo *propertyIvar =
nullptr;
2104 IdentifierInfo *propertyId = Tok.getIdentifierInfo();
2106 SourceLocation propertyIvarLoc;
2109 if (Tok.is(tok::code_completion)) {
2111 Actions.CodeCompletion().CodeCompleteObjCPropertySynthesizeIvar(
2116 if (expectIdentifier())
2118 propertyIvar = Tok.getIdentifierInfo();
2121 Actions.ObjC().ActOnPropertyImplDecl(
2122 getCurScope(), atLoc, propertyLoc,
true, propertyId, propertyIvar,
2124 if (Tok.isNot(tok::comma))
2128 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@synthesize");
2132Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
2133 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
2134 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2137 bool isClassProperty =
false;
2138 if (Tok.is(tok::l_paren)) {
2140 const IdentifierInfo *II = Tok.getIdentifierInfo();
2143 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2147 if (II->
isStr(
"class")) {
2148 isClassProperty =
true;
2149 if (Tok.isNot(tok::r_paren)) {
2150 Diag(Tok, diag::err_expected) << tok::r_paren;
2155 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2162 if (Tok.is(tok::code_completion)) {
2164 Actions.CodeCompletion().CodeCompleteObjCPropertyDefinition(
2169 if (expectIdentifier()) {
2174 IdentifierInfo *propertyId = Tok.getIdentifierInfo();
2176 Actions.ObjC().ActOnPropertyImplDecl(
2177 getCurScope(), atLoc, propertyLoc,
false, propertyId,
nullptr,
2182 if (Tok.isNot(tok::comma))
2186 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@dynamic");
2190StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
2193 if (Tok.isNot(tok::semi)) {
2201 ExpectAndConsume(tok::semi, diag::err_expected_after,
"@throw");
2202 return Actions.ObjC().ActOnObjCAtThrowStmt(atLoc, Res.
get(),
getCurScope());
2206Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
2208 if (Tok.isNot(tok::l_paren)) {
2209 Diag(Tok, diag::err_expected_lparen_after) <<
"@synchronized";
2217 if (Tok.is(tok::r_paren)) {
2220 if (!operand.isInvalid())
2221 Diag(Tok, diag::err_expected) << tok::r_paren;
2228 if (Tok.isNot(tok::l_brace)) {
2229 if (!operand.isInvalid())
2230 Diag(Tok, diag::err_expected) << tok::l_brace;
2235 if (!operand.isInvalid())
2237 Actions.ObjC().ActOnObjCAtSynchronizedOperand(atLoc, operand.get());
2241 StmtResult body(ParseCompoundStatementBody());
2246 if (operand.isInvalid())
2249 if (body.isInvalid())
2250 body = Actions.ActOnNullStmt(Tok.getLocation());
2252 return Actions.ObjC().ActOnObjCAtSynchronizedStmt(atLoc, operand.get(),
2256StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
2257 bool catch_or_finally_seen =
false;
2260 if (Tok.isNot(tok::l_brace)) {
2261 Diag(Tok, diag::err_expected) << tok::l_brace;
2267 StmtResult TryBody(ParseCompoundStatementBody());
2269 if (TryBody.isInvalid())
2270 TryBody = Actions.ActOnNullStmt(Tok.getLocation());
2272 while (Tok.is(tok::at)) {
2282 if (Tok.isObjCAtKeyword(tok::objc_catch)) {
2283 Decl *FirstPart =
nullptr;
2285 if (Tok.is(tok::l_paren)) {
2290 if (Tok.isNot(tok::ellipsis)) {
2291 DeclSpec DS(AttrFactory);
2292 ParsedTemplateInfo TemplateInfo;
2293 ParseDeclarationSpecifiers(DS, TemplateInfo);
2296 ParseDeclarator(ParmDecl);
2301 Actions.ObjC().ActOnObjCExceptionDecl(
getCurScope(), ParmDecl);
2305 SourceLocation RParenLoc;
2307 if (Tok.is(tok::r_paren))
2308 RParenLoc = ConsumeParen();
2313 if (Tok.is(tok::l_brace))
2314 CatchBody = ParseCompoundStatementBody();
2316 Diag(Tok, diag::err_expected) << tok::l_brace;
2317 if (CatchBody.isInvalid())
2318 CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
2320 StmtResult Catch = Actions.ObjC().ActOnObjCAtCatchStmt(
2321 AtCatchFinallyLoc, RParenLoc, FirstPart, CatchBody.get());
2322 if (!Catch.isInvalid())
2323 CatchStmts.push_back(Catch.get());
2326 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2330 catch_or_finally_seen =
true;
2332 assert(Tok.isObjCAtKeyword(tok::objc_finally) &&
"Lookahead confused?");
2337 bool ShouldCapture =
2340 Actions.ActOnCapturedRegionStart(Tok.getLocation(),
getCurScope(),
2344 if (Tok.is(tok::l_brace))
2345 FinallyBody = ParseCompoundStatementBody();
2347 Diag(Tok, diag::err_expected) << tok::l_brace;
2349 if (FinallyBody.isInvalid()) {
2350 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
2352 Actions.ActOnCapturedRegionError();
2353 }
else if (ShouldCapture) {
2354 FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get());
2357 FinallyStmt = Actions.ObjC().ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
2359 catch_or_finally_seen =
true;
2363 if (!catch_or_finally_seen) {
2364 Diag(atLoc, diag::err_missing_catch_finally);
2368 return Actions.ObjC().ActOnObjCAtTryStmt(atLoc, TryBody.get(), CatchStmts,
2373Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
2375 if (Tok.isNot(tok::l_brace)) {
2376 Diag(Tok, diag::err_expected) << tok::l_brace;
2383 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2386 if (AutoreleasePoolBody.isInvalid())
2387 AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
2388 return Actions.ObjC().ActOnObjCAutoreleasePoolStmt(atLoc,
2389 AutoreleasePoolBody.get());
2392void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
2393 if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
2394 trySkippingFunctionBody()) {
2395 Actions.ActOnSkippedFunctionBody(MDecl);
2399 LexedMethod* LM =
new LexedMethod(
this, MDecl);
2400 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2403 Toks.push_back(Tok);
2404 if (Tok.is(tok::kw_try)) {
2406 if (Tok.is(tok::colon)) {
2407 Toks.push_back(Tok);
2409 while (Tok.isNot(tok::l_brace)) {
2410 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2411 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2414 Toks.push_back(Tok);
2416 else if (Tok.is(tok::colon)) {
2419 while (Tok.isNot(tok::l_brace)) {
2420 ConsumeAndStoreUntil(tok::l_paren, Toks,
false);
2421 ConsumeAndStoreUntil(tok::r_paren, Toks,
false);
2423 Toks.push_back(Tok);
2427 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2428 while (Tok.is(tok::kw_catch)) {
2429 ConsumeAndStoreUntil(tok::l_brace, Toks,
false);
2430 ConsumeAndStoreUntil(tok::r_brace, Toks,
false);
2434Decl *Parser::ParseObjCMethodDefinition() {
2435 Decl *MDecl = ParseObjCMethodPrototype();
2437 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, MDecl, Tok.getLocation(),
2438 "parsing Objective-C method");
2441 if (Tok.is(tok::semi)) {
2442 if (CurParsedObjCImpl) {
2443 Diag(Tok, diag::warn_semicolon_before_method_body)
2450 if (Tok.isNot(tok::l_brace)) {
2451 Diag(Tok, diag::err_expected_method_body);
2457 if (Tok.isNot(tok::l_brace))
2468 Actions.ObjC().AddAnyMethodToGlobalPool(MDecl);
2469 assert (CurParsedObjCImpl
2470 &&
"ParseObjCMethodDefinition - Method out of @implementation");
2472 StashAwayMethodOrFunctionBodyTokens(MDecl);
2476StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
2477 ParsedStmtContext StmtCtx) {
2478 if (Tok.is(tok::code_completion)) {
2480 Actions.CodeCompletion().CodeCompleteObjCAtStatement(
getCurScope());
2484 if (Tok.isObjCAtKeyword(tok::objc_try))
2485 return ParseObjCTryStmt(AtLoc);
2487 if (Tok.isObjCAtKeyword(tok::objc_throw))
2488 return ParseObjCThrowStmt(AtLoc);
2490 if (Tok.isObjCAtKeyword(tok::objc_synchronized))
2491 return ParseObjCSynchronizedStmt(AtLoc);
2493 if (Tok.isObjCAtKeyword(tok::objc_autoreleasepool))
2494 return ParseObjCAutoreleasePoolStmt(AtLoc);
2496 if (Tok.isObjCAtKeyword(tok::objc_import) &&
2499 return Actions.ActOnNullStmt(Tok.getLocation());
2502 ExprStatementTokLoc = AtLoc;
2503 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2513 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2514 return handleExprStmt(Res, StmtCtx);
2517ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
2518 switch (Tok.getKind()) {
2519 case tok::code_completion:
2521 Actions.CodeCompletion().CodeCompleteObjCAtExpression(
getCurScope());
2529 if (!Tok.is(tok::numeric_constant)) {
2530 const char *Symbol =
nullptr;
2532 case tok::minus: Symbol =
"-";
break;
2533 case tok::plus: Symbol =
"+";
break;
2534 default: llvm_unreachable(
"missing unary operator case");
2536 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2541 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2542 if (Lit.isInvalid()) {
2547 Lit = Actions.ActOnUnaryOp(
getCurScope(), OpLoc, Kind, Lit.get());
2548 if (Lit.isInvalid())
2551 return ParsePostfixExpressionSuffix(
2552 Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get()));
2555 case tok::string_literal:
2556 case tok::wide_string_literal:
2557 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2559 case tok::char_constant:
2560 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2562 case tok::numeric_constant:
2563 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2566 case tok::kw___objc_yes:
2567 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
true));
2569 case tok::kw___objc_no:
2570 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc,
false));
2574 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2578 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2582 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2585 if (Tok.getIdentifierInfo() ==
nullptr)
2588 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
2589 case tok::objc_encode:
2590 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2591 case tok::objc_protocol:
2592 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2593 case tok::objc_selector:
2594 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2595 case tok::objc_available:
2596 return ParseAvailabilityCheckExpr(AtLoc);
2598 const char *str =
nullptr;
2603 ExprStatementTokLoc == AtLoc) {
2604 char ch = Tok.getIdentifierInfo()->getNameStart()[0];
2607 : (ch ==
'f' ?
"finally"
2608 : (ch ==
'a' ?
"autoreleasepool" :
nullptr));
2611 SourceLocation kwLoc = Tok.getLocation();
2622bool Parser::ParseObjCXXMessageReceiver(
bool &IsExpr,
void *&TypeOrExpr) {
2625 if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2626 tok::annot_cxxscope))
2637 TypeOrExpr = Receiver.
get();
2645 DeclSpec DS(AttrFactory);
2646 ParseCXXSimpleTypeSpecifier(DS);
2648 if (Tok.is(tok::l_paren)) {
2661 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2663 Receiver = ParsePostfixExpressionSuffix(Receiver.
get());
2665 Receiver = ParseRHSOfBinaryExpression(Receiver.
get(),
prec::Comma);
2670 TypeOrExpr = Receiver.
get();
2680 if (
Type.isInvalid())
2684 TypeOrExpr =
Type.get().getAsOpaquePtr();
2688bool Parser::isSimpleObjCMessageExpression() {
2690 "Incorrect start for isSimpleObjCMessageExpression");
2695bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2697 InMessageExpression)
2702 if (Tok.is(tok::annot_typename))
2704 else if (Tok.is(tok::identifier))
2705 Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(),
2711 if (
Type.isUsable() &&
Type.get().get()->isObjCObjectOrInterfaceType()) {
2713 if (AfterNext.
isOneOf(tok::colon, tok::r_square)) {
2714 if (Tok.is(tok::identifier))
2717 return Tok.is(tok::annot_typename);
2724ExprResult Parser::ParseObjCMessageExpression() {
2725 assert(Tok.is(tok::l_square) &&
"'[' expected");
2726 SourceLocation LBracLoc = ConsumeBracket();
2728 if (Tok.is(tok::code_completion)) {
2730 Actions.CodeCompletion().CodeCompleteObjCMessageReceiver(
getCurScope());
2743 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
2745 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
2750 void *TypeOrExpr =
nullptr;
2751 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
2757 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
nullptr,
2758 static_cast<Expr *
>(TypeOrExpr));
2760 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
2765 if (Tok.is(tok::identifier)) {
2766 IdentifierInfo *Name = Tok.getIdentifierInfo();
2767 SourceLocation NameLoc = Tok.getLocation();
2769 switch (Actions.ObjC().getObjCMessageKind(
2770 getCurScope(), Name, NameLoc, Name == Ident_super,
2773 return ParseObjCMessageExpressionBody(LBracLoc,
ConsumeToken(),
nullptr,
2777 if (!ReceiverType) {
2785 if (Tok.is(tok::less)) {
2786 SourceLocation NewEndLoc;
2788 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
2796 ReceiverType = NewReceiverType.
get();
2799 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
2800 ReceiverType,
nullptr);
2815 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
nullptr,
2820Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
2821 SourceLocation SuperLoc,
2823 Expr *ReceiverExpr) {
2826 if (Tok.is(tok::code_completion)) {
2829 Actions.CodeCompletion().CodeCompleteObjCSuperMessage(
2831 else if (ReceiverType)
2832 Actions.CodeCompletion().CodeCompleteObjCClassMessage(
2835 Actions.CodeCompletion().CodeCompleteObjCInstanceMessage(
2842 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
2844 SmallVector<const IdentifierInfo *, 12> KeyIdents;
2845 SmallVector<SourceLocation, 12> KeyLocs;
2846 ExprVector KeyExprs;
2848 if (Tok.is(tok::colon)) {
2851 KeyIdents.push_back(selIdent);
2852 KeyLocs.push_back(Loc);
2854 if (ExpectAndConsume(tok::colon)) {
2864 if (Tok.is(tok::code_completion)) {
2867 Actions.CodeCompletion().CodeCompleteObjCSuperMessage(
2870 else if (ReceiverType)
2871 Actions.CodeCompletion().CodeCompleteObjCClassMessage(
2875 Actions.CodeCompletion().CodeCompleteObjCInstanceMessage(
2884 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2885 Expr = ParseBraceInitializer();
2899 KeyExprs.push_back(Res.
get());
2902 if (Tok.is(tok::code_completion)) {
2905 Actions.CodeCompletion().CodeCompleteObjCSuperMessage(
2908 else if (ReceiverType)
2909 Actions.CodeCompletion().CodeCompleteObjCClassMessage(
2913 Actions.CodeCompletion().CodeCompleteObjCInstanceMessage(
2920 selIdent = ParseObjCSelectorPiece(Loc);
2921 if (!selIdent && Tok.isNot(tok::colon))
2926 while (Tok.is(tok::comma)) {
2931 if (Tok.is(tok::colon)) {
2932 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
2943 KeyExprs.push_back(Res.
get());
2945 }
else if (!selIdent) {
2946 Diag(Tok, diag::err_expected) << tok::identifier;
2955 if (Tok.isNot(tok::r_square)) {
2956 Diag(Tok, diag::err_expected)
2957 << (Tok.is(tok::identifier) ? tok::colon : tok::r_square);
2965 SourceLocation RBracLoc = ConsumeBracket();
2967 unsigned nKeys = KeyIdents.size();
2969 KeyIdents.push_back(selIdent);
2970 KeyLocs.push_back(Loc);
2972 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
2975 return Actions.ObjC().ActOnSuperMessage(
2976 getCurScope(), SuperLoc, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs);
2977 else if (ReceiverType)
2978 return Actions.ObjC().ActOnClassMessage(
getCurScope(), ReceiverType, Sel,
2979 LBracLoc, KeyLocs, RBracLoc,
2981 return Actions.ObjC().ActOnInstanceMessage(
2982 getCurScope(), ReceiverExpr, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs);
2985ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
2992 SmallVector<SourceLocation, 4> AtLocs;
2993 ExprVector AtStrings;
2994 AtLocs.push_back(AtLoc);
2995 AtStrings.push_back(Res.
get());
2997 while (Tok.is(tok::at)) {
3001 if (!isTokenStringLiteral())
3005 if (Lit.isInvalid())
3008 AtStrings.push_back(Lit.get());
3011 return Actions.ObjC().ParseObjCStringLiteral(AtLocs.data(), AtStrings);
3014ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc,
3017 return Actions.ObjC().ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
3020ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {
3021 ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
3022 if (Lit.isInvalid()) {
3026 return Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get());
3029ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {
3030 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
3031 if (Lit.isInvalid()) {
3035 return Actions.ObjC().BuildObjCNumericLiteral(AtLoc, Lit.get());
3039Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) {
3040 if (Tok.isNot(tok::l_paren))
3041 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@");
3046 if (
T.consumeClose())
3049 if (ValueExpr.isInvalid())
3054 SourceLocation LPLoc =
T.getOpenLocation(), RPLoc =
T.getCloseLocation();
3055 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
3056 return Actions.ObjC().BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
3060ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
3061 ExprVector ElementExprs;
3064 bool HasInvalidEltExpr =
false;
3065 while (Tok.isNot(tok::r_square)) {
3077 if (Tok.is(tok::ellipsis))
3080 HasInvalidEltExpr =
true;
3082 ElementExprs.push_back(Res.
get());
3084 if (Tok.is(tok::comma))
3086 else if (Tok.isNot(tok::r_square))
3087 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_square
3090 SourceLocation EndLoc = ConsumeBracket();
3092 if (HasInvalidEltExpr)
3096 return Actions.ObjC().BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args);
3099ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
3100 SmallVector<ObjCDictionaryElement, 4> Elements;
3102 while (Tok.isNot(tok::r_brace)) {
3117 if (ExpectAndConsume(tok::colon)) {
3123 if (ValueExpr.isInvalid()) {
3134 SourceLocation EllipsisLoc;
3140 ObjCDictionaryElement Element = {KeyExpr.
get(), ValueExpr.get(),
3141 EllipsisLoc, std::nullopt};
3142 Elements.push_back(Element);
3145 return ExprError(
Diag(Tok, diag::err_expected_either) << tok::r_brace
3148 SourceLocation EndLoc = ConsumeBrace();
3151 return Actions.ObjC().BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc),
3156Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
3157 assert(Tok.isObjCAtKeyword(tok::objc_encode) &&
"Not an @encode expression!");
3161 if (Tok.isNot(tok::l_paren))
3162 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@encode");
3174 return Actions.ObjC().ParseObjCEncodeExpression(
3175 AtLoc, EncLoc,
T.getOpenLocation(), Ty.
get(),
T.getCloseLocation());
3179Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
3182 if (Tok.isNot(tok::l_paren))
3183 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@protocol");
3188 if (expectIdentifier())
3191 IdentifierInfo *protocolId = Tok.getIdentifierInfo();
3196 return Actions.ObjC().ParseObjCProtocolExpression(
3197 protocolId, AtLoc, ProtoLoc,
T.getOpenLocation(), ProtoIdLoc,
3198 T.getCloseLocation());
3201ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
3204 if (Tok.isNot(tok::l_paren))
3205 return ExprError(
Diag(Tok, diag::err_expected_lparen_after) <<
"@selector");
3207 SmallVector<const IdentifierInfo *, 12> KeyIdents;
3208 SourceLocation sLoc;
3212 bool HasOptionalParen = Tok.is(tok::l_paren);
3213 if (HasOptionalParen)
3216 if (Tok.is(tok::code_completion)) {
3218 Actions.CodeCompletion().CodeCompleteObjCSelector(
getCurScope(), KeyIdents);
3222 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
3224 Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3225 return ExprError(
Diag(Tok, diag::err_expected) << tok::identifier);
3227 KeyIdents.push_back(SelIdent);
3229 unsigned nColons = 0;
3230 if (Tok.isNot(tok::r_paren)) {
3234 KeyIdents.push_back(
nullptr);
3235 }
else if (ExpectAndConsume(tok::colon))
3239 if (Tok.is(tok::r_paren))
3242 if (Tok.is(tok::code_completion)) {
3244 Actions.CodeCompletion().CodeCompleteObjCSelector(
getCurScope(),
3251 SelIdent = ParseObjCSelectorPiece(Loc);
3252 KeyIdents.push_back(SelIdent);
3253 if (!SelIdent && Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3257 if (HasOptionalParen && Tok.is(tok::r_paren))
3260 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
3261 return Actions.ObjC().ParseObjCSelectorExpression(
3262 Sel, AtLoc, SelectorLoc,
T.getOpenLocation(),
T.getCloseLocation(),
3266void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM,
bool parseMethod) {
3268 Decl *MCDecl = LM.D;
3270 MCDecl && ((parseMethod && !Actions.ObjC().isObjCMethodDecl(MCDecl)) ||
3271 (!parseMethod && Actions.ObjC().isObjCMethodDecl(MCDecl)));
3276 SourceLocation OrigLoc = Tok.getLocation();
3278 assert(!LM.Toks.empty() &&
"ParseLexedObjCMethodDef - Empty body!");
3286 LM.Toks.push_back(Eof);
3289 LM.Toks.push_back(Tok);
3290 PP.EnterTokenStream(LM.Toks,
true,
true);
3295 assert(Tok.isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3296 "Inline objective-c method not starting with '{' or 'try' or ':'");
3301 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
3306 Actions.ObjC().ActOnStartOfObjCMethodDef(
getCurScope(), MCDecl);
3308 Actions.ActOnStartOfFunctionDef(
getCurScope(), MCDecl);
3309 if (Tok.is(tok::kw_try))
3310 ParseFunctionTryBlock(MCDecl, BodyScope);
3312 if (Tok.is(tok::colon))
3313 ParseConstructorInitializer(MCDecl);
3315 Actions.ActOnDefaultCtorInitializers(MCDecl);
3316 ParseFunctionStatementBody(MCDecl, BodyScope);
3319 if (Tok.getLocation() != OrigLoc) {
3325 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
3327 while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
3332 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 bool isTopLevelObjCKeyword(tok::ObjCKeywordKind DirectiveKind)
static void takeDeclAttributes(ParsedAttributesView &attrs, ParsedAttributesView &from)
Take all the decl attributes out of the given list and add them to the given attribute set.
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.
AttributePool & getPool() const
void takeAllFrom(ParsedAttributes &Other)
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.
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.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
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.
The JSON file list parser is used to communicate input to InstallAPI.
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
@ Type
The name was classified as a type.
const FunctionProtoType * T
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.