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 (type.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

1955

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.