clang: lib/Parse/ParseObjc.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/ADT/StringExtras.h"
28
29using namespace clang;
30
31
34 if (Tok.is(tok::kw___attribute)) {
35 if (Kind == tok::objc_interface || Kind == tok::objc_protocol)
36 Diag(Tok, diag::err_objc_postfix_attribute_hint)
37 << (Kind == tok::objc_protocol);
38 else
39 Diag(Tok, diag::err_objc_postfix_attribute);
40 ParseGNUAttributes(attrs);
41 }
42}
43
44
45
46
47
48
49
50
51
56
58
59 if (Tok.is(tok::code_completion)) {
60 cutOffParsing();
62 return nullptr;
63 }
64
66 case tok::objc_interface:
67 case tok::objc_protocol:
68 case tok::objc_implementation:
69 break;
70 default:
71 for (const auto &Attr : DeclAttrs) {
74 }
75 }
76
77 Decl *SingleDecl = nullptr;
79 case tok::objc_class:
80 return ParseObjCAtClassDeclaration(AtLoc);
81 case tok::objc_interface:
82 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DeclAttrs);
83 break;
84 case tok::objc_protocol:
85 return ParseObjCAtProtocolDeclaration(AtLoc, DeclAttrs);
86 case tok::objc_implementation:
87 return ParseObjCAtImplementationDeclaration(AtLoc, DeclAttrs);
88 case tok::objc_end:
89 return ParseObjCAtEndDeclaration(AtLoc);
90 case tok::objc_compatibility_alias:
91 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
92 break;
93 case tok::objc_synthesize:
94 SingleDecl = ParseObjCPropertySynthesize(AtLoc);
95 break;
96 case tok::objc_dynamic:
97 SingleDecl = ParseObjCPropertyDynamic(AtLoc);
98 break;
99 case tok::objc_import:
102 SingleDecl = ParseModuleImport(AtLoc, IS);
103 break;
104 }
105 Diag(AtLoc, diag::err_atimport);
108 default:
109 Diag(AtLoc, diag::err_unexpected_at);
111 SingleDecl = nullptr;
112 break;
113 }
115}
116
117
119 Sema &Actions;
122
123public:
125 : Actions(Actions), S(S), Params(nullptr) {}
126
129 }
130
132 assert(!Params);
133 Params = P;
134 }
135
137 if (Params)
139 Params = nullptr;
140 }
141};
142
143
144
145
146
147
148
149
151Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
156
157 while (true) {
158 MaybeSkipAttributes(tok::objc_class);
159 if (Tok.is(tok::code_completion)) {
160 cutOffParsing();
163 }
164 if (expectIdentifier()) {
167 }
171
172
174 if (Tok.is(tok::less))
175 TypeParams = parseObjCTypeParamList();
176 ClassTypeParams.push_back(TypeParams);
178 break;
179 }
180
181
182 if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class"))
184
186 atLoc, ClassNames.data(), ClassLocs.data(), ClassTypeParams,
187 ClassNames.size());
188}
189
190void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
191{
194 return;
195
197 if (CurParsedObjCImpl) {
198 CurParsedObjCImpl->finish(AtLoc);
199 } else {
201 }
202 Diag(AtLoc, diag::err_objc_missing_end)
206}
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
240 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
241 CheckNestedObjCContexts(AtLoc);
242 ConsumeToken();
243
244
245 if (Tok.is(tok::code_completion)) {
246 cutOffParsing();
248 return nullptr;
249 }
250
251 MaybeSkipAttributes(tok::objc_interface);
252
253 if (expectIdentifier())
254 return nullptr;
255
256
259
260
261
262
266 ObjCTypeParamListScope typeParamScope(Actions, getCurScope());
267 if (Tok.is(tok::less))
268 typeParameterList = parseObjCTypeParamListOrProtocolRefs(
269 typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
270
271 if (Tok.is(tok::l_paren) &&
272 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
273
275 T.consumeOpen();
276
279 if (Tok.is(tok::code_completion)) {
280 cutOffParsing();
283 return nullptr;
284 }
285
286
287 if (Tok.is(tok::identifier)) {
290 }
292 Diag(Tok, diag::err_expected)
293 << tok::identifier;
294 return nullptr;
295 }
296
297 T.consumeClose();
298 if (T.getCloseLocation().isInvalid())
299 return nullptr;
300
301
302 assert(LAngleLoc.isInvalid() && "Cannot have already parsed protocols");
305 if (Tok.is(tok::less) &&
306 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, true,
307 LAngleLoc, EndProtoLoc,
308 true))
309 return nullptr;
310
312 AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
313 ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
314 EndProtoLoc, attrs);
315
316 if (Tok.is(tok::l_brace))
317 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
318
319 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
320
321 return CategoryType;
322 }
323
331 if (Tok.is(tok::colon)) {
333
334
335 if (Tok.is(tok::code_completion)) {
336 cutOffParsing();
338 nameLoc);
339 return nullptr;
340 }
341
342 if (expectIdentifier())
343 return nullptr;
346
347
348 if (Tok.is(tok::less)) {
349 parseObjCTypeArgsOrProtocolQualifiers(
350 nullptr, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, LAngleLoc,
351 protocols, protocolLocs, EndProtoLoc,
352 true,
353 true);
354 if (Tok.is(tok::eof))
355 return nullptr;
356 }
357 }
358
359
360 if (LAngleLoc.isValid()) {
361 if (!ProtocolIdents.empty()) {
362
363
364 for (const auto &pair : ProtocolIdents) {
365 protocolLocs.push_back(pair.second);
366 }
368 true,
369 ProtocolIdents, protocols);
370 }
371 } else if (protocols.empty() && Tok.is(tok::less) &&
372 ParseObjCProtocolReferences(protocols, protocolLocs, true, true,
373 LAngleLoc, EndProtoLoc,
374 true)) {
375 return nullptr;
376 }
377
378 if (Tok.isNot(tok::less))
380 superClassId, superClassLoc);
381
384 getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
385 superClassLoc, typeArgs,
386 SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(),
387 protocols.size(), protocolLocs.data(), EndProtoLoc, attrs, &SkipBody);
388
389 if (Tok.is(tok::l_brace))
390 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
391
392 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
393
395 auto *PreviousDef = cast(SkipBody.Previous);
398 } else {
401 DiagsEmitter.diagnoseMismatch(PreviousDef, ClsType);
403 }
404 }
405
406 return ClsType;
407}
408
409
410
415 bool &addedToDeclSpec) {
416
418 return Pool.create(P.getNullabilityKeyword(nullability),
420 nullptr, 0, ParsedAttr::Form::ContextSensitiveKeyword());
421 };
422
423 if (D.getNumTypeObjects() > 0) {
424
425 D.getTypeObject(0).getAttrs().addAtEnd(
426 getNullabilityAttr(D.getAttributePool()));
427 } else if (!addedToDeclSpec) {
428
429
430 D.getMutableDeclSpec().getAttributes().addAtEnd(
431 getNullabilityAttr(D.getMutableDeclSpec().getAttributes().getPool()));
432 addedToDeclSpec = true;
433 }
434}
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
464 assert(Tok.is(tok::less) && "Not at the beginning of a type parameter list");
465
466
468
469
470
472 auto makeProtocolIdentsIntoTypeParameters = [&]() {
473 unsigned index = 0;
474 for (const auto &pair : protocolIdents) {
477 index++, pair.first, pair.second, SourceLocation(), nullptr);
479 typeParams.push_back(typeParam.get());
480 }
481
482 protocolIdents.clear();
483 mayBeProtocolList = false;
484 };
485
486 bool invalid = false;
488
489 do {
490
493 if (Tok.is(tok::kw___covariant) || Tok.is(tok::kw___contravariant)) {
494 variance = Tok.is(tok::kw___covariant)
498
499
500
501 if (mayBeProtocolList) {
502
503
504 makeProtocolIdentsIntoTypeParameters();
505 }
506 }
507
508
509 if (!Tok.is(tok::identifier)) {
510
511 if (Tok.is(tok::code_completion)) {
512
513
514 cutOffParsing();
516 protocolIdents);
517
518
519 return nullptr;
520 }
521
522 Diag(Tok, diag::err_objc_expected_type_parameter);
523 invalid = true;
524 break;
525 }
526
529
530
534
535
536 if (mayBeProtocolList) {
537
538
539 makeProtocolIdentsIntoTypeParameters();
540 }
541
542
545 invalid = true;
546 } else if (mayBeProtocolList) {
547
548
549 protocolIdents.push_back(std::make_pair(paramName, paramLoc));
550 continue;
551 }
552
553
555 getCurScope(), variance, varianceLoc, typeParams.size(), paramName,
556 paramLoc, colonLoc, boundType.isUsable() ? boundType.get() : nullptr);
558 typeParams.push_back(typeParam.get());
560
561
562 if (invalid) {
564 if (Tok.is(tok::greater))
566 } else if (ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc,
567 true,
568 true)) {
569 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
570 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
571 tok::comma, tok::semi },
573 if (Tok.is(tok::greater))
575 }
576
577 if (mayBeProtocolList) {
578
579
580
581
582 if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_paren)) {
583
584
585
586 return nullptr;
587 }
588
589
590
591 makeProtocolIdentsIntoTypeParameters();
592 }
593
594
596 getCurScope(), lAngleLoc, typeParams, rAngleLoc);
597 Scope.enter(list);
598
599
600
603 return invalid ? nullptr : list;
604}
605
606
611
613 return parseObjCTypeParamListOrProtocolRefs(Scope, lAngleLoc, protocolIdents,
614 rAngleLoc,
615 false);
616}
617
619 switch (DirectiveKind) {
620 case tok::objc_class:
621 case tok::objc_compatibility_alias:
622 case tok::objc_interface:
623 case tok::objc_implementation:
624 case tok::objc_protocol:
625 return true;
626 default:
627 return false;
628 }
629}
630
631
632
633
634
635
636
637
638
639
640
641
642
644 Decl *CDecl) {
648
650
651 while (true) {
652
653 if (Tok.isOneOf(tok::minus, tok::plus)) {
654 if (Decl *methodPrototype =
655 ParseObjCMethodPrototype(MethodImplKind, false))
656 allMethods.push_back(methodPrototype);
657
658
659 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
660
662 if (Tok.is(tok::semi))
664 }
665 continue;
666 }
667 if (Tok.is(tok::l_paren)) {
668 Diag(Tok, diag::err_expected_minus_or_plus);
670 tok::minus,
671 MethodImplKind, false);
672 continue;
673 }
674
675 if (Tok.is(tok::semi)) {
676
677
679 continue;
680 }
681
682
683 if (isEofOrEom())
684 break;
685
686
687 if (Tok.is(tok::code_completion)) {
688 cutOffParsing();
693 return;
694 }
695
696
697 if (Tok.isNot(tok::at)) {
698
699
700
701 if (Tok.is(tok::r_brace))
702 break;
703
706
707
708
709
710 if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
714 DeclEnd, EmptyDeclAttrs,
715 EmptyDeclSpecAttrs));
716 continue;
717 }
718
719 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(
720 EmptyDeclAttrs, EmptyDeclSpecAttrs));
721 continue;
722 }
723
724
726 const auto &NextTok = NextToken();
727 if (NextTok.is(tok::code_completion)) {
728 cutOffParsing();
730 return;
731 }
732
734 if (DirectiveKind == tok::objc_end) {
738 break;
739 } else if (DirectiveKind == tok::objc_not_keyword) {
740 Diag(NextTok, diag::err_objc_unknown_at);
742 continue;
743 }
744
745
746
748 break;
749
750
753
754 switch (DirectiveKind) {
755 default:
756
757
758
759
760 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
761
763 break;
764
765 case tok::objc_required:
766 case tok::objc_optional:
767
768 if (contextKey != tok::objc_protocol)
769 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
770 else
772 break;
773
774 case tok::objc_property:
777
778 if (Tok.is(tok::l_paren)) {
780 ParseObjCPropertyAttribute(OCDS);
781 }
782
783 bool addedToDeclSpec = false;
785 if (FD.D.getIdentifier() == nullptr) {
786 Diag(AtLoc, diag::err_objc_property_requires_field_name)
787 << FD.D.getSourceRange();
788 return nullptr;
789 }
790 if (FD.BitfieldSize) {
791 Diag(AtLoc, diag::err_objc_property_bitfield)
792 << FD.D.getSourceRange();
793 return nullptr;
794 }
795
796
797
802 addedToDeclSpec);
803
804
807
811 if (SetterName)
813 else
816 FD.D.getIdentifier());
818 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
819 MethodImplKind);
820
823 };
824
825
827 ParseStructDeclaration(DS, ObjCPropertyCallback);
828
829 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
830 break;
831 }
832 }
833
834
835
836
839 } else {
840 Diag(Tok, diag::err_objc_missing_end)
842 Diag(CDecl->getBeginLoc(), diag::note_objc_container_start)
846 }
847
848
849
851}
852
853
859 P.Diag(nullabilityLoc, diag::warn_nullability_duplicate)
862 return;
863 }
864
865 P.Diag(nullabilityLoc, diag::err_nullability_conflicting)
869}
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
898 assert(Tok.getKind() == tok::l_paren);
900 T.consumeOpen();
901
902 while (true) {
903 if (Tok.is(tok::code_completion)) {
904 cutOffParsing();
906 return;
907 }
909
910
911 if (!II) {
912 T.consumeClose();
913 return;
914 }
915
917
918 if (II->isStr("readonly"))
920 else if (II->isStr("assign"))
922 else if (II->isStr("unsafe_unretained"))
924 else if (II->isStr("readwrite"))
926 else if (II->isStr("retain"))
928 else if (II->isStr("strong"))
930 else if (II->isStr("copy"))
932 else if (II->isStr("nonatomic"))
934 else if (II->isStr("atomic"))
936 else if (II->isStr("weak"))
938 else if (II->isStr("getter") || II->isStr("setter")) {
939 bool IsSetter = II->getNameStart()[0] == 's';
940
941
942 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
943 diag::err_objc_expected_equal_for_getter;
944
945 if (ExpectAndConsume(tok::equal, DiagID)) {
947 return;
948 }
949
950 if (Tok.is(tok::code_completion)) {
951 cutOffParsing();
952 if (IsSetter)
955 else
958 return;
959 }
960
962 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc);
963
964 if (!SelIdent) {
965 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
966 << IsSetter;
968 return;
969 }
970
971 if (IsSetter) {
974
975 if (ExpectAndConsume(tok::colon,
976 diag::err_expected_colon_after_setter_name)) {
978 return;
979 }
980 } else {
983 }
984 } else if (II->isStr("nonnull")) {
991 } else if (II->isStr("nullable")) {
998 } else if (II->isStr("null_unspecified")) {
1005 } else if (II->isStr("null_resettable")) {
1012
1013
1015 } else if (II->isStr("class")) {
1017 } else if (II->isStr("direct")) {
1019 } else {
1020 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
1022 return;
1023 }
1024
1025 if (Tok.isNot(tok::comma))
1026 break;
1027
1029 }
1030
1031 T.consumeClose();
1032}
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1045 bool MethodDefinition) {
1046 assert(Tok.isOneOf(tok::minus, tok::plus) && "expected +/-");
1047
1050 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
1051 MethodDefinition);
1052
1053
1054 return MDecl;
1055}
1056
1057
1058
1059
1060
1061
1062
1063
1064
1066
1067 switch (Tok.getKind()) {
1068 default:
1069 return nullptr;
1070 case tok::colon:
1071
1073 return nullptr;
1074 case tok::ampamp:
1075 case tok::ampequal:
1076 case tok::amp:
1077 case tok::pipe:
1078 case tok::tilde:
1079 case tok::exclaim:
1080 case tok::exclaimequal:
1081 case tok::pipepipe:
1082 case tok::pipeequal:
1083 case tok::caret:
1084 case tok::caretequal: {
1085 std::string ThisTok(PP.getSpelling(Tok));
1088 Tok.setKind(tok::identifier);
1090 return II;
1091 }
1092 return nullptr;
1093 }
1094
1095 case tok::identifier:
1096 case tok::kw_asm:
1097 case tok::kw_auto:
1098 case tok::kw_bool:
1099 case tok::kw_break:
1100 case tok::kw_case:
1101 case tok::kw_catch:
1102 case tok::kw_char:
1103 case tok::kw_class:
1104 case tok::kw_const:
1105 case tok::kw_const_cast:
1106 case tok::kw_continue:
1107 case tok::kw_default:
1108 case tok::kw_delete:
1109 case tok::kw_do:
1110 case tok::kw_double:
1111 case tok::kw_dynamic_cast:
1112 case tok::kw_else:
1113 case tok::kw_enum:
1114 case tok::kw_explicit:
1115 case tok::kw_export:
1116 case tok::kw_extern:
1117 case tok::kw_false:
1118 case tok::kw_float:
1119 case tok::kw_for:
1120 case tok::kw_friend:
1121 case tok::kw_goto:
1122 case tok::kw_if:
1123 case tok::kw_inline:
1124 case tok::kw_int:
1125 case tok::kw_long:
1126 case tok::kw_mutable:
1127 case tok::kw_namespace:
1128 case tok::kw_new:
1129 case tok::kw_operator:
1130 case tok::kw_private:
1131 case tok::kw_protected:
1132 case tok::kw_public:
1133 case tok::kw_register:
1134 case tok::kw_reinterpret_cast:
1135 case tok::kw_restrict:
1136 case tok::kw_return:
1137 case tok::kw_short:
1138 case tok::kw_signed:
1139 case tok::kw_sizeof:
1140 case tok::kw_static:
1141 case tok::kw_static_cast:
1142 case tok::kw_struct:
1143 case tok::kw_switch:
1144 case tok::kw_template:
1145 case tok::kw_this:
1146 case tok::kw_throw:
1147 case tok::kw_true:
1148 case tok::kw_try:
1149 case tok::kw_typedef:
1150 case tok::kw_typeid:
1151 case tok::kw_typename:
1152 case tok::kw_typeof:
1153 case tok::kw_union:
1154 case tok::kw_unsigned:
1155 case tok::kw_using:
1156 case tok::kw_virtual:
1157 case tok::kw_void:
1158 case tok::kw_volatile:
1159 case tok::kw_wchar_t:
1160 case tok::kw_while:
1161 case tok::kw__Bool:
1162 case tok::kw__Complex:
1163 case tok::kw___alignof:
1164 case tok::kw___auto_type:
1167 return II;
1168 }
1169}
1170
1171
1172
1173bool Parser::isTokIdentifier_in() const {
1174
1175
1176
1179}
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
1204
1205 while (true) {
1206 if (Tok.is(tok::code_completion)) {
1207 cutOffParsing();
1210 return;
1211 }
1212
1213 if (Tok.isNot(tok::identifier))
1214 return;
1215
1217 for (unsigned i = 0; i != objc_NumQuals; ++i) {
1218 if (II != ObjCTypeQuals[i] ||
1220 NextToken().is(tok::coloncolon))
1221 continue;
1222
1225 switch (i) {
1226 default: llvm_unreachable("Unknown decl qualifier");
1233
1234 case objc_nonnull:
1237 break;
1238
1239 case objc_nullable:
1242 break;
1243
1244 case objc_null_unspecified:
1247 break;
1248 }
1249
1250
1254
1256 II = nullptr;
1257 break;
1258 }
1259
1260
1261 if (II) return;
1262 }
1263}
1264
1265
1266
1269 for (auto &AL : llvm::reverse(from)) {
1270 if (!AL.isUsedAsTypeAttr()) {
1273 }
1274 }
1275}
1276
1277
1278
1281
1282
1283 assert(D.getDeclarationAttributes().empty());
1284
1285
1288
1289
1292 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
1294}
1295
1296
1297
1298
1299
1305 assert((paramAttrs != nullptr) ==
1307
1308 assert(Tok.is(tok::l_paren) && "expected (");
1309
1311 T.consumeOpen();
1312
1314
1315
1316 ParseObjCTypeQualifierList(DS, context);
1318
1320 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1321
1322 DeclSpec declSpec(AttrFactory);
1323 declSpec.setObjCQualifiers(&DS);
1324 DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
1326 dsContext = DeclSpecContext::DSC_objc_method_result;
1327 ParseSpecifierQualifierList(declSpec, AS_none, dsContext);
1329 ParseDeclarator(declarator);
1330
1331
1332 if (!declarator.isInvalidType()) {
1333
1334 bool addedToDeclSpec = false;
1339 addedToDeclSpec);
1340
1342 if (.isInvalid())
1343 Ty = type.get();
1344
1345
1346
1349 }
1350 }
1351
1352 if (Tok.is(tok::r_paren))
1353 T.consumeClose();
1354 else if (Tok.getLocation() == TypeStartLoc) {
1355
1356 Diag(Tok, diag::err_expected_type);
1358 } else {
1359
1360
1361 T.consumeClose();
1362 }
1363 return Ty;
1364}
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1397 bool MethodDefinition) {
1399
1400 if (Tok.is(tok::code_completion)) {
1401 cutOffParsing();
1403 mType == tok::minus,
1404 nullptr);
1405 return nullptr;
1406 }
1407
1408
1411 if (Tok.is(tok::l_paren))
1412 ReturnType =
1414
1415
1417 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0),
1418 methodAttrs);
1419
1420 if (Tok.is(tok::code_completion)) {
1421 cutOffParsing();
1423 getCurScope(), mType == tok::minus, ReturnType);
1424 return nullptr;
1425 }
1426
1427
1429 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
1430
1431
1432 if (!SelIdent && Tok.isNot(tok::colon)) {
1433 Diag(Tok, diag::err_expected_selector_for_method)
1435
1437 return nullptr;
1438 }
1439
1441 if (Tok.isNot(tok::colon)) {
1442
1443 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0),
1444 methodAttrs);
1445
1449 selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
1450 MethodImplKind, false, MethodDefinition);
1451 PD.complete(Result);
1453 }
1454
1460
1462 while (true) {
1465
1466
1467 if (ExpectAndConsume(tok::colon))
1468 break;
1469
1470 ArgInfo.Type = nullptr;
1471 if (Tok.is(tok::l_paren))
1472 ArgInfo.Type = ParseObjCTypeName(
1474
1475
1476
1477 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0),
1478 paramAttrs);
1479 ArgInfo.ArgAttrs = paramAttrs;
1480
1481
1482 if (Tok.is(tok::code_completion)) {
1483 cutOffParsing();
1484 KeyIdents.push_back(SelIdent);
1487 true, ReturnType, KeyIdents);
1488 return nullptr;
1489 }
1490
1491 if (expectIdentifier())
1492 break;
1493
1497
1498 ArgInfos.push_back(ArgInfo);
1499 KeyIdents.push_back(SelIdent);
1500 KeyLocs.push_back(selLoc);
1501
1502
1503 allParamAttrs.takeAllFrom(paramAttrs.getPool());
1504
1505
1506 if (Tok.is(tok::code_completion)) {
1507 cutOffParsing();
1510 false, ReturnType, KeyIdents);
1511 return nullptr;
1512 }
1513
1514
1515 SelIdent = ParseObjCSelectorPiece(selLoc);
1516 if (!SelIdent && Tok.isNot(tok::colon))
1517 break;
1518 if (!SelIdent) {
1521 Diag(ArgInfo.NameLoc, diag::warn_missing_selector_name) << ArgInfo.Name;
1522 Diag(ArgInfo.NameLoc, diag::note_missing_selector_name) << ArgInfo.Name;
1523 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.Name;
1524 }
1525 }
1526
1527 }
1528
1529 bool isVariadic = false;
1530 bool cStyleParamWarned = false;
1531
1532 while (Tok.is(tok::comma)) {
1534 if (Tok.is(tok::ellipsis)) {
1535 isVariadic = true;
1537 break;
1538 }
1539 if (!cStyleParamWarned) {
1540 Diag(Tok, diag::warn_cstyle_param);
1541 cStyleParamWarned = true;
1542 }
1544 ParsedTemplateInfo TemplateInfo;
1545 ParseDeclarationSpecifiers(DS, TemplateInfo);
1546
1549 ParseDeclarator(ParmDecl);
1550 const IdentifierInfo *ParmII = ParmDecl.getIdentifier();
1553 ParmDecl.getIdentifierLoc(),
1554 Param,
1555 nullptr));
1556 }
1557
1558
1559
1560
1561
1563 for (auto &ArgInfo : ArgInfos) {
1565 getCurScope(), ArgInfo, ObjCParamInfo.size(), MethodDefinition);
1566 ObjCParamInfo.push_back(Param);
1567 }
1568
1569
1570
1571 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0),
1572 methodAttrs);
1573
1574 if (KeyIdents.size() == 0)
1575 return nullptr;
1576
1578 &KeyIdents[0]);
1581 Sel, ObjCParamInfo.data(), CParamInfo.data(), CParamInfo.size(),
1582 methodAttrs, MethodImplKind, isVariadic, MethodDefinition);
1583
1584 PD.complete(Result);
1586}
1587
1588
1589
1590
1591bool Parser::
1594 bool WarnOnDeclarations, bool ForObjCContainer,
1596 bool consumeLastToken) {
1597 assert(Tok.is(tok::less) && "expected <");
1598
1600
1602
1603 while (true) {
1604 if (Tok.is(tok::code_completion)) {
1605 cutOffParsing();
1607 ProtocolIdents);
1608 return true;
1609 }
1610
1611 if (expectIdentifier()) {
1613 return true;
1614 }
1615 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
1617 ProtocolLocs.push_back(Tok.getLocation());
1619
1621 break;
1622 }
1623
1624
1625 if (ParseGreaterThanInTemplateList(LAngleLoc, EndLoc, consumeLastToken,
1626 false))
1627 return true;
1628
1629
1631 ProtocolIdents, Protocols);
1632 return false;
1633}
1634
1636 assert(Tok.is(tok::less) && "Protocol qualifiers start with '<'");
1637 assert(getLangOpts().ObjC && "Protocol qualifiers only exist in Objective-C");
1638
1642 (void)ParseObjCProtocolReferences(protocols, protocolLocs, false, false,
1643 lAngleLoc, rAngleLoc,
1644 true);
1646 lAngleLoc, protocols, protocolLocs, rAngleLoc);
1648 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1651 }
1652
1653 return result;
1654}
1655
1656
1657
1658
1659
1660
1661void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1670 bool consumeLastToken,
1671 bool warnOnIncompleteProtocols) {
1672 assert(Tok.is(tok::less) && "Not at the start of type args or protocols");
1674
1675
1676
1677 bool allSingleIdentifiers = true;
1680
1681
1682
1683 do {
1684
1685 if (Tok.is(tok::identifier) &&
1688 NextToken().is(tok::greatergreater))) {
1691 continue;
1692 }
1693
1694 if (Tok.is(tok::code_completion)) {
1695
1697 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1699 identifierLocs[i]));
1700 }
1701
1703 cutOffParsing();
1707 } else {
1709 identifierLocPairs);
1710 }
1711 return;
1712 }
1713
1714 allSingleIdentifiers = false;
1715 break;
1717
1718
1719
1720 if (allSingleIdentifiers) {
1721
1723 (void)ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc, consumeLastToken,
1724 true);
1725
1726
1728 getCurScope(), baseType, lAngleLoc, identifiers, identifierLocs,
1729 rAngleLoc, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc,
1730 protocolLAngleLoc, protocols, protocolRAngleLoc,
1731 warnOnIncompleteProtocols);
1732 return;
1733 }
1734
1735
1736
1737
1738
1739
1740
1741 bool invalid = false;
1742 IdentifierInfo *foundProtocolId = nullptr, *foundValidTypeId = nullptr;
1743 SourceLocation foundProtocolSrcLoc, foundValidTypeSrcLoc;
1746
1747 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1750 if (typeArg) {
1752 const char *prevSpec = nullptr;
1753 unsigned diagID;
1754 DS.SetTypeSpecType(TST_typename, identifierLocs[i], prevSpec, diagID,
1756
1757
1761 if (fullTypeArg.isUsable()) {
1762 typeArgs.push_back(fullTypeArg.get());
1763 if (!foundValidTypeId) {
1764 foundValidTypeId = identifiers[i];
1765 foundValidTypeSrcLoc = identifierLocs[i];
1766 }
1767 } else {
1768 invalid = true;
1769 unknownTypeArgs.push_back(identifiers[i]);
1770 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1771 }
1772 } else {
1773 invalid = true;
1774 if (!Actions.ObjC().LookupProtocol(identifiers[i], identifierLocs[i])) {
1775 unknownTypeArgs.push_back(identifiers[i]);
1776 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1777 } else if (!foundProtocolId) {
1778 foundProtocolId = identifiers[i];
1779 foundProtocolSrcLoc = identifierLocs[i];
1780 }
1781 }
1782 }
1783
1784
1785 do {
1786 Token CurTypeTok = Tok;
1788
1789
1794 }
1795
1797 typeArgs.push_back(typeArg.get());
1798 if (!foundValidTypeId) {
1800 foundValidTypeSrcLoc = CurTypeTok.getLocation();
1801 }
1802 } else {
1803 invalid = true;
1804 }
1806
1807
1808 if (foundProtocolId && foundValidTypeId)
1810 foundProtocolId, foundProtocolSrcLoc, foundValidTypeId,
1811 foundValidTypeSrcLoc);
1812
1813
1815 if (unknownTypeArgs.size())
1816 for (unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1819
1820
1822 (void)ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc, consumeLastToken,
1823 true);
1824
1825 if (invalid) {
1826 typeArgs.clear();
1827 return;
1828 }
1829
1830
1831 typeArgsLAngleLoc = lAngleLoc;
1832 typeArgsRAngleLoc = rAngleLoc;
1833}
1834
1835void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1844 bool consumeLastToken) {
1845 assert(Tok.is(tok::less));
1846
1847
1848 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1849 typeArgsLAngleLoc,
1850 typeArgs,
1851 typeArgsRAngleLoc,
1852 protocolLAngleLoc,
1853 protocols,
1854 protocolLocs,
1855 protocolRAngleLoc,
1856 consumeLastToken,
1857 false);
1858 if (Tok.is(tok::eof))
1859 return;
1860
1861
1862
1863
1864 if ((consumeLastToken && Tok.is(tok::less)) ||
1865 (!consumeLastToken && NextToken().is(tok::less))) {
1866
1867
1868 if (!consumeLastToken)
1870
1871 if (!protocols.empty()) {
1873 if (!consumeLastToken)
1875 Diag(Tok, diag::err_objc_type_args_after_protocols)
1876 << SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1877 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1878 } else {
1879 ParseObjCProtocolReferences(protocols, protocolLocs,
1880 false,
1881 false,
1882 protocolLAngleLoc, protocolRAngleLoc,
1883 consumeLastToken);
1884 }
1885 }
1886}
1887
1888TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1891 bool consumeLastToken,
1893 assert(Tok.is(tok::less));
1901
1902
1903 parseObjCTypeArgsAndProtocolQualifiers(type, typeArgsLAngleLoc, typeArgs,
1904 typeArgsRAngleLoc, protocolLAngleLoc,
1905 protocols, protocolLocs,
1906 protocolRAngleLoc, consumeLastToken);
1907
1908 if (Tok.is(tok::eof))
1909 return true;
1910
1911
1912 if (consumeLastToken)
1913 endLoc = PrevTokLocation;
1914 else
1916
1918 getCurScope(), loc, type, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc,
1919 protocolLAngleLoc, protocols, protocolLocs, protocolRAngleLoc);
1920}
1921
1922void Parser::HelperActionsForIvarDeclarations(
1925 bool RBraceMissing) {
1926 if (!RBraceMissing)
1927 T.consumeClose();
1928
1930 "Ivars should have interfaceDecl as their decl context");
1932
1933
1935 T.getOpenLocation(), T.getCloseLocation(),
1937}
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1956
1957
1958
1959
1960void Parser::ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
1963 assert(Tok.is(tok::l_brace) && "expected {");
1965
1967
1969 T.consumeOpen();
1970
1971 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1972
1973
1974
1975 if (Tok.is(tok::semi)) {
1976 ConsumeExtraSemi(InstanceVariableList);
1977 continue;
1978 }
1979
1980
1981 if (TryConsumeToken(tok::at)) {
1982 if (Tok.is(tok::code_completion)) {
1983 cutOffParsing();
1985 return;
1986 }
1987
1989 case tok::objc_private:
1990 case tok::objc_public:
1991 case tok::objc_protected:
1992 case tok::objc_package:
1995 continue;
1996
1997 case tok::objc_end:
1998 Diag(Tok, diag::err_objc_unexpected_atend);
2002 PP.EnterToken(Tok, true);
2003 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
2004 T, AllIvarDecls, true);
2005 return;
2006
2007 default:
2008 Diag(Tok, diag::err_objc_illegal_visibility_spec);
2009 continue;
2010 }
2011 }
2012
2013 if (Tok.is(tok::code_completion)) {
2014 cutOffParsing();
2017 return;
2018 }
2019
2020
2021
2022
2023 if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2025 ParseStaticAssertDeclaration(DeclEnd);
2026 continue;
2027 }
2028
2031 "Ivar should have interfaceDecl as its decl context");
2032
2033 FD.D.setObjCIvar(true);
2035 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
2036 FD.BitfieldSize, visibility);
2037 if (Field)
2038 AllIvarDecls.push_back(Field);
2039 FD.complete(Field);
2040 return Field;
2041 };
2042
2043
2045 ParseStructDeclaration(DS, ObjCIvarCallback);
2046
2047 if (Tok.is(tok::semi)) {
2049 } else {
2050 Diag(Tok, diag::err_expected_semi_decl_list);
2051
2053 }
2054 }
2055 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
2056 T, AllIvarDecls, false);
2057}
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2076Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
2079 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2080 ConsumeToken();
2081
2082 if (Tok.is(tok::code_completion)) {
2083 cutOffParsing();
2085 return nullptr;
2086 }
2087
2088 MaybeSkipAttributes(tok::objc_protocol);
2089
2090 if (expectIdentifier())
2091 return nullptr;
2092
2095
2096 if (TryConsumeToken(tok::semi)) {
2099 attrs);
2100 }
2101
2102 CheckNestedObjCContexts(AtLoc);
2103
2104 if (Tok.is(tok::comma)) {
2106 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2107
2108
2109 while (true) {
2111 if (expectIdentifier()) {
2113 return nullptr;
2114 }
2118
2119 if (Tok.isNot(tok::comma))
2120 break;
2121 }
2122
2123 if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol"))
2124 return nullptr;
2125
2127 attrs);
2128 }
2129
2130
2132
2135 if (Tok.is(tok::less) &&
2136 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, true,
2137 LAngleLoc, EndProtoLoc,
2138 true))
2139 return nullptr;
2140
2143 AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
2144 ProtocolLocs.data(), EndProtoLoc, attrs, &SkipBody);
2145
2146 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2148 auto *PreviousDef = cast(SkipBody.Previous);
2151 PreviousDef->getDefinition());
2152 } else {
2155 DiagsEmitter.diagnoseMismatch(PreviousDef, ProtoType);
2156 }
2157 }
2159}
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2172Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
2175 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2176 CheckNestedObjCContexts(AtLoc);
2177 ConsumeToken();
2178
2179
2180 if (Tok.is(tok::code_completion)) {
2181 cutOffParsing();
2183 return nullptr;
2184 }
2185
2186 MaybeSkipAttributes(tok::objc_implementation);
2187
2188 if (expectIdentifier())
2189 return nullptr;
2190
2194
2195
2196
2197 if (Tok.is(tok::less)) {
2201 ObjCTypeParamListScope typeParamScope(Actions, getCurScope());
2202 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
2203 protocolIdents, rAngleLoc)) {
2204 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2205 << SourceRange(diagLoc, PrevTokLocation);
2206 } else if (lAngleLoc.isValid()) {
2207 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2209 }
2210 }
2211
2212 if (Tok.is(tok::l_paren)) {
2213
2214 ConsumeParen();
2217
2218 if (Tok.is(tok::code_completion)) {
2219 cutOffParsing();
2222 return nullptr;
2223 }
2224
2225 if (Tok.is(tok::identifier)) {
2228 } else {
2229 Diag(Tok, diag::err_expected)
2230 << tok::identifier;
2231 return nullptr;
2232 }
2233 if (Tok.isNot(tok::r_paren)) {
2234 Diag(Tok, diag::err_expected) << tok::r_paren;
2235 SkipUntil(tok::r_paren);
2236 return nullptr;
2237 }
2238 rparenLoc = ConsumeParen();
2239 if (Tok.is(tok::less)) {
2240 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2241 SourceLocation protocolLAngleLoc, protocolRAngleLoc;
2244 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2245 false,
2246 false,
2247 protocolLAngleLoc, protocolRAngleLoc,
2248 true);
2249 }
2251 AtLoc, nameId, nameLoc, categoryId, categoryLoc, Attrs);
2252
2253 } else {
2254
2258
2259 if (expectIdentifier())
2260 return nullptr;
2262 superClassLoc = ConsumeToken();
2263 }
2265 AtLoc, nameId, nameLoc, superClassId, superClassLoc, Attrs);
2266
2267 if (Tok.is(tok::l_brace))
2268 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2269 else if (Tok.is(tok::less)) {
2270 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2271
2272 SourceLocation protocolLAngleLoc, protocolRAngleLoc;
2275 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2276 false,
2277 false,
2278 protocolLAngleLoc, protocolRAngleLoc,
2279 true);
2280 }
2281 }
2282 assert(ObjCImpDecl);
2283
2285
2286 {
2287 ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
2288 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2290 MaybeParseCXX11Attributes(DeclAttrs);
2293 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs)) {
2295 DeclsInGroup.append(DG.begin(), DG.end());
2296 }
2297 }
2298 }
2299
2301 DeclsInGroup);
2302}
2303
2305Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
2307 "ParseObjCAtEndDeclaration(): Expected @end");
2309 if (CurParsedObjCImpl)
2310 CurParsedObjCImpl->finish(atEnd);
2311 else
2312
2313 Diag(atEnd.getBegin(), diag::err_expected_objc_container);
2314 return nullptr;
2315}
2316
2317Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2318 if (!Finished) {
2319 finish(P.Tok.getLocation());
2320 if (P.isEofOrEom()) {
2321 P.Diag(P.Tok, diag::err_objc_missing_end)
2323 P.Diag(Dcl->getBeginLoc(), diag::note_objc_container_start)
2325 }
2326 }
2327 P.CurParsedObjCImpl = nullptr;
2328 assert(LateParsedObjCMethods.empty());
2329}
2330
2331void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
2332 assert(!Finished);
2333 P.Actions.ObjC().DefaultSynthesizeProperties(P.getCurScope(), Dcl,
2335 for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2336 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2337 true);
2338
2339 P.Actions.ObjC().ActOnAtEnd(P.getCurScope(), AtEnd);
2340
2341 if (HasCFunction)
2342 for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2343 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2344 false);
2345
2346
2347 for (LateParsedObjCMethodContainer::iterator
2348 I = LateParsedObjCMethods.begin(),
2349 E = LateParsedObjCMethods.end(); I != E; ++I)
2350 delete *I;
2351 LateParsedObjCMethods.clear();
2352
2353 Finished = true;
2354}
2355
2356
2357
2358
2360 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
2361 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2362 ConsumeToken();
2363 if (expectIdentifier())
2364 return nullptr;
2367 if (expectIdentifier())
2368 return nullptr;
2371 ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias");
2373 classId, classLoc);
2374}
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2389 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2391
2392 while (true) {
2393 if (Tok.is(tok::code_completion)) {
2394 cutOffParsing();
2397 return nullptr;
2398 }
2399
2400 if (Tok.isNot(tok::identifier)) {
2401 Diag(Tok, diag::err_synthesized_property_name);
2403 return nullptr;
2404 }
2405
2411
2412 if (Tok.is(tok::code_completion)) {
2413 cutOffParsing();
2416 return nullptr;
2417 }
2418
2419 if (expectIdentifier())
2420 break;
2422 propertyIvarLoc = ConsumeToken();
2423 }
2425 getCurScope(), atLoc, propertyLoc, true, propertyId, propertyIvar,
2427 if (Tok.isNot(tok::comma))
2428 break;
2430 }
2431 ExpectAndConsume(tok::semi, diag::err_expected_after, "@synthesize");
2432 return nullptr;
2433}
2434
2435
2436
2437
2438
2439
2440
2441
2444 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2446
2447 bool isClassProperty = false;
2448 if (Tok.is(tok::l_paren)) {
2449 ConsumeParen();
2451
2452 if (!II) {
2453 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2455 } else {
2457 if (II->isStr("class")) {
2458 isClassProperty = true;
2459 if (Tok.isNot(tok::r_paren)) {
2460 Diag(Tok, diag::err_expected) << tok::r_paren;
2462 } else
2463 ConsumeParen();
2464 } else {
2465 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2467 }
2468 }
2469 }
2470
2471 while (true) {
2472 if (Tok.is(tok::code_completion)) {
2473 cutOffParsing();
2476 return nullptr;
2477 }
2478
2479 if (expectIdentifier()) {
2481 return nullptr;
2482 }
2483
2487 getCurScope(), atLoc, propertyLoc, false, propertyId, nullptr,
2491
2492 if (Tok.isNot(tok::comma))
2493 break;
2495 }
2496 ExpectAndConsume(tok::semi, diag::err_expected_after, "@dynamic");
2497 return nullptr;
2498}
2499
2500
2501
2502
2506 if (Tok.isNot(tok::semi)) {
2511 }
2512 }
2513
2514 ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw");
2516}
2517
2518
2519
2520
2522Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
2524 if (Tok.isNot(tok::l_paren)) {
2525 Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
2527 }
2528
2529
2530 ConsumeParen();
2532
2533 if (Tok.is(tok::r_paren)) {
2534 ConsumeParen();
2535 } else {
2536 if (!operand.isInvalid())
2537 Diag(Tok, diag::err_expected) << tok::r_paren;
2538
2539
2541 }
2542
2543
2544 if (Tok.isNot(tok::l_brace)) {
2545 if (!operand.isInvalid())
2546 Diag(Tok, diag::err_expected) << tok::l_brace;
2548 }
2549
2550
2551 if (!operand.isInvalid())
2552 operand =
2554
2555
2557 StmtResult body(ParseCompoundStatementBody());
2558 bodyScope.Exit();
2559
2560
2561
2562 if (operand.isInvalid())
2564
2565 if (body.isInvalid())
2567
2569 body.get());
2570}
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2584 bool catch_or_finally_seen = false;
2585
2587 if (Tok.isNot(tok::l_brace)) {
2588 Diag(Tok, diag::err_expected) << tok::l_brace;
2590 }
2594 StmtResult TryBody(ParseCompoundStatementBody());
2595 TryScope.Exit();
2596 if (TryBody.isInvalid())
2598
2599 while (Tok.is(tok::at)) {
2600
2601
2602
2603 Token AfterAt = GetLookAheadToken(1);
2606 break;
2607
2610 Decl *FirstPart = nullptr;
2612 if (Tok.is(tok::l_paren)) {
2613 ConsumeParen();
2617 if (Tok.isNot(tok::ellipsis)) {
2619 ParsedTemplateInfo TemplateInfo;
2620 ParseDeclarationSpecifiers(DS, TemplateInfo);
2623 ParseDeclarator(ParmDecl);
2624
2625
2626
2627 FirstPart =
2629 } else
2631
2633
2634 if (Tok.is(tok::r_paren))
2635 RParenLoc = ConsumeParen();
2636 else
2638
2640 if (Tok.is(tok::l_brace))
2641 CatchBody = ParseCompoundStatementBody();
2642 else
2643 Diag(Tok, diag::err_expected) << tok::l_brace;
2644 if (CatchBody.isInvalid())
2646
2648 AtCatchFinallyLoc, RParenLoc, FirstPart, CatchBody.get());
2650 CatchStmts.push_back(Catch.get());
2651
2652 } else {
2653 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2654 << "@catch clause";
2656 }
2657 catch_or_finally_seen = true;
2658 } else {
2659 assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
2661 ParseScope FinallyScope(this,
2663
2664 bool ShouldCapture =
2666 if (ShouldCapture)
2669
2671 if (Tok.is(tok::l_brace))
2672 FinallyBody = ParseCompoundStatementBody();
2673 else
2674 Diag(Tok, diag::err_expected) << tok::l_brace;
2675
2676 if (FinallyBody.isInvalid()) {
2678 if (ShouldCapture)
2680 } else if (ShouldCapture) {
2682 }
2683
2685 FinallyBody.get());
2686 catch_or_finally_seen = true;
2687 break;
2688 }
2689 }
2690 if (!catch_or_finally_seen) {
2691 Diag(atLoc, diag::err_missing_catch_finally);
2693 }
2694
2696 FinallyStmt.get());
2697}
2698
2699
2700
2701
2703Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
2705 if (Tok.isNot(tok::l_brace)) {
2706 Diag(Tok, diag::err_expected) << tok::l_brace;
2708 }
2709
2710
2712
2713 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2714
2715 BodyScope.Exit();
2716 if (AutoreleasePoolBody.isInvalid())
2719 AutoreleasePoolBody.get());
2720}
2721
2722
2723
2724void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
2725 if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
2726 trySkippingFunctionBody()) {
2728 return;
2729 }
2730
2731 LexedMethod* LM = new LexedMethod(this, MDecl);
2732 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2734
2735 Toks.push_back(Tok);
2736 if (Tok.is(tok::kw_try)) {
2738 if (Tok.is(tok::colon)) {
2739 Toks.push_back(Tok);
2741 while (Tok.isNot(tok::l_brace)) {
2742 ConsumeAndStoreUntil(tok::l_paren, Toks, false);
2743 ConsumeAndStoreUntil(tok::r_paren, Toks, false);
2744 }
2745 }
2746 Toks.push_back(Tok);
2747 }
2748 else if (Tok.is(tok::colon)) {
2750
2751 while (Tok.isNot(tok::l_brace)) {
2752 ConsumeAndStoreUntil(tok::l_paren, Toks, false);
2753 ConsumeAndStoreUntil(tok::r_paren, Toks, false);
2754 }
2755 Toks.push_back(Tok);
2756 }
2757 ConsumeBrace();
2758
2759 ConsumeAndStoreUntil(tok::r_brace, Toks, false);
2760 while (Tok.is(tok::kw_catch)) {
2761 ConsumeAndStoreUntil(tok::l_brace, Toks, false);
2762 ConsumeAndStoreUntil(tok::r_brace, Toks, false);
2763 }
2764}
2765
2766
2767
2768Decl *Parser::ParseObjCMethodDefinition() {
2769 Decl *MDecl = ParseObjCMethodPrototype();
2770
2772 "parsing Objective-C method");
2773
2774
2775 if (Tok.is(tok::semi)) {
2776 if (CurParsedObjCImpl) {
2777 Diag(Tok, diag::warn_semicolon_before_method_body)
2779 }
2781 }
2782
2783
2784 if (Tok.isNot(tok::l_brace)) {
2785 Diag(Tok, diag::err_expected_method_body);
2786
2787
2789
2790
2791 if (Tok.isNot(tok::l_brace))
2792 return nullptr;
2793 }
2794
2795 if (!MDecl) {
2796 ConsumeBrace();
2798 return nullptr;
2799 }
2800
2801
2803 assert (CurParsedObjCImpl
2804 && "ParseObjCMethodDefinition - Method out of @implementation");
2805
2806 StashAwayMethodOrFunctionBodyTokens(MDecl);
2807 return MDecl;
2808}
2809
2811 ParsedStmtContext StmtCtx) {
2812 if (Tok.is(tok::code_completion)) {
2813 cutOffParsing();
2816 }
2817
2819 return ParseObjCTryStmt(AtLoc);
2820
2822 return ParseObjCThrowStmt(AtLoc);
2823
2825 return ParseObjCSynchronizedStmt(AtLoc);
2826
2828 return ParseObjCAutoreleasePoolStmt(AtLoc);
2829
2834 }
2835
2836 ExprStatementTokLoc = AtLoc;
2837 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2839
2840
2841
2844 }
2845
2846
2847 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2848 return handleExprStmt(Res, StmtCtx);
2849}
2850
2852 switch (Tok.getKind()) {
2853 case tok::code_completion:
2854 cutOffParsing();
2857
2858 case tok:âž–
2859 case tok:âž• {
2862
2863 if (!Tok.is(tok::numeric_constant)) {
2864 const char *Symbol = nullptr;
2865 switch (Kind) {
2866 case tok:âž– Symbol = "-"; break;
2867 case tok:âž• Symbol = "+"; break;
2868 default: llvm_unreachable("missing unary operator case");
2869 }
2870 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2871 << Symbol;
2873 }
2874
2876 if (Lit.isInvalid()) {
2877 return Lit;
2878 }
2879 ConsumeToken();
2880
2882 if (Lit.isInvalid())
2883 return Lit;
2884
2885 return ParsePostfixExpressionSuffix(
2887 }
2888
2889 case tok::string_literal:
2890 case tok::wide_string_literal:
2891 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2892
2893 case tok::char_constant:
2894 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2895
2896 case tok::numeric_constant:
2897 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2898
2899 case tok::kw_true:
2900 case tok::kw___objc_yes:
2901 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, true));
2902 case tok::kw_false:
2903 case tok::kw___objc_no:
2904 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, false));
2905
2906 case tok::l_square:
2907
2908 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2909
2910 case tok::l_brace:
2911
2912 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2913
2914 case tok::l_paren:
2915
2916 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2917
2918 default:
2920 return ExprError(Diag(AtLoc, diag::err_unexpected_at));
2921
2923 case tok::objc_encode:
2924 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2925 case tok::objc_protocol:
2926 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2927 case tok::objc_selector:
2928 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2929 case tok::objc_available:
2930 return ParseAvailabilityCheckExpr(AtLoc);
2931 default: {
2932 const char *str = nullptr;
2933
2934
2935
2936 if (GetLookAheadToken(1).is(tok::l_brace) &&
2937 ExprStatementTokLoc == AtLoc) {
2939 str =
2940 ch == 't' ? "try"
2941 : (ch == 'f' ? "finally"
2942 : (ch == 'a' ? "autoreleasepool" : nullptr));
2943 }
2944 if (str) {
2946 return ExprError(Diag(AtLoc, diag::err_unexpected_at) <<
2948 }
2949 else
2950 return ExprError(Diag(AtLoc, diag::err_unexpected_at));
2951 }
2952 }
2953 }
2954}
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
2980
2981 if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2982 tok::annot_cxxscope))
2984
2986
2987
2988
2989
2990
2993 return true;
2994
2995 IsExpr = true;
2996 TypeOrExpr = Receiver.get();
2997 return false;
2998 }
2999
3000
3001
3002
3003
3005 ParseCXXSimpleTypeSpecifier(DS);
3006
3007 if (Tok.is(tok::l_paren)) {
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
3022 Receiver = ParsePostfixExpressionSuffix(Receiver.get());
3024 Receiver = ParseRHSOfBinaryExpression(Receiver.get(), prec::Comma);
3026 return true;
3027
3028 IsExpr = true;
3029 TypeOrExpr = Receiver.get();
3030 return false;
3031 }
3032
3033
3034
3035
3039 if (Type.isInvalid())
3040 return true;
3041
3042 IsExpr = false;
3043 TypeOrExpr = Type.get().getAsOpaquePtr();
3044 return false;
3045}
3046
3047
3048
3049
3050
3051
3052bool Parser::isSimpleObjCMessageExpression() {
3054 "Incorrect start for isSimpleObjCMessageExpression");
3055 return GetLookAheadToken(1).is(tok::identifier) &&
3056 GetLookAheadToken(2).is(tok::identifier);
3057}
3058
3059bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
3061 InMessageExpression)
3062 return false;
3063
3065
3066 if (Tok.is(tok::annot_typename))
3068 else if (Tok.is(tok::identifier))
3071 else
3072 return false;
3073
3074
3076 const Token &AfterNext = GetLookAheadToken(2);
3077 if (AfterNext.isOneOf(tok::colon, tok::r_square)) {
3078 if (Tok.is(tok::identifier))
3080
3081 return Tok.is(tok::annot_typename);
3082 }
3083 }
3084
3085 return false;
3086}
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097ExprResult Parser::ParseObjCMessageExpression() {
3098 assert(Tok.is(tok::l_square) && "'[' expected");
3099 SourceLocation LBracLoc = ConsumeBracket();
3100
3101 if (Tok.is(tok::code_completion)) {
3102 cutOffParsing();
3105 }
3106
3108
3110
3111
3112
3113
3114
3115
3116 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
3118 return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), nullptr,
3119 nullptr);
3120
3121
3122 bool IsExpr;
3123 void *TypeOrExpr = nullptr;
3124 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
3127 }
3128
3129 if (IsExpr)
3130 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), nullptr,
3131 static_cast<Expr *>(TypeOrExpr));
3132
3133 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
3135 nullptr);
3136 }
3137
3138 if (Tok.is(tok::identifier)) {
3143 getCurScope(), Name, NameLoc, Name == Ident_super,
3144 NextToken().is(tok::period), ReceiverType)) {
3146 return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), nullptr,
3147 nullptr);
3148
3150 if (!ReceiverType) {
3153 }
3154
3156
3157
3158 if (Tok.is(tok::less)) {
3161 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3162 true,
3163 NewEndLoc);
3164 if (!NewReceiverType.isUsable()) {
3167 }
3168
3169 ReceiverType = NewReceiverType.get();
3170 }
3171
3172 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
3173 ReceiverType, nullptr);
3174
3176
3177 break;
3178 }
3179 }
3180
3181
3185 return Res;
3186 }
3187
3188 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), nullptr,
3189 Res.get());
3190}
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3231Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
3234 Expr *ReceiverExpr) {
3236
3237 if (Tok.is(tok::code_completion)) {
3238 cutOffParsing();
3242 else if (ReceiverType)
3244 getCurScope(), ReceiverType, {}, false);
3245 else
3247 getCurScope(), ReceiverExpr, {}, false);
3249 }
3250
3251
3254
3257 ExprVector KeyExprs;
3258
3259 if (Tok.is(tok::colon)) {
3260 while (true) {
3261
3262 KeyIdents.push_back(selIdent);
3263 KeyLocs.push_back(Loc);
3264
3265 if (ExpectAndConsume(tok::colon)) {
3266
3267
3268
3271 }
3272
3273
3274
3275 if (Tok.is(tok::code_completion)) {
3276 cutOffParsing();
3280 true);
3281 else if (ReceiverType)
3284 true);
3285 else
3288 true);
3289
3291 }
3292
3295 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3296 Expr = ParseBraceInitializer();
3297 } else
3299
3302
3303
3304
3306 return Res;
3307 }
3308
3309
3310 KeyExprs.push_back(Res.get());
3311
3312
3313 if (Tok.is(tok::code_completion)) {
3314 cutOffParsing();
3318 false);
3319 else if (ReceiverType)
3322 false);
3323 else
3326 false);
3328 }
3329
3330
3331 selIdent = ParseObjCSelectorPiece(Loc);
3332 if (!selIdent && Tok.isNot(tok::colon))
3333 break;
3334
3335 }
3336
3337 while (Tok.is(tok::comma)) {
3339
3341 if (Tok.is(tok::colon))
3344 if (Tok.is(tok::colon)) {
3345 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3347 }
3348
3349
3350
3352 return Res;
3353 }
3354
3355
3356 KeyExprs.push_back(Res.get());
3357 }
3358 } else if (!selIdent) {
3359 Diag(Tok, diag::err_expected) << tok::identifier;
3360
3361
3362
3363
3366 }
3367
3368 if (Tok.isNot(tok::r_square)) {
3369 Diag(Tok, diag::err_expected)
3370 << (Tok.is(tok::identifier) ? tok::colon : tok::r_square);
3371
3372
3373
3376 }
3377
3378 SourceLocation RBracLoc = ConsumeBracket();
3379
3380 unsigned nKeys = KeyIdents.size();
3381 if (nKeys == 0) {
3382 KeyIdents.push_back(selIdent);
3383 KeyLocs.push_back(Loc);
3384 }
3386
3389 getCurScope(), SuperLoc, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3390 else if (ReceiverType)
3392 LBracLoc, KeyLocs, RBracLoc,
3393 KeyExprs);
3395 getCurScope(), ReceiverExpr, Sel, LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3396}
3397
3400 if (Res.isInvalid()) return Res;
3401
3402
3403
3404
3406 ExprVector AtStrings;
3407 AtLocs.push_back(AtLoc);
3408 AtStrings.push_back(Res.get());
3409
3410 while (Tok.is(tok::at)) {
3411 AtLocs.push_back(ConsumeToken());
3412
3413
3414 if (!isTokenStringLiteral())
3415 return ExprError(Diag(Tok, diag::err_objc_concat_string));
3416
3418 if (Lit.isInvalid())
3419 return Lit;
3420
3421 AtStrings.push_back(Lit.get());
3422 }
3423
3425}
3426
3427
3428
3429
3430
3431
3433 bool ArgValue) {
3436}
3437
3438
3439
3440
3443 if (Lit.isInvalid()) {
3444 return Lit;
3445 }
3446 ConsumeToken();
3448}
3449
3450
3451
3452
3453
3454
3457 if (Lit.isInvalid()) {
3458 return Lit;
3459 }
3460 ConsumeToken();
3462}
3463
3464
3465
3466
3469 if (Tok.isNot(tok::l_paren))
3470 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@");
3471
3473 T.consumeOpen();
3475 if (T.consumeClose())
3477
3478 if (ValueExpr.isInvalid())
3480
3481
3482
3483 SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation();
3484 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
3486 ValueExpr.get());
3487}
3488
3490 ExprVector ElementExprs;
3491 ConsumeBracket();
3492
3493 bool HasInvalidEltExpr = false;
3494 while (Tok.isNot(tok::r_square)) {
3495
3498
3499
3500
3502 return Res;
3503 }
3504
3507 HasInvalidEltExpr = true;
3508
3509
3510 if (Tok.is(tok::ellipsis))
3513 HasInvalidEltExpr = true;
3514
3515 ElementExprs.push_back(Res.get());
3516
3517 if (Tok.is(tok::comma))
3519 else if (Tok.isNot(tok::r_square))
3520 return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_square
3521 << tok::comma);
3522 }
3523 SourceLocation EndLoc = ConsumeBracket();
3524
3525 if (HasInvalidEltExpr)
3527
3530}
3531
3534 ConsumeBrace();
3535 bool HasInvalidEltExpr = false;
3536 while (Tok.isNot(tok::r_brace)) {
3537
3539 {
3543
3544
3545
3547 return KeyExpr;
3548 }
3549 }
3550
3551 if (ExpectAndConsume(tok::colon)) {
3554 }
3555
3557 if (ValueExpr.isInvalid()) {
3558
3559
3560
3562 return ValueExpr;
3563 }
3564
3565
3568 if (KeyExpr.isInvalid() || ValueExpr.isInvalid())
3569 HasInvalidEltExpr = true;
3570
3571
3572
3573
3577
3578
3579
3581 EllipsisLoc, std::nullopt};
3582 Elements.push_back(Element);
3583
3585 return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_brace
3586 << tok::comma);
3587 }
3589
3590 if (HasInvalidEltExpr)
3592
3593
3595 Elements);
3596}
3597
3598
3599
3601Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
3602 assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
3603
3605
3606 if (Tok.isNot(tok::l_paren))
3607 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
3608
3610 T.consumeOpen();
3611
3613
3614 T.consumeClose();
3615
3618
3620 AtLoc, EncLoc, T.getOpenLocation(), Ty.get(), T.getCloseLocation());
3621}
3622
3623
3624
3626Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
3628
3629 if (Tok.isNot(tok::l_paren))
3630 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
3631
3633 T.consumeOpen();
3634
3635 if (expectIdentifier())
3637
3640
3641 T.consumeClose();
3642
3644 protocolId, AtLoc, ProtoLoc, T.getOpenLocation(), ProtoIdLoc,
3645 T.getCloseLocation());
3646}
3647
3648
3649
3652
3653 if (Tok.isNot(tok::l_paren))
3654 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
3655
3658
3660 T.consumeOpen();
3661 bool HasOptionalParen = Tok.is(tok::l_paren);
3662 if (HasOptionalParen)
3663 ConsumeParen();
3664
3665 if (Tok.is(tok::code_completion)) {
3666 cutOffParsing();
3669 }
3670
3671 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
3672 if (!SelIdent &&
3673 Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3674 return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
3675
3676 KeyIdents.push_back(SelIdent);
3677
3678 unsigned nColons = 0;
3679 if (Tok.isNot(tok::r_paren)) {
3680 while (true) {
3681 if (TryConsumeToken(tok::coloncolon)) {
3682 ++nColons;
3683 KeyIdents.push_back(nullptr);
3684 } else if (ExpectAndConsume(tok::colon))
3686 ++nColons;
3687
3688 if (Tok.is(tok::r_paren))
3689 break;
3690
3691 if (Tok.is(tok::code_completion)) {
3692 cutOffParsing();
3694 KeyIdents);
3696 }
3697
3698
3700 SelIdent = ParseObjCSelectorPiece(Loc);
3701 KeyIdents.push_back(SelIdent);
3702 if (!SelIdent && Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3703 break;
3704 }
3705 }
3706 if (HasOptionalParen && Tok.is(tok::r_paren))
3707 ConsumeParen();
3708 T.consumeClose();
3711 Sel, AtLoc, SelectorLoc, T.getOpenLocation(), T.getCloseLocation(),
3712 !HasOptionalParen);
3713}
3714
3715void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
3716
3717 Decl *MCDecl = LM.D;
3718 bool skip =
3721 if (skip)
3722 return;
3723
3724
3726
3727 assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!");
3728
3729
3735 LM.Toks.push_back(Eof);
3736
3737
3738 LM.Toks.push_back(Tok);
3739 PP.EnterTokenStream(LM.Toks, true, true);
3740
3741
3743
3744 assert(Tok.isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3745 "Inline objective-c method not starting with '{' or 'try' or ':'");
3746
3751
3752
3753
3754 if (parseMethod)
3756 else
3758 if (Tok.is(tok::kw_try))
3759 ParseFunctionTryBlock(MCDecl, BodyScope);
3760 else {
3761 if (Tok.is(tok::colon))
3762 ParseConstructorInitializer(MCDecl);
3763 else
3765 ParseFunctionStatementBody(MCDecl, BodyScope);
3766 }
3767
3769
3770
3771
3772
3773
3775 OrigLoc))
3778 }
3779
3780
3781 if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl)
3783}
Defines the clang::ASTContext interface.
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.
Class to handle popping type parameters when leaving the scope.
ObjCTypeParamListScope(Sema &Actions, Scope *S)
void enter(ObjCTypeParamList *P)
~ObjCTypeParamListScope()
const clang::PrintingPolicy & getPrintingPolicy() const
The result of parsing/analyzing an expression, statement etc.
Attr - This represents one attribute.
bool isGNUAttribute() const
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 { ....
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Captures information about "declaration specifiers".
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.
This represents one expression.
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.
RAII object that makes '>' behave either as an operator or as the closing angle bracket for a templat...
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.
tok::ObjCKeywordKind getObjCKeywordID() const
Return the Objective-C keyword ID for the this identifier.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ObjCCategoryDecl - Represents a category declaration.
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)
Represents an ObjC class declaration.
void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition)
Represents an Objective-C protocol declaration.
void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition)
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Wrapper for void* pointer.
static OpaquePtr getFromOpaquePtr(void *P)
Represents a parameter to a function.
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)
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 type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Preprocessor & getPreprocessor() const
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.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
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 ...
friend class ObjCDeclContextSwitch
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
SmallVector< Stmt *, 32 > StmtVector
A SmallVector of statements.
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...
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
RAII object used to inform the actions that we're currently parsing a declaration.
A class for parsing a DeclSpec.
A class for parsing a field declarator.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
SourceManager & getSourceManager() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
IdentifierTable & getIdentifierTable()
SelectorTable & getSelectorTable()
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
A (possibly-)qualified type.
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.
Selector getNullarySelector(const IdentifierInfo *ID)
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Smart pointer class that efficiently represents Objective-C method names.
void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression, ObjCInterfaceDecl *Super=nullptr)
void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, IdentifierInfo *PropertyName)
void CodeCompleteObjCClassForwardDecl(Scope *S)
void CodeCompleteObjCAtStatement(Scope *S)
void CodeCompleteObjCMessageReceiver(Scope *S)
void CodeCompleteObjCProtocolDecl(Scope *S)
void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS)
@ 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,...
void CodeCompleteObjCAtDirective(Scope *S)
void CodeCompleteObjCPropertySetter(Scope *S)
void CodeCompleteObjCImplementationCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
void CodeCompleteObjCInterfaceDecl(Scope *S)
void CodeCompleteObjCAtExpression(Scope *S)
void CodeCompleteObjCPropertyDefinition(Scope *S)
void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression)
void CodeCompleteObjCMethodDeclSelector(Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnType, ArrayRef< const IdentifierInfo * > SelIdents)
void CodeCompleteObjCInterfaceCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
void CodeCompleteObjCSelector(Scope *S, ArrayRef< const IdentifierInfo * > SelIdents)
void CodeCompleteObjCImplementationDecl(Scope *S)
void CodeCompleteObjCMethodDecl(Scope *S, std::optional< bool > IsInstanceMethod, ParsedType ReturnType)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteObjCProtocolReferences(ArrayRef< IdentifierLocPair > Protocols)
void CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
void CodeCompleteObjCAtVisibility(Scope *S)
void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression, bool IsSuper=false)
void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, bool IsParameter)
void CodeCompleteObjCPropertyGetter(Scope *S)
Decl * ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, Expr *BitWidth, tok::ObjCKeywordKind visibility)
ActOnIvar - Each ivar field of an objective-c class is passed into this in order to create an IvarDec...
void ActOnStartOfObjCMethodDef(Scope *S, Decl *D)
ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible and user declared,...
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
TypeResult actOnObjCTypeArgsAndProtocolQualifiers(Scope *S, SourceLocation Loc, ParsedType BaseType, SourceLocation TypeArgsLAngleLoc, ArrayRef< ParsedType > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< Decl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc)
Build a specialized and/or protocol-qualified Objective-C type.
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
ObjCInterfaceDecl * ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, IdentifierInfo *SuperName, SourceLocation SuperLoc, ArrayRef< ParsedType > SuperTypeArgs, SourceRange SuperTypeArgsRange, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody)
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList)
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.
ObjCImplementationDecl * ActOnStartClassImplementation(SourceLocation AtClassImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *SuperClassname, SourceLocation SuperClassLoc, const ParsedAttributesView &AttrList)
Decl * ActOnObjCExceptionDecl(Scope *S, Declarator &D)
StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, Stmt *SynchBody)
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
DeclResult actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, IdentifierInfo *paramName, SourceLocation paramLoc, SourceLocation colonLoc, ParsedType typeBound)
ObjCContainerKind getObjCContainerKind() const
ParmVarDecl * ActOnMethodParmDeclaration(Scope *S, ObjCArgInfo &ArgInfo, int ParamIndex, bool MethodDefinition)
DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef< Decl * > Decls)
ObjCContainerDecl * getObjCDeclContext() const
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, MultiStmtArg Catch, Stmt *Finally)
StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
TypeResult actOnObjCProtocolQualifierType(SourceLocation lAngleLoc, ArrayRef< Decl * > protocols, ArrayRef< SourceLocation > protocolLocs, SourceLocation rAngleLoc)
Build a an Objective-C protocol-qualified 'id' type where no base type was specified.
Decl * ActOnCompatibilityAlias(SourceLocation AtCompatibilityAliasLoc, IdentifierInfo *AliasName, SourceLocation AliasLocation, IdentifierInfo *ClassName, SourceLocation ClassLocation)
ActOnCompatibilityAlias - this action is called after complete parsing of a @compatibility_alias decl...
ObjCTypeParamList * actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, ArrayRef< Decl * > typeParams, SourceLocation rAngleLoc)
ObjCCategoryDecl * ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, const IdentifierInfo *CategoryName, SourceLocation CategoryLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList)
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)
void actOnObjCTypeArgsOrProtocolQualifiers(Scope *S, ParsedType baseType, SourceLocation lAngleLoc, ArrayRef< IdentifierInfo * > identifiers, ArrayRef< SourceLocation > identifierLocs, SourceLocation rAngleLoc, SourceLocation &typeArgsLAngleLoc, SmallVectorImpl< ParsedType > &typeArgs, SourceLocation &typeArgsRAngleLoc, SourceLocation &protocolLAngleLoc, SmallVectorImpl< Decl * > &protocols, SourceLocation &protocolRAngleLoc, bool warnOnIncompleteProtocols)
Given a list of identifiers (and their locations), resolve the names to either Objective-C protocol q...
Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)
ObjCCategoryImplDecl * ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *CatName, SourceLocation CatLoc, const ParsedAttributesView &AttrList)
ActOnStartCategoryImplementation - Perform semantic checks on the category implementation declaration...
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)
Decl * ActOnMethodDeclaration(Scope *S, SourceLocation BeginLoc, SourceLocation EndLoc, tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, ArrayRef< SourceLocation > SelectorLocs, Selector Sel, ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind, bool isVariadic, bool MethodDefinition)
ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)
Decl * ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, bool ImplKind, IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, SourceLocation PropertyIvarLoc, ObjCPropertyQueryKind QueryKind)
ActOnPropertyImplDecl - This routine performs semantic checks and builds the AST node for a property ...
void ActOnTypedefedProtocols(SmallVectorImpl< Decl * > &ProtocolRefs, SmallVectorImpl< SourceLocation > &ProtocolLocs, IdentifierInfo *SuperName, SourceLocation SuperLoc)
ActOnTypedefedProtocols - this action finds protocol list as part of the typedef'ed use for a qualifi...
DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, ArrayRef< IdentifierLocPair > IdentList, const ParsedAttributesView &attrList)
ActOnForwardProtocolDeclaration - Handle @protocol foo;.
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, Scope *CurScope)
ObjCProtocolDecl * ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody)
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, ArrayRef< ObjCTypeParamList * > TypeParamLists, unsigned NumElts)
StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, Decl *Parm, Stmt *Body)
@ 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'.
bool isObjCMethodDecl(Decl *D)
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, SourceLocation ProtocolLoc, IdentifierInfo *TypeArgId, SourceLocation TypeArgLoc, bool SelectProtocolFirst=false)
Decl * ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef< Decl * > allMethods={}, ArrayRef< DeclGroupPtrTy > allTUVars={})
StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
void AddAnyMethodToGlobalPool(Decl *D)
AddAnyMethodToGlobalPool - Add any method, instance or factory to global pool.
void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, ArrayRef< IdentifierLocPair > ProtocolId, SmallVectorImpl< Decl * > &Protocols)
FindProtocolDeclaration - This routine looks up protocols and issues an error if they are not declare...
Records and restores the CurFPFeatures state on entry/exit of compound statements.
Sema - This implements semantic analysis and AST building for C.
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
Decl * ActOnSkippedFunctionBody(Decl *Decl)
Decl * ActOnParamDeclarator(Scope *S, Declarator &D, SourceLocation ExplicitThisLoc={})
ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() to introduce parameters into fun...
bool ActOnDuplicateODRHashDefinition(T *Duplicate, T *Previous)
Check ODR hashes for C/ObjC when merging types from modules.
ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope=nullptr)
void ActOnCapturedRegionError()
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ASTContext & getASTContext() const
SemaCodeCompletion & CodeCompletion()
Decl * ActOnStartOfFunctionDef(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, SkipBodyInfo *SkipBody=nullptr, FnBodyKind BodyKind=FnBodyKind::Other)
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
StmtResult ActOnCapturedRegionEnd(Stmt *S)
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
bool canSkipFunctionBody(Decl *D)
Determine whether we can skip parsing the body of a function definition, assuming we don't care about...
void ActOnDefaultCtorInitializers(Decl *CDtorDecl)
TypeResult ActOnTypeName(Declarator &D)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
void ActOnLastBitfield(SourceLocation DeclStart, SmallVectorImpl< Decl * > &AllIvarDecls)
ActOnLastBitfield - This routine handles synthesized bitfields rules for class and class extensions.
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
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.
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
void DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType, bool IsTemplateName=false)
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
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.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setLength(unsigned Len)
void setKind(tok::TokenKind K)
tok::ObjCKeywordKind getObjCKeywordID() const
Return the ObjC keyword kind.
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)) {....
tok::TokenKind getKind() const
void setEofData(const void *D)
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
const void * getEofData() const
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
bool isSimpleTypeSpecifier(const LangOptions &LangOpts) const
Determine whether the token kind starts a simple-type-specifier.
void startToken()
Reset all flags to cleared.
The base class of the type hierarchy.
bool isObjCObjectOrInterfaceType() const
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 ...
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.
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
@ Property
The type of a property.
@ Result
The result type of a method or function.
std::pair< NullabilityKind, bool > DiagNullabilityKind
A nullability kind paired with a bit indicating whether it used a context-sensitive keyword.
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 is a subtype of X when the type parameter is covariant and...
@ Covariant
The parameter is covariant, e.g., X is a subtype of X when the type parameter is covariant and T i...
std::pair< IdentifierInfo *, SourceLocation > IdentifierLocPair
A simple pair of identifier info and location.
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
An element in an Objective-C dictionary literal.
ParsedAttributesView ArgAttrs
ArgAttrs - Attribute list for this argument.