clang: lib/Sema/SemaDeclObjC.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

30#include "llvm/ADT/DenseMap.h"

31#include "llvm/ADT/DenseSet.h"

32

33using namespace clang;

34

35

36

37

38

39

40

41

42

43

45 QualType receiverTypeIfCall) {

48

49

50

51

52

53

54

57

59 return false;

61

62 } else {

64 assert(resultClass && "unexpected object type!");

65

66

67

69 if (receiverTypeIfCall.isNull() &&

70 !isa(method->getDeclContext()))

71 return false;

72

73

74 } else {

75

76

78 if (isa(method->getDeclContext())) {

79 if (receiverTypeIfCall.isNull())

80 return false;

81

83 ->getInterfaceDecl();

84

85

86 if (!receiverClass) return false;

87 } else {

89 assert(receiverClass && "method not associated with a class!");

90 }

91

92

95 return false;

96 }

97 }

98

100

101

102

103 if (receiverTypeIfCall.isNull() &&

105 method->addAttr(UnavailableAttr::CreateImplicit(Context, "",

106 UnavailableAttr::IR_ARCInitReturnsUnrelated, loc));

107 return true;

108 }

109

110

111 Diag(loc, diag::err_arc_init_method_unrelated_result_type);

113 return true;

114}

115

116

117

120 if (OldD->hasAttr() && !NewD->hasAttr()) {

121 S.Diag(NewD->getLocation(), diag::warn_overriding_method_missing_noescape);

122 S.Diag(OldD->getLocation(), diag::note_overridden_marked_noescape);

123 return false;

124 }

125

126 return true;

127}

128

129

130

135 S.Diag(CD->getLocation(), diag::note_cat_conform_to_noescape_prot)

138}

139

145

146

147

148

151

152

154 = dyn_cast(NewMethod->getDeclContext());

155 if (!CurrentClass) {

158 CurrentClass = Cat->getClassInterface();

159 else if (ObjCImplDecl *Impl = dyn_cast(DC))

160 CurrentClass = Impl->getClassInterface();

162 = dyn_cast(DC))

163 CurrentClass = CatImpl->getClassInterface();

164 }

165

166 if (CurrentClass) {

168 diag::warn_related_result_type_compatibility_class)

170 << ResultType

171 << ResultTypeRange;

172 } else {

174 diag::warn_related_result_type_compatibility_protocol)

175 << ResultType

176 << ResultTypeRange;

177 }

178

181 diag::note_related_result_type_family)

182 << 0

183 << Family;

184 else

186 diag::note_related_result_type_overridden);

187 }

188

189 if ((NewMethod->hasAttr() !=

190 Overridden->hasAttr())) {

193 ? diag::err_nsreturns_retained_attribute_mismatch

194 : diag::warn_nsreturns_retained_attribute_mismatch)

195 << 1;

196 Diag(Overridden->getLocation(), diag::note_previous_decl) << "method";

197 }

198 if ((NewMethod->hasAttr() !=

199 Overridden->hasAttr())) {

202 ? diag::err_nsreturns_retained_attribute_mismatch

203 : diag::warn_nsreturns_retained_attribute_mismatch)

204 << 0;

205 Diag(Overridden->getLocation(), diag::note_previous_decl) << "method";

206 }

207

212 ni != ne && oi != oe; ++ni, ++oi) {

215 if (newDecl->hasAttr() !=

216 oldDecl->hasAttr()) {

219 ? diag::err_nsconsumed_attribute_mismatch

220 : diag::warn_nsconsumed_attribute_mismatch);

221 Diag(oldDecl->getLocation(), diag::note_previous_decl) << "parameter";

222 }

223

225 }

226}

227

228

229

233 switch (family) {

243 return false;

244

249 Diag(method->getLocation(), diag::err_dealloc_bad_result_type)

252 else

253 Diag(method->getLocation(), diag::err_dealloc_bad_result_type)

256 return true;

257 }

258 return false;

259

261

263 return true;

264

265 method->addAttr(NSConsumesSelfAttr::CreateImplicit(Context));

266

267

268

269 if (method->hasAttr())

270 return false;

271 break;

272

277 if (method->hasAttr() ||

278 method->hasAttr() ||

279 method->hasAttr())

280 return false;

281 break;

282 }

283

284 method->addAttr(NSReturnsRetainedAttr::CreateImplicit(Context));

285 return false;

286}

287

290 if (!ND)

291 return;

292 bool IsCategory = false;

293 StringRef RealizedPlatform;

295 nullptr, VersionTuple(),

296 &RealizedPlatform);

298 if (isa(ND)) {

300 return;

301 if (RealizedPlatform.empty())

303

304

305 if (RealizedPlatform.ends_with("_app_extension"))

306 return;

307 S.Diag(ImplLoc, diag::warn_unavailable_def);

310 return;

311 }

312 if (const auto *CD = dyn_cast(ND)) {

313 if (!CD->getClassInterface()->isDeprecated())

314 return;

315 ND = CD->getClassInterface();

316 IsCategory = true;

317 } else

318 return;

319 }

320 S.Diag(ImplLoc, diag::warn_deprecated_def)

321 << (isa(ND)

322 ? 0

323 : isa(ND) || IsCategory ? 2

324 : 1);

325 if (isa(ND))

328 else

330 << (isa(ND) ? "category" : "class");

331}

332

333

334

336 ObjCMethodDecl *MDecl = dyn_cast_or_null(D);

337

338

339 if (!MDecl)

340 return;

343 else

345}

346

347

348

349static bool

352

357 } else {

358 return true;

359 }

360

361

362

363 return T.getLocalQualifiers().hasObjCLifetime();

364}

365

366

367

372 ObjCMethodDecl *MDecl = dyn_cast_or_null(D);

373

376

377

378 if (!MDecl)

379 return;

380

385 diag::err_func_def_incomplete_result))

387

388

391

392

393

394

395

397

400

401

403 false);

404

405

406 for (auto *Param : MDecl->parameters()) {

407 if (!Param->isInvalidDecl() && getLangOpts().ObjCAutoRefCount &&

409 Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) <<

410 Param->getType();

411

412 if (Param->getIdentifier())

414 }

415

416

423 Diag(MDecl->getLocation(), diag::err_arc_illegal_method_def)

425 break;

426

438 break;

439 }

440 }

441

442

443

447

448 if (IMD) {

453 ObjCImplDecl *ImplDeclOfMethodDecl = nullptr;

454 if (ObjCInterfaceDecl *OID = dyn_cast(ContDeclOfMethodDecl))

455 ImplDeclOfMethodDecl = OID->getImplementation();

456 else if (ObjCCategoryDecl *CD = dyn_cast(ContDeclOfMethodDecl)) {

457 if (CD->IsClassExtension()) {

459 ImplDeclOfMethodDecl = OID->getImplementation();

460 } else

461 ImplDeclOfMethodDecl = CD->getImplementation();

462 }

463

464

465 if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef)

467 }

468

473 IC->getSuperClass() != nullptr;

474 } else if (IC->hasDesignatedInitializers()) {

477 }

478 }

479

480

481

482

483

490

494

495 } else {

497 SuperClass->lookupMethod(MDecl->getSelector(),

500 (SuperMethod && SuperMethod->hasAttr());

501 }

502 }

503 }

504

505

506

508}

509

510namespace {

511

512

513

514

516 public:

517 ObjCInterfaceValidatorCCC() : CurrentIDecl(nullptr) {}

519 : CurrentIDecl(IDecl) {}

520

521 bool ValidateCandidate(const TypoCorrection &candidate) override {

524 }

525

526 std::unique_ptr clone() override {

527 return std::make_unique(*this);

528 }

529

530 private:

532};

533

534}

535

539 unsigned NumProtoRefs,

541 assert(ProtoRefs);

542

544 for (unsigned i = 0; i < NumProtoRefs; ++i) {

546 nullptr,

547 false,

548 true);

549 }

550}

551

558

561

562 if (!PrevDecl) {

563

564

565 ObjCInterfaceValidatorCCC CCC(IDecl);

570 << SuperName << ClassName);

572 }

573 }

574

576 Diag(SuperLoc, diag::err_recursive_superclass)

577 << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);

579 } else {

581 dyn_cast_or_null(PrevDecl);

583

584

585 if (SuperClassDecl) {

588 }

589

590 if (PrevDecl && !SuperClassDecl) {

591

592

594 dyn_cast_or_null(PrevDecl)) {

595 QualType T = TDecl->getUnderlyingType();

598 SuperClassDecl = dyn_cast(IDecl);

600

601

602

603

604

607 }

608 }

609 }

610

611

612

613

614

615

616 if (!SuperClassDecl) {

617 Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;

618 Diag(PrevDecl->getLocation(), diag::note_previous_definition);

619 }

620 }

621

622 if (!isa_and_nonnull(PrevDecl)) {

623 if (!SuperClassDecl)

624 Diag(SuperLoc, diag::err_undef_superclass)

625 << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);

627 SuperLoc, SuperClassType, diag::err_forward_superclass,

628 SuperClassDecl->getDeclName(), ClassName,

629 SourceRange(AtInterfaceLoc, ClassLoc))) {

630 SuperClassDecl = nullptr;

632 }

633 }

634

635 if (SuperClassType.isNull()) {

636 assert(!SuperClassDecl && "Failed to set SuperClassType?");

637 return;

638 }

639

640

642 if (!SuperTypeArgs.empty()) {

645 SuperTypeArgsRange.getBegin(), SuperTypeArgs,

648 if (!fullSuperClassType.isUsable())

649 return;

650

651 SuperClassType =

653 }

654

655 if (!SuperClassTInfo) {

657 SuperLoc);

658 }

659

662 }

663}

664

670

672 if (parsedTypeBound) {

673

677

679

680

684 diag::err_objc_type_param_bound_missing_pointer)

685 << typeBound << paramName

687

688

689

692

693

698

699

701 } else {

702

704 diag::err_objc_type_param_bound_nonobject)

705 << typeBound << paramName;

706

707

708 typeBoundInfo = nullptr;

709 }

710

711

712

713 if (typeBoundInfo) {

717 bool diagnosed = false;

719 if (qual) {

721 rangeToRemove = attr.getLocalSourceRange();

722 if (attr.getTypePtr()->getImmediateNullability()) {

724 diag::err_objc_type_param_bound_explicit_nullability)

725 << paramName << typeBound

727 diagnosed = true;

728 }

729 }

730 }

731

732 if (!diagnosed) {

735 diag::err_objc_type_param_bound_qualified)

736 << paramName << typeBound

739 }

740

741

742

743

746 if (!quals.empty()) {

747 typeBoundInfo =

749 }

750 }

751 }

752 }

753

754

755

756 if (!typeBoundInfo) {

759 }

760

761

763 varianceLoc, index, paramLoc, paramName,

764 colonLoc, typeBoundInfo);

765}

766

772

774 typeParams(

775 reinterpret_cast<ObjCTypeParamDecl * const *>(typeParamsIn.data()),

776 typeParamsIn.size());

777

778

779

780

781

782 llvm::SmallDenseMap<IdentifierInfo *, ObjCTypeParamDecl *> knownParams;

783 for (auto *typeParam : typeParams) {

784 auto known = knownParams.find(typeParam->getIdentifier());

785 if (known != knownParams.end()) {

786 Diag(typeParam->getLocation(), diag::err_objc_type_param_redecl)

787 << typeParam->getIdentifier()

788 << SourceRange(known->second->getLocation());

789

790 typeParam->setInvalidDecl();

791 } else {

792 knownParams.insert(std::make_pair(typeParam->getIdentifier(), typeParam));

793

794

796 }

797 }

798

799

801}

802

805 for (auto *typeParam : *typeParamList) {

806 if (!typeParam->isInvalidDecl()) {

807 S->RemoveDecl(typeParam);

809 }

810 }

811}

812

813namespace {

814

815

816 enum class TypeParamListContext {

817 ForwardDeclaration,

820 Extension

821 };

822}

823

824

825

826

830 TypeParamListContext newContext) {

831

832 if (prevTypeParams->size() != newTypeParams->size()) {

834 if (newTypeParams->size() > prevTypeParams->size()) {

836 } else {

838 }

839

840 S.Diag(diagLoc, diag::err_objc_type_param_arity_mismatch)

841 << static_cast<unsigned>(newContext)

842 << (newTypeParams->size() > prevTypeParams->size())

843 << prevTypeParams->size()

844 << newTypeParams->size();

845

846 return true;

847 }

848

849

850 for (unsigned i = 0, n = prevTypeParams->size(); i != n; ++i) {

853

854

857 newContext != TypeParamListContext::Definition) {

858

859

863 !(isa(prevTypeParam->getDeclContext()) &&

864 cast(prevTypeParam->getDeclContext())

865 ->getDefinition() == prevTypeParam->getDeclContext())) {

866

867

868

869 } else {

870 {

871

875

876 auto diag = S.Diag(diagLoc,

877 diag::err_objc_type_param_variance_conflict)

878 << static_cast<unsigned>(newTypeParam->getVariance())

880 << static_cast<unsigned>(prevTypeParam->getVariance())

885 break;

886

889 StringRef newVarianceStr

891 ? "__covariant"

892 : "__contravariant";

896 (newVarianceStr + " ").str());

897 } else {

899 newVarianceStr);

900 }

901 }

902 }

903 }

904

905 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)

907

908

910 }

911 }

912

913

916 continue;

917

918

919

923 S.Diag(newBoundRange.getBegin(), diag::err_objc_type_param_bound_conflict)

931 newBoundRange,

934

935 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)

937

938

939

941 continue;

942 }

943

944

945

946

947 if (newContext == TypeParamListContext::ForwardDeclaration ||

948 newContext == TypeParamListContext::Definition) {

949

952 std::string newCode

956 diag::err_objc_type_param_bound_missing)

959 << (newContext == TypeParamListContext::ForwardDeclaration)

961

962 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)

964 }

965

966

968 }

969

970 return false;

971}

972

978 Decl *const *ProtoRefs, unsigned NumProtoRefs,

981 assert(ClassName && "Missing class identifier");

982

984

988

989 if (PrevDecl && !isa(PrevDecl)) {

990 Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;

991 Diag(PrevDecl->getLocation(), diag::note_previous_definition);

992 }

993

994

995 ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null(PrevDecl);

996

997 if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {

998

999

1000

1001

1002

1003

1004

1005

1006

1007

1008

1009

1011 }

1012

1013

1014

1015 if (PrevIDecl) {

1017 if (typeParamList) {

1018

1020 typeParamList,

1021 TypeParamListContext::Definition)) {

1022 typeParamList = nullptr;

1023 }

1024 } else {

1025 Diag(ClassLoc, diag::err_objc_parameterized_forward_class_first)

1026 << ClassName;

1027 Diag(prevTypeParamList->getLAngleLoc(), diag::note_previous_decl)

1028 << ClassName;

1029

1030

1032 for (auto *typeParam : *prevTypeParamList) {

1038 typeParam->getUnderlyingType())));

1039 }

1040

1043 clonedTypeParams,

1045 }

1046 }

1047 }

1048

1051 ClassName, typeParamList, PrevIDecl, ClassLoc);

1052 if (PrevIDecl) {

1053

1057 SkipBody->New = IDecl;

1059 } else {

1060 Diag(AtInterfaceLoc, diag::err_duplicate_class_def)

1062 Diag(Def->getLocation(), diag::note_previous_definition);

1064 }

1065 }

1066 }

1067

1071

1072

1073 if (PrevIDecl)

1075

1077

1078

1079

1084

1085 if (SuperName) {

1086

1088

1090 ClassName, ClassLoc,

1091 SuperName, SuperLoc, SuperTypeArgs,

1092 SuperTypeArgsRange);

1093 } else {

1095 }

1096

1097

1098 if (NumProtoRefs) {

1100 NumProtoRefs, ProtoLocs);

1102 ProtoLocs, Context);

1104 }

1105

1108 return IDecl;

1109}

1110

1111

1112

1113

1118 if (!SuperName)

1119 return;

1122 if (!IDecl)

1123 return;

1124

1125 if (const TypedefNameDecl *TDecl = dyn_cast_or_null(IDecl)) {

1126 QualType T = TDecl->getUnderlyingType();

1129 ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end());

1130

1131

1132

1133

1134 ProtocolLocs.append(OPT->getNumProtocols(), SuperLoc);

1135 }

1136 }

1137}

1138

1139

1140

1147

1151 if (ADecl) {

1152 Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;

1153 Diag(ADecl->getLocation(), diag::note_previous_declaration);

1154 return nullptr;

1155 }

1156

1161 dyn_cast_or_null(CDeclU)) {

1162 QualType T = TDecl->getUnderlyingType();

1165 ClassName = IDecl->getIdentifier();

1169 }

1170 }

1171 }

1172 ObjCInterfaceDecl *CDecl = dyn_cast_or_null(CDeclU);

1173 if (!CDecl) {

1174 Diag(ClassLocation, diag::warn_undef_interface) << ClassName;

1175 if (CDeclU)

1176 Diag(CDeclU->getLocation(), diag::note_previous_declaration);

1177 return nullptr;

1178 }

1179

1180

1183

1186

1188}

1189

1193

1194 bool res = false;

1196 E = PList.end(); I != E; ++I) {

1198 if (PDecl->getIdentifier() == PName) {

1199 Diag(Ploc, diag::err_protocol_has_circular_dependency);

1200 Diag(PrevLoc, diag::note_previous_definition);

1201 res = true;

1202 }

1203

1204 if (!PDecl->hasDefinition())

1205 continue;

1206

1208 PDecl->getLocation(), PDecl->getReferencedProtocols()))

1209 res = true;

1210 }

1211 }

1212 return res;

1213}

1214

1217 SourceLocation ProtocolLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs,

1221 bool err = false;

1222

1223 assert(ProtocolName && "Missing protocol identifier");

1228

1229

1230

1231

1233 ProtocolLoc, AtProtoInterfaceLoc,

1234 Def);

1235

1238 SkipBody->New = PDecl;

1240 } else {

1241

1242 Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;

1243 Diag(Def->getLocation(), diag::note_previous_definition);

1244 }

1245

1246

1247

1251 } else {

1252 if (PrevDecl) {

1253

1254

1258 ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList);

1259 }

1260

1261

1263 ProtocolLoc, AtProtoInterfaceLoc,

1264 PrevDecl);

1265

1268 }

1269

1273

1274

1275 if (PrevDecl)

1277

1278 if (!err && NumProtoRefs ) {

1279

1281 NumProtoRefs, ProtoLocs);

1283 ProtoLocs, Context);

1284 }

1285

1288 return PDecl;

1289}

1290

1295 UndefinedProtocol = PDecl;

1296 return true;

1297 }

1298

1299 for (auto *PI : PDecl->protocols())

1301 UndefinedProtocol = PI;

1302 return true;

1303 }

1304 return false;

1305}

1306

1307

1308

1309

1311 bool ForObjCContainer,

1316 if (!PDecl) {

1324 PDiag(diag::err_undeclared_protocol_suggest)

1325 << Pair.first);

1326 }

1327

1328 if (!PDecl) {

1329 Diag(Pair.second, diag::err_undeclared_protocol) << Pair.first;

1330 continue;

1331 }

1332

1335

1336

1337

1338 if (!ForObjCContainer) {

1340 }

1341

1342

1343

1344

1346

1347 if (WarnOnDeclarations &&

1349 Diag(Pair.second, diag::warn_undef_protocolref) << Pair.first;

1350 Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined)

1351 << UndefinedProtocol;

1352 }

1353 Protocols.push_back(PDecl);

1354 }

1355}

1356

1357namespace {

1358

1359

1360class ObjCTypeArgOrProtocolValidatorCCC final

1364 public:

1365 ObjCTypeArgOrProtocolValidatorCCC(ASTContext &context,

1367 : Context(context), LookupKind(lookupKind) { }

1368

1369 bool ValidateCandidate(const TypoCorrection &candidate) override {

1370

1373 return true;

1374 }

1375

1376

1378

1380

1381

1382

1383 if (isa(typeDecl) && !Context.getLangOpts().CPlusPlus)

1384 return false;

1385

1386

1387

1389 if (type->isObjCObjectPointerType() ||

1390 type->isBlockPointerType() ||

1391 type->isDependentType() ||

1392 type->isObjCObjectType())

1393 return true;

1394

1395 return false;

1396 }

1397

1398

1399

1401 return true;

1402

1403 return false;

1404 }

1405

1406 return false;

1407 }

1408

1409 std::unique_ptr clone() override {

1410 return std::make_unique(*this);

1411 }

1412};

1413}

1414

1419 bool SelectProtocolFirst) {

1420 Diag(TypeArgLoc, diag::err_objc_type_args_and_protocols)

1421 << SelectProtocolFirst << TypeArgId << ProtocolId

1423}

1424

1432 bool warnOnIncompleteProtocols) {

1434

1435

1436 unsigned numProtocolsResolved = 0;

1437 auto resolvedAsProtocols = [&] {

1438 assert(numProtocolsResolved == identifiers.size() && "Unresolved protocols");

1439

1440

1441

1442

1445 bool allAreTypeNames = false;

1447 if (!base.isNull()) {

1449 baseClass = objcObjectType->getInterface();

1450 if (baseClass) {

1452 if (typeParams->size() == numProtocolsResolved) {

1453

1454 allAreTypeNames = true;

1455 }

1456 }

1457 }

1458 }

1459 }

1460

1461 for (unsigned i = 0, n = protocols.size(); i != n; ++i) {

1464

1465

1466 if (!warnOnIncompleteProtocols) {

1468 }

1469

1470

1473

1474

1475

1476

1478 if (warnOnIncompleteProtocols &&

1480 Diag(identifierLocs[i], diag::warn_undef_protocolref)

1482 Diag(forwardDecl->getLocation(), diag::note_protocol_decl_undefined)

1483 << forwardDecl;

1484 }

1485

1486

1487

1488

1489 if (allAreTypeNames) {

1490 if (auto *decl =

1493 if (isa(decl)) {

1494 if (firstClassNameLoc.isInvalid())

1495 firstClassNameLoc = identifierLocs[i];

1496 } else if (!isa(decl)) {

1497

1498 allAreTypeNames = false;

1499 }

1500 } else {

1501 allAreTypeNames = false;

1502 }

1503 }

1504 }

1505

1506

1507

1508

1509

1510 if (allAreTypeNames && firstClassNameLoc.isValid()) {

1513 bool allProtocolsDeclared = true;

1514 for (auto *proto : protocols) {

1515 if (knownProtocols.count(static_cast<ObjCProtocolDecl *>(proto)) == 0) {

1516 allProtocolsDeclared = false;

1517 break;

1518 }

1519 }

1520

1521 if (allProtocolsDeclared) {

1522 Diag(firstClassNameLoc, diag::warn_objc_redundant_qualified_class_type)

1526 }

1527 }

1528

1529 protocolLAngleLoc = lAngleLoc;

1530 protocolRAngleLoc = rAngleLoc;

1531 assert(protocols.size() == identifierLocs.size());

1532 };

1533

1534

1535 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {

1537 protocols.push_back(proto);

1538 if (proto)

1539 ++numProtocolsResolved;

1540 }

1541

1542

1543 if (numProtocolsResolved == identifiers.size())

1544 return resolvedAsProtocols();

1545

1546

1547

1548

1549

1550 typedef llvm::PointerUnion<TypeDecl *, ObjCInterfaceDecl *> TypeOrClassDecl;

1552 unsigned numTypeDeclsResolved = 0;

1553 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {

1556 if (decl) {

1557 typeDecls.push_back(TypeOrClassDecl());

1558 continue;

1559 }

1560

1561 if (auto typeDecl = dyn_cast(decl)) {

1562 typeDecls.push_back(typeDecl);

1563 ++numTypeDeclsResolved;

1564 continue;

1565 }

1566

1567 if (auto objcClass = dyn_cast(decl)) {

1568 typeDecls.push_back(objcClass);

1569 ++numTypeDeclsResolved;

1570 continue;

1571 }

1572

1573 typeDecls.push_back(TypeOrClassDecl());

1574 }

1575

1577

1578

1579

1580 auto resolveTypeReference = [&](TypeOrClassDecl typeDecl, SourceLocation loc)

1582

1584 const char* prevSpec;

1585 unsigned diagID;

1587 if (auto *actualTypeDecl = typeDecl.dyn_cast<TypeDecl *>())

1589 else

1595

1598

1599

1601

1602

1603

1612 starLoc);

1613

1614

1615 Diag(loc, diag::err_objc_type_arg_missing_star)

1618 }

1619

1620

1622 };

1623

1624

1625

1626 auto resolvedAsTypeDecls = [&] {

1627

1628 protocols.clear();

1629

1630 assert(numTypeDeclsResolved == identifiers.size() && "Unresolved type decl");

1631

1632 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {

1633

1634 TypeResult type = resolveTypeReference(typeDecls[i], identifierLocs[i]);

1635 if (type.isUsable()) {

1636 typeArgs.clear();

1637 return;

1638 }

1639

1640 typeArgs.push_back(type.get());

1641 }

1642

1643 typeArgsLAngleLoc = lAngleLoc;

1644 typeArgsRAngleLoc = rAngleLoc;

1645 };

1646

1647

1648

1649 if (numTypeDeclsResolved == identifiers.size())

1650 return resolvedAsTypeDecls();

1651

1652

1653

1654

1656 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {

1657

1658

1659 if (protocols[i] || typeDecls[i]) {

1660

1661

1663

1664

1665 if (protocols[i] && typeDecls[i])

1666 continue;

1667

1668

1669

1672 continue;

1673 }

1674

1675

1676

1678 continue;

1679

1680

1681

1683 continue;

1684

1685

1686

1688 identifiers[i], identifierLocs[i],

1689 protocols[i] != nullptr);

1690

1691 protocols.clear();

1692 typeArgs.clear();

1693 return;

1694 }

1695

1696

1697 ObjCTypeArgOrProtocolValidatorCCC CCC(Context, lookupKind);

1701 if (corrected) {

1702

1705 PDiag(diag::err_undeclared_protocol_suggest)

1706 << identifiers[i]);

1708 protocols[i] = proto;

1709 ++numProtocolsResolved;

1710 continue;

1711 }

1712

1713

1716 PDiag(diag::err_unknown_typename_suggest)

1717 << identifiers[i]);

1719 typeDecls[i] = typeDecl;

1720 ++numTypeDeclsResolved;

1721 continue;

1722 }

1723

1724

1727 PDiag(diag::err_unknown_type_or_class_name_suggest)

1728 << identifiers[i] << true);

1730 typeDecls[i] = objcClass;

1731 ++numTypeDeclsResolved;

1732 continue;

1733 }

1734 }

1735

1736

1737 Diag(identifierLocs[i],

1740 ? diag::err_undeclared_protocol

1741 : diag::err_unknown_typename))

1742 << identifiers[i];

1743 protocols.clear();

1744 typeArgs.clear();

1745 return;

1746 }

1747

1748

1749

1750 if (numProtocolsResolved == identifiers.size())

1751 return resolvedAsProtocols();

1752

1753

1754 assert(numTypeDeclsResolved == identifiers.size() && "Not all types?");

1755 return resolvedAsTypeDecls();

1756}

1757

1758

1759

1760

1763 if (!ID)

1764 return;

1765

1766 llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;

1767 for (auto *MD : ID->methods())

1768 MethodMap[MD->getSelector()] = MD;

1769

1770 if (MethodMap.empty())

1771 return;

1772 for (const auto *Method : CAT->methods()) {

1773 const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];

1774 if (PrevMethod &&

1775 (PrevMethod->isInstanceMethod() == Method->isInstanceMethod()) &&

1777 Diag(Method->getLocation(), diag::err_duplicate_method_decl)

1778 << Method->getDeclName();

1779 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);

1780 }

1781 }

1782}

1783

1784

1796 IdentPair.second, AtProtocolLoc, PrevDecl);

1797

1800

1803

1804 if (PrevDecl)

1806

1807 DeclsInGroup.push_back(PDecl);

1808 }

1809

1811}

1812

1817 Decl *const *ProtoRefs, unsigned NumProtoRefs,

1823

1824

1825

1826 if (!IDecl ||

1828 diag::err_category_forward_interface,

1829 CategoryName == nullptr)) {

1830

1831

1832

1834 AtInterfaceLoc, ClassLoc, CategoryLoc,

1835 CategoryName, IDecl, typeParamList);

1838

1839 if (!IDecl)

1840 Diag(ClassLoc, diag::err_undef_interface) << ClassName;

1842 return CDecl;

1843 }

1844

1846 Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;

1848 diag::note_implementation_declared);

1849 }

1850

1851 if (CategoryName) {

1852

1855

1856 Diag(CategoryLoc, diag::warn_dup_category_def)

1857 << ClassName << CategoryName;

1858 Diag(Previous->getLocation(), diag::note_previous_definition);

1859 }

1860 }

1861

1862

1863 if (typeParamList) {

1866 SemaRef, prevTypeParamList, typeParamList,

1867 CategoryName ? TypeParamListContext::Category

1868 : TypeParamListContext::Extension))

1869 typeParamList = nullptr;

1870 } else {

1872 diag::err_objc_parameterized_category_nonclass)

1873 << (CategoryName != nullptr)

1874 << ClassName

1876

1877 typeParamList = nullptr;

1878 }

1879 }

1880

1882 ClassLoc, CategoryLoc, CategoryName, IDecl,

1883 typeParamList);

1884

1886

1887

1888

1889

1892

1893 if (NumProtoRefs) {

1895 NumProtoRefs, ProtoLocs);

1897 ProtoLocs, Context);

1898

1901 NumProtoRefs, Context);

1902 }

1903

1906 return CDecl;

1907}

1908

1909

1910

1911

1921 if (!CatIDecl) {

1922

1923

1924 CatIDecl =

1926 ClassLoc, CatLoc, CatName, IDecl,

1927 nullptr);

1929 }

1930 }

1931

1934 ClassLoc, AtCatImplLoc, CatLoc);

1935

1936 if (!IDecl) {

1937 Diag(ClassLoc, diag::err_undef_interface) << ClassName;

1941 diag::err_undef_interface)) {

1943 }

1944

1947

1948

1950

1951

1952

1953 if (IDecl && IDecl->hasAttr()) {

1954 Diag(ClassLoc, diag::err_objc_runtime_visible_category)

1956 }

1957

1958

1959 if (CatIDecl) {

1961 Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName

1962 << CatName;

1964 diag::note_previous_definition);

1966 } else {

1968

1969

1972 }

1973 }

1974

1977 return CDecl;

1978}

1979

1986

1990 if (PrevDecl && !isa(PrevDecl)) {

1991 Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;

1992 Diag(PrevDecl->getLocation(), diag::note_previous_definition);

1993 } else if ((IDecl = dyn_cast_or_null(PrevDecl))) {

1994

1995

1997 diag::warn_undef_interface);

1998 } else {

1999

2000

2001 ObjCInterfaceValidatorCCC CCC{};

2006

2007

2008

2010 Corrected, PDiag(diag::warn_undef_interface_suggest) << ClassName,

2011 false);

2012 } else {

2013 Diag(ClassLoc, diag::warn_undef_interface) << ClassName;

2014 }

2015 }

2016

2017

2019 if (SuperClassname) {

2020

2021 PrevDecl =

2024 if (PrevDecl && !isa(PrevDecl)) {

2025 Diag(SuperClassLoc, diag::err_redefinition_different_kind)

2026 << SuperClassname;

2027 Diag(PrevDecl->getLocation(), diag::note_previous_definition);

2028 } else {

2029 SDecl = dyn_cast_or_null(PrevDecl);

2031 SDecl = nullptr;

2032 if (!SDecl)

2033 Diag(SuperClassLoc, diag::err_undef_superclass)

2034 << SuperClassname << ClassName;

2036

2037

2038 Diag(SuperClassLoc, diag::err_conflicting_super_class)

2040 Diag(SDecl->getLocation(), diag::note_previous_definition);

2041 }

2042 }

2043 }

2044

2045 if (!IDecl) {

2046

2047

2048

2049

2050

2051 IDecl =

2053 ClassName, nullptr,

2054 nullptr, ClassLoc, true);

2057 if (SDecl) {

2060 SuperClassLoc));

2062 } else {

2064 }

2065

2067 } else {

2068

2069

2070

2073 }

2074

2077 ClassLoc, AtClassImplLoc, SuperClassLoc);

2078

2081

2084 return IMPDecl;

2085 }

2086

2087

2089

2090 Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;

2092 diag::note_previous_definition);

2094 } else {

2097

2098

2100 }

2101

2102

2103

2106 Diag(ClassLoc, diag::err_objc_runtime_visible_subclass)

2109 }

2110

2112 return IMPDecl;

2113}

2114

2119 DeclsInGroup.reserve(Decls.size() + 1);

2120

2121 for (unsigned i = 0, e = Decls.size(); i != e; ++i) {

2122 Decl *Dcl = Decls[i];

2123 if (!Dcl)

2124 continue;

2127 DeclsInGroup.push_back(Dcl);

2128 }

2129

2130 DeclsInGroup.push_back(ObjCImpDecl);

2131

2133}

2134

2138 assert(ImpDecl && "missing implementation decl");

2141 if (!IDecl)

2142 return;

2143

2144

2145

2148

2149 for (unsigned i = 0, e = numIvars; i != e; ++i) {

2151

2152

2153

2154

2157 ImpDecl->addDecl(ivars[i]);

2158 }

2159

2160 return;

2161 }

2162

2163 if (numIvars == 0)

2164 return;

2165

2166 assert(ivars && "missing @implementation ivars");

2169 Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use);

2170 for (unsigned i = 0; i < numIvars; i++) {

2174 Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);

2175 Diag(ClsIvar->getLocation(), diag::note_previous_definition);

2176 continue;

2177 }

2178

2181 CDecl->getIvarDecl(ImplIvar->getIdentifier())) {

2182 Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);

2183 Diag(ClsExtIvar->getLocation(), diag::note_previous_definition);

2184 continue;

2185 }

2186 }

2187

2190 ImpDecl->addDecl(ImplIvar);

2191 }

2192 return;

2193 }

2194

2195

2196

2197 unsigned j = 0;

2200 for (; numIvars > 0 && IVI != IVE; ++IVI) {

2203 assert (ImplIvar && "missing implementation ivar");

2204 assert (ClsIvar && "missing class ivar");

2205

2206

2208 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)

2211 Diag(ClsIvar->getLocation(), diag::note_previous_definition);

2215 diag::err_conflicting_ivar_bitwidth)

2218 diag::note_previous_definition);

2219 }

2220

2222 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)

2224 Diag(ClsIvar->getLocation(), diag::note_previous_definition);

2225 }

2226 --numIvars;

2227 }

2228

2229 if (numIvars > 0)

2230 Diag(ivars[j]->getLocation(), diag::err_inconsistent_ivar_count);

2231 else if (IVI != IVE)

2232 Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);

2233}

2234

2236

2238}

2239

2242 unsigned DiagID,

2243 NamedDecl *NeededFor = nullptr) {

2245 return;

2246

2247

2248

2249

2250

2251

2252 {

2255 B << method;

2256 if (NeededFor)

2257 B << NeededFor;

2258

2259

2260 std::string FixItStr;

2261 llvm::raw_string_ostream Out(FixItStr);

2263 Out << " {\n}\n\n";

2264

2267 }

2268

2269

2271 if (MethodLoc.isValid())

2272 S.Diag(MethodLoc, diag::note_method_declared_at) << method;

2273}

2274

2275

2276

2277

2278

2279

2280

2281

2282

2283

2284

2285

2286

2287

2288

2289

2290

2291

2292

2293

2294

2295

2296

2297

2298

2299

2300

2301

2302

2303

2304

2305

2306

2307

2311 bool rejectId) {

2312

2313 if (rejectId && B->isObjCIdType()) return false;

2314

2315

2316

2317

2318

2322 }

2323

2324

2325

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2336

2338}

2339

2342}

2343

2344

2348 (y & ~Decl::OBJC_TQ_CSNullability);

2349}

2350

2354 bool IsProtocolMethodDecl,

2355 bool IsOverridingMode,

2356 bool Warn) {

2357 if (IsProtocolMethodDecl &&

2360 if (Warn) {

2362 (IsOverridingMode

2363 ? diag::warn_conflicting_overriding_ret_type_modifiers

2364 : diag::warn_conflicting_ret_type_modifiers))

2367 S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)

2369 }

2370 else

2371 return false;

2372 }

2373 if (Warn && IsOverridingMode &&

2374 !isa(MethodImpl->getDeclContext()) &&

2377 false)) {

2381 diag::warn_conflicting_nullability_attr_overriding_ret_types)

2388 S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration);

2389 }

2390

2393 return true;

2394 if (!Warn)

2395 return false;

2396

2397 unsigned DiagID =

2398 IsOverridingMode ? diag::warn_conflicting_overriding_ret_types

2399 : diag::warn_conflicting_ret_types;

2400

2401

2402

2407

2408

2409

2410

2412 return false;

2413

2414 DiagID =

2415 IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types

2416 : diag::warn_non_covariant_ret_types;

2417 }

2418 }

2419

2425 ? diag::note_previous_declaration

2426 : diag::note_previous_definition)

2428 return false;

2429}

2430

2436 bool IsProtocolMethodDecl,

2437 bool IsOverridingMode,

2438 bool Warn) {

2439 if (IsProtocolMethodDecl &&

2442 if (Warn) {

2443 if (IsOverridingMode)

2445 diag::warn_conflicting_overriding_param_modifiers)

2449 diag::warn_conflicting_param_modifiers)

2452 S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)

2454 }

2455 else

2456 return false;

2457 }

2458

2461 if (Warn && IsOverridingMode &&

2462 !isa(MethodImpl->getDeclContext()) &&

2465 diag::warn_conflicting_nullability_attr_overriding_param_types)

2472 S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration);

2473 }

2475 return true;

2476

2477 if (!Warn)

2478 return false;

2479 unsigned DiagID =

2480 IsOverridingMode ? diag::warn_conflicting_overriding_param_types

2481 : diag::warn_conflicting_param_types;

2482

2483

2484

2489

2490

2491

2492

2494 return false;

2495

2496 DiagID =

2497 IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types

2498 : diag::warn_non_contravariant_param_types;

2499 }

2500 }

2501

2504 << MethodImpl->getDeclName() << IfaceTy << ImplTy;

2506 (IsOverridingMode ? diag::note_previous_declaration

2507 : diag::note_previous_definition))

2509 return false;

2510}

2511

2512

2513

2518 if (implFamily == declFamily) return false;

2519

2520

2521

2522

2524

2525

2526 if (impl->isInvalidDecl() || decl->isInvalidDecl()) return true;

2527

2530 unsigned errorID = diag::err_arc_lost_method_convention;

2531 unsigned noteID = diag::note_arc_lost_method_convention;

2532 if (declFamily == OMF_None) {

2533 unmatched = decl;

2534 family = implFamily;

2535 errorID = diag::err_arc_gained_method_convention;

2536 noteID = diag::note_arc_gained_method_convention;

2537 }

2538

2539

2540 enum FamilySelector {

2541 F_alloc, F_copy, F_mutableCopy = F_copy, F_init, F_new

2542 };

2543 FamilySelector familySelector = FamilySelector();

2544

2545 switch (family) {

2546 case OMF_None: llvm_unreachable("logic error, no method convention");

2556

2557

2558 return false;

2559

2560 case OMF_init: familySelector = F_init; break;

2561 case OMF_alloc: familySelector = F_alloc; break;

2562 case OMF_copy: familySelector = F_copy; break;

2563 case OMF_mutableCopy: familySelector = F_mutableCopy; break;

2564 case OMF_new: familySelector = F_new; break;

2565 }

2566

2567 enum ReasonSelector { R_NonObjectReturn, R_UnrelatedReturn };

2568 ReasonSelector reasonSelector;

2569

2570

2571

2573 reasonSelector = R_UnrelatedReturn;

2574 } else {

2575 reasonSelector = R_NonObjectReturn;

2576 }

2577

2578 S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector);

2579 S.Diag(decl->getLocation(), noteID) << int(familySelector) << int(reasonSelector);

2580

2581 return true;

2582}

2583

2586 bool IsProtocolMethodDecl) {

2589 return;

2590

2592 IsProtocolMethodDecl, false, true);

2593

2597 IM != EM && IF != EF; ++IM, ++IF) {

2599 IsProtocolMethodDecl, false, true);

2600 }

2601

2604 diag::warn_conflicting_variadic);

2605 Diag(MethodDecl->getLocation(), diag::note_previous_declaration);

2606 }

2607}

2608

2611 bool IsProtocolMethodDecl) {

2612

2614 true, true);

2615

2619 IM != EM && IF != EF; ++IM, ++IF) {

2621 IsProtocolMethodDecl, true, true);

2622 }

2623

2626 diag::warn_conflicting_overriding_variadic);

2627 Diag(Overridden->getLocation(), diag::note_previous_declaration);

2628 }

2629}

2630

2631

2632

2635 bool IsProtocolMethodDecl) {

2637

2638

2639

2642 return;

2643

2644

2645 if (MethodDecl->hasAttr() ||

2646 MethodDecl->hasAttr())

2647 return;

2648

2650 IsProtocolMethodDecl, false, false);

2655 IM != EM && IF != EF; ++IM, ++IF) {

2657 *IF, IsProtocolMethodDecl, false, false);

2659 break;

2660 }

2666

2669 diag::warn_category_method_impl_match);

2670 Diag(MethodDecl->getLocation(), diag::note_method_declared_at)

2672 }

2673}

2674

2675

2676

2677

2678

2679

2680

2683

2686 if (PDecl->hasAttr())

2688 for (const auto *PI : PDecl->protocols())

2690}

2691

2692

2693

2694

2697 if (!Super)

2698 return;

2699

2702

2704}

2705

2706

2707

2714 : dyn_cast(CDecl);

2715 assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");

2716

2719

2720

2721

2722

2723

2724

2725

2726

2727

2728

2729

2730

2731 if (PDecl->hasAttr()) {

2732 if (!ProtocolsExplictImpl) {

2735 }

2736 if (ProtocolsExplictImpl->contains(PDecl->getIdentifier()))

2737 return;

2738

2739

2740

2741 Super = nullptr;

2742 }

2743

2745

2746

2747

2748

2749

2750

2751

2754 if (InsMap.count(fISelector))

2755

2756

2758 }

2759

2760

2764

2765

2766

2767

2768

2769

2770

2771 if (!NSIDecl)

2773 if (method->getImplementationControl() !=

2775 !method->isPropertyAccessor() &&

2776 !InsMap.count(method->getSelector()) &&

2778 method->getSelector(), true ,

2779 false , true ,

2780 nullptr ))) {

2781

2782

2783

2784

2785

2786

2787

2788

2789

2791 method->getSelector(), true ,

2792 true , false ))

2793 if (C || MethodInClass->isPropertyAccessor())

2794 continue;

2795 unsigned DIAG = diag::warn_unimplemented_protocol_method;

2798 }

2799 }

2800 }

2801

2803 if (method->getImplementationControl() !=

2805 !ClsMap.count(method->getSelector()) &&

2807 method->getSelector(), false ,

2808 false ,

2809 true , nullptr ))) {

2810

2811 if (C && IDecl->lookupMethod(method->getSelector(),

2812 false ,

2813 true ,

2814 false ))

2815 continue;

2816

2817 unsigned DIAG = diag::warn_unimplemented_protocol_method;

2820 }

2821 }

2822 }

2823

2824 for (auto *PI : PDecl->protocols())

2826 ProtocolsExplictImpl);

2827}

2828

2829

2830

2831

2835 ObjCContainerDecl *CDecl, bool &IncompleteImpl, bool ImmediateClass,

2836 bool WarnCategoryMethodImpl) {

2837

2838

2840 if (!InsMapSeen.insert(I->getSelector()).second)

2841 continue;

2842 if (!I->isPropertyAccessor() &&

2843 !InsMap.count(I->getSelector())) {

2844 if (ImmediateClass)

2846 diag::warn_undef_method_impl);

2847 continue;

2848 } else {

2851 assert(CDecl->getInstanceMethod(I->getSelector(), true) &&

2852 "Expected to find the method through lookup as well");

2853

2854 if (ImpMethodDecl) {

2855

2857 continue;

2858 if (!WarnCategoryMethodImpl)

2860 isa(CDecl));

2861 else if (!I->isPropertyAccessor())

2863 }

2864 }

2865 }

2866

2867

2868

2870 if (!ClsMapSeen.insert(I->getSelector()).second)

2871 continue;

2872 if (!I->isPropertyAccessor() &&

2873 !ClsMap.count(I->getSelector())) {

2874 if (ImmediateClass)

2876 diag::warn_undef_method_impl);

2877 } else {

2880 assert(CDecl->getClassMethod(I->getSelector(), true) &&

2881 "Expected to find the method through lookup as well");

2882

2883 if (ImpMethodDecl) {

2884

2886 continue;

2887 if (!WarnCategoryMethodImpl)

2889 isa(CDecl));

2890 else if (!I->isPropertyAccessor())

2892 }

2893 }

2894 }

2895

2896 if (ObjCProtocolDecl *PD = dyn_cast (CDecl)) {

2897

2898

2899 for (auto *PI : PD->protocols())

2901 IMPDecl, PI, IncompleteImpl, false,

2902 WarnCategoryMethodImpl);

2903 }

2904

2905 if (ObjCInterfaceDecl *I = dyn_cast (CDecl)) {

2906

2907

2908

2909 if (!WarnCategoryMethodImpl) {

2910 for (auto *Cat : I->visible_categories())

2912 IMPDecl, Cat, IncompleteImpl,

2913 ImmediateClass && Cat->IsClassExtension(),

2914 WarnCategoryMethodImpl);

2915 } else {

2916

2917 for (auto *Ext : I->visible_extensions())

2919 IMPDecl, Ext, IncompleteImpl, false,

2920 WarnCategoryMethodImpl);

2921 }

2922

2923

2924 for (auto *PI : I->all_referenced_protocols())

2926 IMPDecl, PI, IncompleteImpl, false,

2927 WarnCategoryMethodImpl);

2928

2929

2930

2931 if (!WarnCategoryMethodImpl && I->getSuperClass())

2933 IMPDecl,

2934 I->getSuperClass(), IncompleteImpl, false);

2935 }

2936}

2937

2938

2939

2940

2943

2945 if (!CatDecl)

2946 return;

2948 if (!IDecl)

2949 return;

2952

2954 Selector Sel = I->getSelector();

2955

2956

2957

2958 if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true))

2959 continue;

2960 InsMap.insert(Sel);

2961 }

2962

2963 for (const auto *I : CatIMPDecl->class_methods()) {

2964 Selector Sel = I->getSelector();

2965 if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false))

2966 continue;

2967 ClsMap.insert(Sel);

2968 }

2969 if (InsMap.empty() && ClsMap.empty())

2970 return;

2971

2973 bool IncompleteImpl = false;

2975 CatIMPDecl, IDecl,

2976 IncompleteImpl, false,

2977 true );

2978}

2979

2982 bool IncompleteImpl) {

2984

2985

2987 InsMap.insert(I->getSelector());

2988

2989

2990 for (const auto *PImpl : IMPDecl->property_impls()) {

2991

2993 continue;

2994

2995 const auto *P = PImpl->getPropertyDecl();

2996 if (P) continue;

2997

2998 InsMap.insert(P->getGetterName());

2999 if (P->getSetterName().isNull())

3000 InsMap.insert(P->getSetterName());

3001 }

3002

3003

3004

3005

3006 if (const ObjCInterfaceDecl *IDecl = dyn_cast(CDecl)) {

3007 bool SynthesizeProperties = getLangOpts().ObjCDefaultSynthProperties &&

3009 !IDecl->isObjCRequiresPropertyDefs();

3011 }

3012

3013

3015

3018 ClsMap.insert(I->getSelector());

3019

3020

3021

3024 IMPDecl, CDecl,

3025 IncompleteImpl, true);

3026

3027

3028

3030 dyn_cast(IMPDecl))

3032

3033

3034

3035

3036

3037

3039

3040 if (ObjCInterfaceDecl *I = dyn_cast (CDecl)) {

3041 for (auto *PI : I->all_referenced_protocols())

3043 ClsMap, I, ExplicitImplProtocols);

3044 } else if (ObjCCategoryDecl *C = dyn_cast(CDecl)) {

3045

3046

3047 if (C->IsClassExtension()) {

3048 for (auto *P : C->protocols())

3050 ClsMap, CDecl, ExplicitImplProtocols);

3052 false);

3053 }

3054 } else

3055 llvm_unreachable("invalid ObjCContainerDecl type.");

3056}

3057

3061 unsigned NumElts) {

3064 for (unsigned i = 0; i != NumElts; ++i) {

3065

3069 if (PrevDecl && !isa(PrevDecl)) {

3070

3071

3072

3073

3074

3075

3076

3077 TypedefNameDecl *TDD = dyn_cast(PrevDecl);

3079 Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];

3080 Diag(PrevDecl->getLocation(), diag::note_previous_definition);

3081 } else {

3082

3083

3084

3085

3087 Diag(AtClassLoc, diag::warn_forward_class_redefinition)

3088 << IdentList[i];

3089 Diag(PrevDecl->getLocation(), diag::note_previous_definition);

3090 continue;

3091 }

3092 }

3093 }

3094

3095

3097 = dyn_cast_or_null(PrevDecl);

3098

3100 if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {

3101

3102

3103

3104

3105

3106

3107

3108

3109

3110

3111

3112

3114 }

3115

3116

3117

3119 if (PrevIDecl && TypeParams) {

3121

3123 SemaRef, PrevTypeParams, TypeParams,

3124 TypeParamListContext::ForwardDeclaration)) {

3125 TypeParams = nullptr;

3126 }

3128

3129 Diag(IdentLocs[i], diag::err_objc_parameterized_forward_class)

3130 << ClassName

3132 Diag(Def->getLocation(), diag::note_defined_here)

3133 << ClassName;

3134

3135 TypeParams = nullptr;

3136 }

3137 }

3138

3141 PrevIDecl, IdentLocs[i]);

3143

3144 if (PrevIDecl)

3146

3149 DeclsInGroup.push_back(IDecl);

3150 }

3151

3153}

3154

3157 const Type *left, const Type *right);

3158

3162 const Type *left =

3164 const Type *right =

3166

3167 if (left == right) return true;

3168

3169

3171 return false;

3172

3174

3175

3176

3177

3178

3182 return false;

3183

3185 return false;

3186

3187

3188

3189

3190

3191 if (isa(left)) return isa(right);

3192 if (isa(right)) return false;

3193

3194

3195

3196

3197

3200

3201

3202

3211

3212

3213

3214

3215 return (leftSK == rightSK);

3216}

3217

3220 const Type *lt, const Type *rt) {

3221 assert(lt && rt && lt != rt);

3222

3223 if (!isa(lt) || !isa(rt)) return false;

3224 RecordDecl *left = cast(lt)->getDecl();

3225 RecordDecl *right = cast(rt)->getDecl();

3226

3227

3228 if (left->isUnion() != right->isUnion()) return false;

3229

3230

3231 if ((isa(left) && !cast(left)->isPOD()) ||

3232 (isa(right) && !cast(right)->isPOD()))

3233 return false;

3234

3235

3239 return false;

3240

3242 return false;

3243

3244

3247 for (; li != le && ri != re; ++li, ++ri) {

3248 if (matchTypes(Context, strategy, li->getType(), ri->getType()))

3249 return false;

3250 }

3251 return (li == le && ri == re);

3252}

3253

3254

3255

3256

3263 return false;

3264

3265

3267 return false;

3268

3270 return false;

3271

3273 (left->hasAttr()

3274 != right->hasAttr() ||

3275 left->hasAttr()

3276 != right->hasAttr()))

3277 return false;

3278

3282

3283 for (; li != le && ri != re; ++li, ++ri) {

3284 assert(ri != right->param_end() && "Param mismatch");

3285 const ParmVarDecl *lparm = *li, *rparm = *ri;

3286

3287 if (matchTypes(Context, strategy, lparm->getType(), rparm->getType()))

3288 return false;

3289

3291 lparm->hasAttr() != rparm->hasAttr())

3292 return false;

3293 }

3294 return true;

3295}

3296

3299 auto *MethodProtocol = dyn_cast(Method->getDeclContext());

3300 auto *MethodInListProtocol =

3301 dyn_cast(MethodInList->getDeclContext());

3302

3303

3304 if ((MethodProtocol && !MethodInListProtocol) ||

3305 (!MethodProtocol && MethodInListProtocol))

3306 return false;

3307

3308 if (MethodProtocol && MethodInListProtocol)

3309 return true;

3310

3314 return MethodInterface == MethodInListInterface;

3315}

3316

3319

3320

3322 dyn_cast(Method->getDeclContext()))

3323 if (!CD->IsClassExtension() && List->getBits() < 2)

3324 List->setBits(List->getBits() + 1);

3325

3326

3327 if (List->getMethod() == nullptr) {

3328 List->setMethod(Method);

3329 List->setNext(nullptr);

3330 return;

3331 }

3332

3333

3334

3337 for (; List; Previous = List, List = List->getNext()) {

3338

3340 continue;

3341

3343 List->getMethod());

3344

3345

3346

3347

3348

3349

3350

3351

3352

3353

3354 if (!SameDeclaration ||

3356

3357

3358

3360 List->setHasMoreThanOneDecl(true);

3361

3362

3363

3364 if (Method->isDeprecated() && SameDeclaration &&

3365 !ListWithSameDeclaration && !List->getMethod()->isDeprecated())

3366 ListWithSameDeclaration = List;

3367

3368 if (Method->isUnavailable() && SameDeclaration &&

3369 !ListWithSameDeclaration &&

3370 List->getMethod()->getAvailability() < AR_Deprecated)

3371 ListWithSameDeclaration = List;

3372 continue;

3373 }

3374

3376

3377

3380 else {

3381

3382

3383

3384

3385 List->setHasMoreThanOneDecl(true);

3386 }

3387

3388

3389

3392 List->setMethod(Method);

3393 }

3394

3395

3398 List->setMethod(Method);

3399 }

3400

3401 return;

3402 }

3403

3404

3405

3407

3408

3409 if (ListWithSameDeclaration) {

3410 auto *List = new (Mem) ObjCMethodList(*ListWithSameDeclaration);

3411

3412 ListWithSameDeclaration->setMethod(Method);

3413 ListWithSameDeclaration->setNext(List);

3414 return;

3415 }

3416

3418}

3419

3420

3421

3425}

3426

3429 return;

3431}

3432

3433void SemaObjC::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,

3434 bool instance) {

3435

3436 if (cast(Method->getDeclContext())->isInvalidDecl())

3437 return;

3438

3441

3443

3445

3446 ObjCMethodList &Entry = instance ? Lists.first : Lists.second;

3448}

3449

3450

3451

3452

3453

3454

3458 return false;

3459

3461 return false;

3462

3465 return false;

3466

3467

3468

3470}

3471

3472

3475 if (!TypeBound)

3476 return true;

3477

3479

3480 return true;

3481

3482 auto *BoundInterface = TypeBound->getInterface();

3483 assert(BoundInterface && "unexpected object type!");

3484

3485

3486

3487 auto *MethodProtocol = dyn_cast(Method->getDeclContext());

3488 if (MethodProtocol) {

3489 return true;

3490 }

3491

3492

3493

3495

3496

3497

3498 return MethodInterface == BoundInterface ||

3499 MethodInterface->isSuperClassOf(BoundInterface) ||

3500 BoundInterface->isSuperClassOf(MethodInterface);

3501 }

3502 llvm_unreachable("unknown method context");

3503}

3504

3505

3506

3509 bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound) {

3512

3513 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);

3515 return false;

3516

3517

3518 ObjCMethodList &MethList = InstanceFirst ? Pos->second.first :

3519 Pos->second.second;

3521 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible()) {

3523 Methods.push_back(M->getMethod());

3524 }

3525

3526

3527 if (!Methods.empty())

3528 return Methods.size() > 1;

3529

3530 if (!CheckTheOther)

3531 return false;

3532

3533

3534 ObjCMethodList &MethList2 = InstanceFirst ? Pos->second.second :

3535 Pos->second.first;

3537 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible()) {

3539 Methods.push_back(M->getMethod());

3540 }

3541

3542 return Methods.size() > 1;

3543}

3544

3548

3550 FilteredMethods.push_back(BestMethod);

3551

3552 for (auto *M : Methods)

3553 if (M != BestMethod && !M->hasAttr())

3554 FilteredMethods.push_back(M);

3555

3556 if (FilteredMethods.size() > 1)

3558 receiverIdOrClass);

3559

3560 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);

3561

3562

3564 return true;

3566 BestMethod->isInstanceMethod() ? Pos->second.first : Pos->second.second;

3568}

3569

3571 bool receiverIdOrClass,

3572 bool instance) {

3575

3576 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);

3578 return nullptr;

3579

3580

3581 ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;

3584 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible())

3585 return M->getMethod();

3586 }

3587 return nullptr;

3588}

3589

3592 bool receiverIdOrClass) {

3593

3594 bool issueDiagnostic = false, issueError = false;

3595

3596

3597

3598 bool strictSelectorMatch =

3599 receiverIdOrClass &&

3602 if (strictSelectorMatch) {

3603 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {

3605 issueDiagnostic = true;

3606 break;

3607 }

3608 }

3609 }

3610

3611

3612

3613

3614 if (!strictSelectorMatch ||

3615 (issueDiagnostic && getLangOpts().ObjCAutoRefCount))

3616 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {

3617

3620 issueDiagnostic = true;

3622 issueError = true;

3623 break;

3624 }

3625 }

3626

3627 if (issueDiagnostic) {

3628 if (issueError)

3629 Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R;

3630 else if (strictSelectorMatch)

3631 Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;

3632 else

3633 Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;

3634

3635 Diag(Methods[0]->getBeginLoc(),

3636 issueError ? diag::note_possibility : diag::note_using)

3637 << Methods[0]->getSourceRange();

3638 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {

3639 Diag(Methods[I]->getBeginLoc(), diag::note_also_found)

3640 << Methods[I]->getSourceRange();

3641 }

3642 }

3643}

3644

3646 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);

3648 return nullptr;

3649

3650 auto &Methods = Pos->second;

3651 for (const ObjCMethodList *Method = &Methods.first; Method;

3652 Method = Method->getNext())

3653 if (Method->getMethod() &&

3654 (Method->getMethod()->isDefined() ||

3656 return Method->getMethod();

3657

3658 for (const ObjCMethodList *Method = &Methods.second; Method;

3659 Method = Method->getNext())

3660 if (Method->getMethod() &&

3661 (Method->getMethod()->isDefined() ||

3663 return Method->getMethod();

3664 return nullptr;

3665}

3666

3667static void

3671 const unsigned MaxEditDistance = 1;

3672 unsigned BestEditDistance = MaxEditDistance + 1;

3674

3675 unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size());

3676 if (MinPossibleEditDistance > 0 &&

3677 Typo.size() / MinPossibleEditDistance < 1)

3678 return;

3679 unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance);

3680 if (EditDistance > MaxEditDistance)

3681 return;

3682 if (EditDistance == BestEditDistance)

3683 BestMethod.push_back(Method);

3684 else if (EditDistance < BestEditDistance) {

3685 BestMethod.clear();

3686 BestMethod.push_back(Method);

3687 }

3688}

3689

3692 if (ObjectType.isNull())

3693 return true;

3695 true ))

3696 return true;

3698 false ) != nullptr;

3699}

3700

3703 unsigned NumArgs = Sel.getNumArgs();

3705 bool ObjectIsId = true, ObjectIsClass = true;

3706 if (ObjectType.isNull())

3707 ObjectIsId = ObjectIsClass = false;

3709 return nullptr;

3712 ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);

3713 ObjectIsId = ObjectIsClass = false;

3714 }

3716 ObjectIsClass = false;

3718 ObjectIsId = false;

3719 else

3720 return nullptr;

3721

3722 for (GlobalMethodPool::iterator b = MethodPool.begin(),

3724

3725 for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())

3726 if (M->getMethod() &&

3727 (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&

3728 (M->getMethod()->getSelector() != Sel)) {

3729 if (ObjectIsId)

3730 Methods.push_back(M->getMethod());

3731 else if (!ObjectIsClass &&

3733 SemaRef, M->getMethod()->getSelector(), ObjectType))

3734 Methods.push_back(M->getMethod());

3735 }

3736

3737 for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())

3738 if (M->getMethod() &&

3739 (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&

3740 (M->getMethod()->getSelector() != Sel)) {

3741 if (ObjectIsClass)

3742 Methods.push_back(M->getMethod());

3743 else if (!ObjectIsId &&

3745 SemaRef, M->getMethod()->getSelector(), ObjectType))

3746 Methods.push_back(M->getMethod());

3747 }

3748 }

3749

3751 for (unsigned i = 0, e = Methods.size(); i < e; i++) {

3754 }

3755 return (SelectedMethods.size() == 1) ? SelectedMethods[0] : nullptr;

3756}

3757

3758

3759

3760

3761

3762

3765 for (auto *Ivar : ID->ivars()) {

3766 if (Ivar->isInvalidDecl())

3767 continue;

3770 if (prevIvar) {

3771 Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;

3772 Diag(prevIvar->getLocation(), diag::note_previous_declaration);

3773 Ivar->setInvalidDecl();

3774 }

3775 }

3776 }

3777}

3778

3779

3782

3783 for (auto ivar = ID->getClassInterface()->all_declared_ivar_begin();

3784 ivar; ivar = ivar->getNextIvar()) {

3785 if (ivar->isInvalidDecl()) continue;

3788 S.Diag(ivar->getLocation(), diag::err_arc_weak_disabled);

3789 } else {

3790 S.Diag(ivar->getLocation(), diag::err_arc_weak_no_runtime);

3791 }

3792 }

3793 }

3794}

3795

3796

3800 return;

3801

3802 for (auto ivar = ID->all_declared_ivar_begin(); ivar;

3803 ivar = ivar->getNextIvar()) {

3804 if (ivar->isInvalidDecl())

3805 continue;

3806 QualType IvarTy = ivar->getType();

3810 S.Diag(ivar->getLocation(), diag::err_flexible_array_arc_retainable);

3811 ivar->setInvalidDecl();

3812 }

3813 }

3814}

3815

3818 case Decl::ObjCInterface:

3820 case Decl::ObjCProtocol:

3822 case Decl::ObjCCategory:

3823 if (cast(SemaRef.CurContext)->IsClassExtension())

3826 case Decl::ObjCImplementation:

3828 case Decl::ObjCCategoryImpl:

3830

3831 default:

3833 }

3834}

3835

3838 return true;

3840 return (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember());

3841}

3842

3847 if ((IntfDecl = dyn_cast(OCD))) {

3848 Ivars = IntfDecl->ivars();

3849 } else if (auto *ImplDecl = dyn_cast(OCD)) {

3850 IntfDecl = ImplDecl->getClassInterface();

3851 Ivars = ImplDecl->ivars();

3852 } else if (auto *CategoryDecl = dyn_cast(OCD)) {

3853 if (CategoryDecl->IsClassExtension()) {

3854 IntfDecl = CategoryDecl->getClassInterface();

3855 Ivars = CategoryDecl->ivars();

3856 }

3857 }

3858

3859

3860 if (!isa(OCD)) {

3861 for (auto *ivar : Ivars) {

3863 S.Diag(ivar->getLocation(), diag::warn_variable_sized_ivar_visibility)

3864 << ivar->getDeclName() << ivar->getType();

3865 }

3866 }

3867 }

3868

3869

3870 if (!IntfDecl)

3871 return;

3872

3873

3876 if (ivar->isInvalidDecl() || !ivar->getNextIvar())

3877 continue;

3878 QualType IvarTy = ivar->getType();

3879 bool IsInvalidIvar = false;

3881 S.Diag(ivar->getLocation(), diag::err_flexible_array_not_at_end)

3882 << ivar->getDeclName() << IvarTy

3883 << llvm::to_underlying(TagTypeKind::Class);

3884 IsInvalidIvar = true;

3886 if (RecordTy->getDecl()->hasFlexibleArrayMember()) {

3887 S.Diag(ivar->getLocation(),

3888 diag::err_objc_variable_sized_type_not_at_end)

3889 << ivar->getDeclName() << IvarTy;

3890 IsInvalidIvar = true;

3891 }

3892 }

3893 if (IsInvalidIvar) {

3894 S.Diag(ivar->getNextIvar()->getLocation(),

3895 diag::note_next_ivar_declaration)

3896 << ivar->getNextIvar()->getSynthesize();

3897 ivar->setInvalidDecl();

3898 }

3899 }

3900

3901

3902

3903

3905 (Ivars.begin() == Ivars.end()) ? nullptr : *Ivars.begin();

3908 while (SuperClass && SuperClass->ivar_empty())

3910 if (SuperClass) {

3911 auto IvarIter = SuperClass->ivar_begin();

3912 std::advance(IvarIter, SuperClass->ivar_size() - 1);

3916 diag::warn_superclass_variable_sized_type_not_at_end)

3919 S.Diag(LastIvar->getLocation(), diag::note_entity_declared_at)

3921 }

3922 }

3923 }

3924}

3925

3928

3931 const llvm::iterator_rangeObjCProtocolList::iterator &Protocols) {

3932 for (auto *PI : Protocols)

3934}

3935

3940

3943 for (auto *MD : PDecl->methods()) {

3944 if (!MD->isPropertyAccessor()) {

3945 if (const auto *CMD =

3946 IDecl->getMethod(MD->getSelector(), MD->isInstanceMethod())) {

3947 if (CMD->isDirectMethod())

3948 DirectMembers.push_back(CMD);

3949 }

3950 }

3951 }

3952 for (auto *PD : PDecl->properties()) {

3953 if (const auto *CPD = IDecl->FindPropertyVisibleInPrimaryClass(

3954 PD->getIdentifier(),

3955 PD->isClassProperty()

3958 if (CPD->isDirectProperty())

3959 DirectMembers.push_back(CPD);

3960 }

3961 }

3962 if (!DirectMembers.empty()) {

3963 S.Diag(CDecl->getLocation(), diag::err_objc_direct_protocol_conformance)

3965 for (const auto *MD : DirectMembers)

3966 S.Diag(MD->getLocation(), diag::note_direct_member_here);

3967 return;

3968 }

3969

3970

3973}

3974

3975

3981 return nullptr;

3982

3983 assert(AtEnd.isValid() && "Invalid location for '@end'");

3984

3986 Decl *ClassDecl = OCD;

3987

3988 bool isInterfaceDeclKind =

3989 isa(ClassDecl) || isa(ClassDecl)

3990 || isa(ClassDecl);

3991 bool checkIdenticalMethods = isa(ClassDecl);

3992

3993

3994

3995

3996

3997 if (auto *OID = dyn_cast(SemaRef.CurContext)) {

3998 for (auto *PropImpl : OID->property_impls()) {

3999 if (auto *Getter = PropImpl->getGetterMethodDecl())

4000 if (Getter->isSynthesizedAccessorStub())

4001 OID->addDecl(Getter);

4002 if (auto *Setter = PropImpl->getSetterMethodDecl())

4003 if (Setter->isSynthesizedAccessorStub())

4004 OID->addDecl(Setter);

4005 }

4006 }

4007

4008

4009 llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;

4010 llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;

4011

4012 for (unsigned i = 0, e = allMethods.size(); i != e; i++ ) {

4014 cast_or_null(allMethods[i]);

4015

4016 if (!Method) continue;

4018

4021 : false;

4022 if ((isInterfaceDeclKind && PrevMethod && match)

4023 || (checkIdenticalMethods && match)) {

4024 Diag(Method->getLocation(), diag::err_duplicate_method_decl)

4026 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);

4028 } else {

4029 if (PrevMethod) {

4033 Diag(Method->getLocation(), diag::warn_duplicate_method_decl)

4035 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);

4036 }

4038

4040 }

4041 } else {

4042

4045 : false;

4046 if ((isInterfaceDeclKind && PrevMethod && match)

4047 || (checkIdenticalMethods && match)) {

4048 Diag(Method->getLocation(), diag::err_duplicate_method_decl)

4050 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);

4052 } else {

4053 if (PrevMethod) {

4057 Diag(Method->getLocation(), diag::warn_duplicate_method_decl)

4059 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);

4060 }

4063 }

4064 }

4065 }

4066 if (isa(ClassDecl)) {

4067

4068 } else if (ObjCCategoryDecl *C = dyn_cast(ClassDecl)) {

4069

4070

4071

4072

4073 if (C->IsClassExtension()) {

4076 }

4077

4079 C->protocols());

4080 }

4081 if (ObjCContainerDecl *CDecl = dyn_cast(ClassDecl)) {

4082 if (CDecl->getIdentifier())

4083

4084

4085

4086 for (auto *I : CDecl->properties())

4088 CDecl->setAtEndRange(AtEnd);

4089 }

4091 IC->setAtEndRange(AtEnd);

4093

4094

4095

4096

4097

4098 for (const auto *Ext : IDecl->visible_extensions()) {

4099 for (const auto *Property : Ext->instance_properties()) {

4100

4102 = IC->FindPropertyImplDecl(Property->getIdentifier(),

4104 if (PIDecl->getPropertyImplementation()

4106 continue;

4107

4108 for (const auto *Ext : IDecl->visible_extensions()) {

4110 Ext->getInstanceMethod(Property->getGetterName()))

4111 GetterMethod->setPropertyAccessor(true);

4112 if (Property->isReadOnly())

4114 = Ext->getInstanceMethod(Property->getSetterName()))

4115 SetterMethod->setPropertyAccessor(true);

4116 }

4117 }

4118 }

4123 if (IDecl->hasDesignatedInitializers())

4127

4128 bool HasRootClassAttr = IDecl->hasAttr();

4129 if (IDecl->getSuperClass() == nullptr) {

4130

4131

4132 if (!HasRootClassAttr) {

4135 Diag(DeclLoc, diag::warn_objc_root_class_missing)

4136 << IDecl->getIdentifier();

4137

4138

4142 ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null(IF);

4143 if (NSObjectDecl && NSObjectDecl->getDefinition()) {

4144 Diag(SuperClassLoc, diag::note_objc_needs_superclass)

4146 } else {

4147 Diag(SuperClassLoc, diag::note_objc_needs_superclass);

4148 }

4149 }

4150 } else if (HasRootClassAttr) {

4151

4152 Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass);

4153 }

4154

4156

4157

4158

4159

4160 if (IDecl->hasAttr() &&

4161 Super->hasAttr()) {

4162 Diag(IC->getLocation(), diag::err_restricted_superclass_mismatch);

4163 Diag(Super->getLocation(), diag::note_class_declared);

4164 }

4165 }

4166

4167 if (IDecl->hasAttr())

4168 Diag(IC->getLocation(), diag::err_implementation_of_class_stub);

4169

4171 while (IDecl->getSuperClass()) {

4173 IDecl = IDecl->getSuperClass();

4174 }

4175 }

4176 }

4179 dyn_cast(ClassDecl)) {

4180 CatImplClass->setAtEndRange(AtEnd);

4181

4182

4183

4184 if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {

4186 = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) {

4188 }

4189 }

4190 } else if (const auto *IntfDecl = dyn_cast(ClassDecl)) {

4192 if (!IntfDecl->hasAttr() &&

4193 Super->hasAttr()) {

4194 Diag(IntfDecl->getLocation(), diag::err_restricted_superclass_mismatch);

4195 Diag(Super->getLocation(), diag::note_class_declared);

4196 }

4197 }

4198

4199 if (IntfDecl->hasAttr() &&

4200 !IntfDecl->hasAttr())

4201 Diag(IntfDecl->getLocation(), diag::err_class_stub_subclassing_mismatch);

4202 }

4204 if (isInterfaceDeclKind) {

4205

4206 for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {

4209 if (VarDecl *VDecl = dyn_cast(*I)) {

4210 if (!VDecl->hasExternalStorage())

4211 Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);

4212 }

4213 }

4214 }

4216

4217 for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {

4220 (*I)->setTopLevelDeclInObjCContainer();

4222 }

4223

4225 return ClassDecl;

4226}

4227

4228

4229

4233}

4234

4235

4236

4237

4242

4243

4244

4245

4248

4249 if (ResultObjectType->isObjCIdType() ||

4250 ResultObjectType->isObjCQualifiedIdType())

4252

4253 if (CurrentClass) {

4255 = ResultObjectType->getInterfaceDecl()) {

4256

4259

4260

4261 if (ResultClass->isSuperClassOf(CurrentClass))

4263 }

4264 } else {

4265

4266

4268 }

4269 }

4270

4272}

4273

4274namespace {

4275

4276

4277class OverrideSearch {

4278public:

4281 bool Recursive;

4282

4283public:

4284 OverrideSearch(Sema &S, const ObjCMethodDecl *method) : Method(method) {

4286

4287

4288

4289 SemaObjC::GlobalMethodPool::iterator it =

4294

4297 return;

4298 }

4300 method->isInstanceMethod() ? it->second.first : it->second.second;

4302

4304 = cast(method->getDeclContext());

4305

4306

4307

4308

4310 dyn_cast(container)) {

4311 searchFromContainer(container);

4314 } else {

4315 searchFromContainer(container);

4316 }

4317 }

4318

4319 typedef decltype(Overridden)::iterator iterator;

4320 iterator begin() const { return Overridden.begin(); }

4321 iterator end() const { return Overridden.end(); }

4322

4323private:

4326

4328#define OBJCCONTAINER(type, base) \

4329 case Decl::type: \

4330 searchFrom(cast<type##Decl>(container)); \

4331 break;

4332#define ABSTRACT_DECL(expansion)

4333#define DECL(type, base) \

4334 case Decl::type:

4335#include "clang/AST/DeclNodes.inc"

4336 llvm_unreachable("not an ObjC container!");

4337 }

4338 }

4339

4342 return;

4343

4344

4345

4347 }

4348

4350

4351

4352

4354 }

4355

4357

4358

4359

4361 search(category);

4364

4365

4368 }

4369 }

4370

4372

4374 return;

4375

4376

4378 search(Cat);

4379

4380

4382 search(super);

4383

4384

4386 }

4387

4389

4390

4393 }

4394

4396 for (const auto *Proto : protocols)

4397 search(Proto);

4398 }

4399

4401

4404 true);

4405

4406

4407 if (meth) {

4408 Overridden.insert(meth);

4409 return;

4410 }

4411

4412

4413

4414

4415

4416 Recursive = true;

4417

4418 searchFromContainer(container);

4419 }

4420};

4421}

4422

4426 const auto *attr = overridden->getAttr();

4427 Diag(method->getLocation(), diag::err_objc_override_direct_method);

4428 Diag(attr->getLocation(), diag::note_previous_declaration);

4430 const auto *attr = method->getAttr();

4431 Diag(attr->getLocation(), diag::err_objc_direct_on_override)

4432 << isa(overridden->getDeclContext());

4433 Diag(overridden->getLocation(), diag::note_previous_declaration);

4434 }

4435}

4436

4441 if (!ObjCMethod)

4442 return;

4443 auto IsMethodInCurrentClass = [CurrentClass](const ObjCMethodDecl *M) {

4444

4445 return M->getClassInterface()->getCanonicalDecl() ==

4447 };

4448

4449 OverrideSearch overrides(SemaRef, ObjCMethod);

4450

4451

4452

4453

4454

4455 bool hasOverriddenMethodsInBaseOrProtocol = false;

4457 if (!hasOverriddenMethodsInBaseOrProtocol) {

4458 if (isa(overridden->getDeclContext()) ||

4459 !IsMethodInCurrentClass(overridden) || overridden->isOverriding()) {

4461 hasOverriddenMethodsInBaseOrProtocol = true;

4462 } else if (isa(ObjCMethod->getDeclContext())) {

4463

4464

4465

4466

4467

4468

4469

4470 GlobalMethodPool::iterator It =

4474 ObjCMethod->isInstanceMethod()? It->second.first: It->second.second;

4475 unsigned CategCount = List.getBits();

4476 if (CategCount > 0) {

4477

4478

4479 if (CategCount > 1 ||

4480 !isa(overridden->getDeclContext())) {

4481 OverrideSearch overrides(SemaRef, overridden);

4483 if (isa(SuperOverridden->getDeclContext()) ||

4484 !IsMethodInCurrentClass(SuperOverridden)) {

4486 hasOverriddenMethodsInBaseOrProtocol = true;

4487 overridden->setOverriding(true);

4488 break;

4489 }

4490 }

4491 }

4492 }

4493 }

4494 }

4495 }

4496

4497

4500

4501

4503

4504 if (ObjCMethod->isImplicit() && overridden->isImplicit())

4505 continue;

4506

4507

4508 if (isa(ObjCMethod->getDeclContext()) ||

4509 isa(ObjCMethod->getDeclContext()))

4511 isa(overridden->getDeclContext()));

4512

4513 if (CurrentClass && overridden->getDeclContext() != CurrentClass &&

4514 isa(overridden->getDeclContext()) &&

4515 !overridden->isImplicit() ) {

4519 PrevE = overridden->param_end();

4520 for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) {

4521 assert(PrevI != overridden->param_end() && "Param mismatch");

4524

4525

4527 Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)

4528 << T1 << T2;

4529 Diag(overridden->getLocation(), diag::note_previous_declaration);

4530 break;

4531 }

4532 }

4533 }

4534 }

4535

4536 ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol);

4537}

4538

4539

4540

4543 bool usesCSKeyword,

4546 bool prevUsesCSKeyword) {

4547

4548 auto nullability = type->getNullability();

4550

4551

4552 if (nullability.has_value() == prevNullability.has_value()) {

4553

4554 if (!nullability)

4555 return type;

4556

4557

4558 if (*nullability == *prevNullability)

4559 return type;

4560

4561

4562 S.Diag(loc, diag::err_nullability_conflicting)

4565 return type;

4566 }

4567

4568

4569 if (nullability)

4570 return type;

4571

4572

4574}

4575

4576

4577

4578

4582

4583 if (prevMethod->hasAttr() &&

4584 !method->hasAttr()) {

4585

4587 ObjCRequiresSuperAttr::CreateImplicit(S.Context,

4589 }

4590

4591

4601

4602

4603 unsigned numParams = method->param_size();

4604 unsigned numPrevParams = prevMethod->param_size();

4605 for (unsigned i = 0, n = std::min(numParams, numPrevParams); i != n; ++i) {

4608

4609

4616 param->setType(newParamType);

4617 }

4618}

4619

4620

4621

4625 llvm::Triple::x86 &&

4626 "x86-specific check invoked for a different target");

4630 if (P->getType()->isVectorType()) {

4631 Loc = P->getBeginLoc();

4632 T = P->getType();

4633 break;

4634 }

4635 }

4640 } else

4641 return;

4642 }

4643

4644

4645

4647 VersionTuple AcceptedInVersion;

4648 if (Triple.getOS() == llvm::Triple::IOS)

4649 AcceptedInVersion = VersionTuple(9);

4650 else if (Triple.isMacOSX())

4651 AcceptedInVersion = VersionTuple(10, 11);

4652 else

4653 return;

4655 AcceptedInVersion)

4656 return;

4657 SemaRef.Diag(Loc, diag::err_objc_method_unsupported_param_ret_type)

4659 : 0)

4660 << (Triple.isMacOSX() ? "macOS 10.11" : "iOS 9");

4661}

4662

4665 CD->hasAttr()) {

4668 }

4669}

4670

4676 bool diagnosed = false;

4677

4679 if (diagnosed || IMD->isImplicit())

4680 return;

4681 if (Method->isDirectMethod() || IMD->isDirectMethod()) {

4682 S.Diag(Method->getLocation(), diag::err_objc_direct_duplicate_decl)

4683 << Method->isDirectMethod() << 0 << IMD->isDirectMethod()

4685 S.Diag(IMD->getLocation(), diag::note_previous_declaration);

4686 diagnosed = true;

4687 }

4688 };

4689

4690

4691

4692

4693

4694

4695

4696

4697

4698

4699

4700

4701

4702

4703 if (auto *IMD = IDecl->getMethod(Sel, isInstance))

4704 diagClash(IMD);

4706 if (Impl != ImpDecl)

4708 diagClash(IMD);

4709

4711 if (auto *IMD = Cat->getMethod(Sel, isInstance))

4712 diagClash(IMD);

4713 else if (auto CatImpl = Cat->getImplementation())

4714 if (CatImpl != ImpDecl)

4715 if (auto *IMD = Cat->getMethod(Sel, isInstance))

4716 diagClash(IMD);

4717}

4718

4721 int ParamIndex,

4722 bool MethodDefinition) {

4726

4727 if (!ArgInfo.Type) {

4729 DI = nullptr;

4730 } else {

4732 }

4739 if (S->isDeclScope(PrevDecl)) {

4741 (MethodDefinition ? diag::warn_method_param_redefinition

4742 : diag::warn_method_param_declaration))

4743 << ArgInfo.Name;

4744 Diag(PrevDecl->getLocation(), diag::note_previous_declaration);

4745 }

4746 }

4749

4750

4751

4752

4759

4760

4763 if (Param->hasAttr()) {

4764 Diag(Param->getLocation(), diag::err_block_on_nonlocal);

4766 }

4767

4768 S->AddDecl(Param);

4770 return Param;

4771}

4772

4777

4778

4780 unsigned CNumArgs,

4782 bool isVariadic, bool MethodDefinition) {

4784

4786 Diag(MethodLoc, diag::err_missing_method_context);

4787 return nullptr;

4788 }

4789

4792

4793 bool HasRelatedResultType = false;

4795 if (ReturnType) {

4797

4799 return nullptr;

4800

4801 QualType bareResultType = resultDeclType;

4803 HasRelatedResultType = (bareResultType == Context.getObjCInstanceType());

4804 } else {

4806 Diag(MethodLoc, diag::warn_missing_method_return_type)

4808 }

4809

4811 Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo,

4813 false, false,

4814 false, false,

4815 MethodDeclKind == tok::objc_optional

4818 HasRelatedResultType);

4819

4821 for (unsigned I = 0; I < Sel.getNumArgs(); ++I) {

4825 Params.push_back(Param);

4826 }

4827

4828 for (unsigned i = 0, e = CNumArgs; i != e; ++i) {

4829 ParmVarDecl *Param = cast(CParamInfo[i].Param);

4831 if (ArgType.isNull())

4833 else

4834

4836

4838 Params.push_back(Param);

4839 }

4840

4841 ObjCMethod->setMethodParams(Context, Params, SelectorLocs);

4844

4848

4849

4851 if (ObjCImplDecl *ImpDecl = dyn_cast(ClassDecl)) {

4852 if (MethodType == tok::minus) {

4853 PrevMethod = ImpDecl->getInstanceMethod(Sel);

4854 ImpDecl->addInstanceMethod(ObjCMethod);

4855 } else {

4856 PrevMethod = ImpDecl->getClassMethod(Sel);

4857 ImpDecl->addClassMethod(ObjCMethod);

4858 }

4859

4860

4861

4862

4863

4864

4866 if (auto *Setter = PropertyImpl->getSetterMethodDecl())

4867 if (Setter->getSelector() == Sel &&

4868 Setter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) {

4869 assert(Setter->isSynthesizedAccessorStub() && "autosynth stub expected");

4870 PropertyImpl->setSetterMethodDecl(ObjCMethod);

4871 }

4872 if (auto *Getter = PropertyImpl->getGetterMethodDecl())

4873 if (Getter->getSelector() == Sel &&

4874 Getter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) {

4875 assert(Getter->isSynthesizedAccessorStub() && "autosynth stub expected");

4876 PropertyImpl->setGetterMethodDecl(ObjCMethod);

4877 break;

4878 }

4879 }

4880

4881

4882

4883

4884

4885

4886

4890 const auto *attr = CanonicalMD->getAttr();

4892 ObjCDirectAttr::CreateImplicit(Context, attr->getLocation()));

4893 }

4894 }

4895

4896

4897

4899 if (auto *IMD = IDecl->lookupMethod(ObjCMethod->getSelector(),

4902

4903

4904

4905

4906

4907

4908

4909

4910

4911

4912

4913

4914

4915

4916

4917

4918

4919 if (IDecl == IMD->getClassInterface()) {

4920 auto diagContainerMismatch = [&] {

4921 int decl = 0, impl = 0;

4922

4923 if (auto *Cat = dyn_cast(IMD->getDeclContext()))

4924 decl = Cat->IsClassExtension() ? 1 : 2;

4925

4926 if (isa(ImpDecl))

4927 impl = 1 + (decl != 0);

4928

4930 diag::err_objc_direct_impl_decl_mismatch)

4931 << decl << impl;

4932 Diag(IMD->getLocation(), diag::note_previous_declaration);

4933 };

4934

4936 const auto *attr = ObjCMethod->getAttr();

4938 diagContainerMismatch();

4939 } else if (!IMD->isDirectMethod()) {

4940 Diag(attr->getLocation(), diag::err_objc_direct_missing_on_decl);

4941 Diag(IMD->getLocation(), diag::note_previous_declaration);

4942 }

4943 } else if (IMD->isDirectMethod()) {

4944 const auto *attr = IMD->getAttr();

4946 diagContainerMismatch();

4947 } else {

4949 ObjCDirectAttr::CreateImplicit(Context, attr->getLocation()));

4950 }

4951 }

4952 }

4953

4954

4955 if (isa(ImpDecl) && IMD->isOverriding() &&

4957 Diag(ObjCMethod->getLocation(), diag::warn_dealloc_in_category)

4959 }

4960 } else {

4963 }

4964

4965

4966

4967

4968 for (auto *C : IDecl->visible_categories())

4969 for (auto &P : C->protocols())

4970 if (auto *IMD = P->lookupMethod(ObjCMethod->getSelector(),

4972 assert(ObjCMethod->parameters().size() ==

4973 IMD->parameters().size() &&

4974 "Methods have different number of parameters");

4975 auto OI = IMD->param_begin(), OE = IMD->param_end();

4977 for (; OI != OE; ++OI, ++NI)

4979 }

4980 }

4981 } else {

4982 if (!isa(ClassDecl)) {

4984

4985 ObjCInterfaceDecl *IDecl = dyn_cast(ClassDecl);

4986 if (!IDecl)

4987 IDecl = cast(ClassDecl)->getClassInterface();

4988

4989

4990

4991 if (IDecl)

4993 }

4994

4995 cast(ClassDecl)->addDecl(ObjCMethod);

4996 }

4997

4998 if (PrevMethod) {

4999

5000 Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)

5002 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);

5004 return ObjCMethod;

5005 }

5006

5007

5008

5009

5010 ObjCInterfaceDecl *CurrentClass = dyn_cast(ClassDecl);

5011 if (!CurrentClass) {

5012 if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl))

5013 CurrentClass = Cat->getClassInterface();

5014 else if (ObjCImplDecl *Impl = dyn_cast(ClassDecl))

5015 CurrentClass = Impl->getClassInterface();

5017 = dyn_cast(ClassDecl))

5018 CurrentClass = CatImpl->getClassInterface();

5019 }

5020

5023

5025

5026 bool ARCError = false;

5029

5030

5033 getLangOpts().ObjCInferRelatedResultType) {

5034 bool InferRelatedResultType = false;

5045 break;

5046

5049 InferRelatedResultType = ObjCMethod->isClassMethod();

5050 break;

5051

5057 break;

5058 }

5059

5060 if (InferRelatedResultType &&

5063 }

5064

5065 if (MethodDefinition &&

5068

5069

5070

5071 if (const auto *attr = ObjCMethod->getAttr()) {

5074 Diag(attr->getLocation(), diag::warn_availability_on_static_initializer)

5075 << 0;

5076 ObjCMethod->dropAttr();

5077 }

5078 }

5079

5080

5082

5084

5085 return ObjCMethod;

5086}

5087

5089

5090

5092 return false;

5093

5094

5095

5096 if (isa(

5098 return false;

5099

5100 Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);

5102

5103 return true;

5104}

5105

5106

5107

5112

5115 Diag(DeclStart, diag::err_undef_interface) << ClassName;

5116 return;

5117 }

5119 Diag(DeclStart, diag::err_atdef_nonfragile_interface);

5120 return;

5121 }

5122

5123

5126

5127 for (unsigned i = 0; i < Ivars.size(); i++) {

5131 ID->getLocation(),

5132 ID->getLocation(),

5133 ID->getIdentifier(), ID->getType(),

5134 ID->getBitWidth());

5135 Decls.push_back(FD);

5136 }

5137

5138

5140 D != Decls.end(); ++D) {

5141 FieldDecl *FD = cast(*D);

5145 Record->addDecl(FD);

5146 }

5147}

5148

5149

5156

5157

5158

5159

5161 Diag(IdLoc, diag::err_arg_with_address_space);

5163 }

5164

5165

5166

5168

5170

5173 Diag(IdLoc, diag::err_illegal_qualifiers_on_catch_parm);

5175

5178 Diag(IdLoc, diag::err_catch_param_not_objc_type);

5181 Diag(IdLoc, diag::err_catch_param_not_objc_type);

5182 }

5183

5187

5188

5191

5194 return New;

5195}

5196

5198 const DeclSpec &DS = D.getDeclSpec();

5199

5200

5201

5208 }

5212 if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())

5213 Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),

5214 diag::err_invalid_thread)

5216 D.getMutableDeclSpec().ClearStorageClassSpecs();

5217

5219

5220

5221

5224

5227

5230 D.getIdentifierLoc(),

5231 D.getIdentifier(),

5232 D.isInvalidType());

5233

5234

5235 if (D.getCXXScopeSpec().isSet()) {

5236 Diag(D.getIdentifierLoc(), diag::err_qualified_objc_catch_parm)

5237 << D.getCXXScopeSpec().getRange();

5239 }

5240

5241

5242 S->AddDecl(New);

5243 if (D.getIdentifier())

5245

5247

5248 if (New->hasAttr())

5250 return New;

5251}

5252

5253

5254

5262 Ivars.push_back(Iv);

5263 }

5264}

5265

5268

5272 for (unsigned I = 0, N = Sels.size(); I != N; ++I)

5274 }

5275

5276

5277

5278

5281 return;

5283 Selector Sel = SelectorAndLocation.first;

5286 Diag(Loc, diag::warn_unimplemented_selector) << Sel;

5287 }

5288}

5289

5294 return nullptr;

5296 if (!IDecl)

5297 return nullptr;

5299 false,

5300 false);

5302 return nullptr;

5305

5306

5307

5308 IV = const_cast<ObjCInterfaceDecl *>(IDecl)->lookupInstanceVariable(

5309 IV->getIdentifier());

5310 return IV;

5311 }

5312 return nullptr;

5313}

5314

5315namespace {

5316

5317

5319public:

5323 bool AccessedIvar;

5324 bool InvokedSelfMethod;

5325

5328 : S(S), Method(Method), IvarD(IvarD), AccessedIvar(false),

5329 InvokedSelfMethod(false) {

5330 assert(IvarD);

5331 }

5332

5334 if (E->getDecl() == IvarD) {

5335 AccessedIvar = true;

5336 return false;

5337 }

5338 return true;

5339 }

5340

5343 S.ObjC().isSelfExpr(E->getInstanceReceiver(), Method)) {

5344 InvokedSelfMethod = true;

5345 }

5346 return true;

5347 }

5348};

5349}

5350

5353 if (S->hasUnrecoverableErrorOccurred())

5354 return;

5355

5357 unsigned DIAG = diag::warn_unused_property_backing_ivar;

5360 continue;

5361

5364 if (!IV)

5365 continue;

5366

5367 if (CurMethod->isSynthesizedAccessorStub())

5368 continue;

5369

5370 UnusedBackingIvarChecker Checker(SemaRef, CurMethod, IV);

5371 Checker.TraverseStmt(CurMethod->getBody());

5372 if (Checker.AccessedIvar)

5373 continue;

5374

5375

5376

5377

5378

5379 if (!IV->isReferenced() || !Checker.InvokedSelfMethod) {

5381 Diag(PDecl->getLocation(), diag::note_property_declare);

5382 }

5383 }

5384}

5385

5389

5392 return T;

5393

5395

5396

5397

5398

5400 if (T.isConstQualified()) {

5404 NameLoc, diag::err_arc_array_param_no_ownership, T, false));

5405 else

5406 Diag(NameLoc, diag::err_arc_array_param_no_ownership)

5408 }

5410 } else {

5412 }

5414

5415 return T;

5416}

5417

5420 bool DoTypoCorrection) {

5421

5422

5425

5426 if (!IDecl && DoTypoCorrection) {

5427

5428

5436 }

5437 }

5438 ObjCInterfaceDecl *Def = dyn_cast_or_null(IDecl);

5439

5442 return Def;

5443}

5444

5450

5451 unsigned kind = -1U;

5452 if (VarDecl *var = dyn_cast(decl)) {

5453 if (var->hasAttr())

5454 kind = 0;

5455 else if (!var->hasLocalStorage())

5456 kind = 1;

5457 } else if (isa(decl)) {

5458 kind = 3;

5459 } else if (isa(decl)) {

5460 kind = 2;

5461 }

5462

5463 if (kind != -1U) {

5464 Diag(decl->getLocation(), diag::err_arc_autoreleasing_var) << kind;

5465 }

5467

5468 if (type->isObjCLifetimeType())

5469 return false;

5470

5471 lifetime = type->getObjCARCImplicitLifetime();

5474 }

5475

5476 if (VarDecl *var = dyn_cast(decl)) {

5477

5479 var->getTLSKind()) {

5480 Diag(var->getLocation(), diag::err_arc_thread_ownership)

5481 << var->getType();

5482 return true;

5483 }

5484 }

5485

5486 return false;

5487}

5488

5490 return (dyn_cast_or_null(SemaRef.CurContext));

5491}

5492

5495 return;

5500 if (ivars.empty())

5501 return;

5503 for (unsigned i = 0; i < ivars.size(); i++) {

5505 if (Field->isInvalidDecl())

5506 continue;

5507

5512

5515 InitSeq.Perform(SemaRef, InitEntity, InitKind, {});

5517

5518

5519 if (!MemberInit.get() || MemberInit.isInvalid())

5520 continue;

5521

5522 Member = new (Context)

5525 AllToInit.push_back(Member);

5526

5527

5530 ->getAs()) {

5531 CXXRecordDecl *RD = cast(RecordTy->getDecl());

5536 PDiag(diag::err_access_dtor_ivar)

5538 }

5539 }

5540 }

5542 AllToInit.size());

5543 }

5544}

5545

5546

5547

5550 switch (ivarVisibility) {

5551 default:

5552 llvm_unreachable("Unknown visitibility kind");

5553 case tok::objc_private:

5555 case tok::objc_public:

5557 case tok::objc_protected:

5559 case tok::objc_package:

5561 }

5562}

5563

5564

5565

5568

5571 if (II)

5572 Loc = D.getIdentifierLoc();

5573

5574

5575

5576

5579

5580 if (BitWidth) {

5581

5582 BitWidth =

5585 if (!BitWidth)

5586 D.setInvalidType();

5587 } else {

5588

5589

5590

5591 }

5593 Diag(Loc, diag::err_ivar_reference_type);

5594 D.setInvalidType();

5595 }

5596

5597

5600 TInfo, T, Loc, diag::err_typecheck_ivar_variable_size))

5601 D.setInvalidType();

5602 }

5603

5604

5608

5611 if (!EnclosingDecl || EnclosingDecl->isInvalidDecl())

5612 return nullptr;

5615 dyn_cast(EnclosingDecl)) {

5617

5618

5619 EnclosingContext = IMPDecl->getClassInterface();

5620 assert(EnclosingContext && "Implementation has no class interface!");

5621 } else

5622 EnclosingContext = EnclosingDecl;

5623 } else {

5624 if (ObjCCategoryDecl *CDecl = dyn_cast(EnclosingDecl)) {

5626 Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();

5627 return nullptr;

5628 }

5629 }

5630 EnclosingContext = EnclosingDecl;

5631 }

5632

5633

5636 II, T, TInfo, ac, BitWidth);

5637

5640

5641 if (II) {

5644 RedeclarationKind::ForVisibleRedeclaration);

5646 !isa(PrevDecl)) {

5647 Diag(Loc, diag::err_duplicate_member) << II;

5648 Diag(PrevDecl->getLocation(), diag::note_previous_declaration);

5650 }

5651 }

5652

5653

5655

5656 if (D.isInvalidType())

5658

5659

5662

5663 if (D.getDeclSpec().isModulePrivateSpecified())

5665

5666 if (II) {

5667

5668

5669 S->AddDecl(NewID);

5671 }

5672

5674 isa(EnclosingDecl))

5675 Diag(Loc, diag::warn_ivars_in_interface);

5676

5677 return NewID;

5678}

Defines the clang::ASTContext interface.

Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.

#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY)

static QualType getObjectType(APValue::LValueBase B)

Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.

llvm::MachO::Record Record

static bool IsVariableSizedType(QualType T)

static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD)

static bool HasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param)

HasExplicitOwnershipAttr - returns true when pointer to ObjC pointer has explicit ownership attribute...

static void checkObjCDirectMethodClashes(Sema &S, ObjCInterfaceDecl *IDecl, ObjCMethodDecl *Method, ObjCImplDecl *ImpDecl=nullptr)

static bool CheckMethodOverrideParam(Sema &S, ObjCMethodDecl *MethodImpl, ObjCMethodDecl *MethodDecl, ParmVarDecl *ImplVar, ParmVarDecl *IfaceVar, bool IsProtocolMethodDecl, bool IsOverridingMode, bool Warn)

static SourceRange getTypeRange(TypeSourceInfo *TSI)

std::unique_ptr< ProtocolNameSet > LazyProtocolNameSet

static bool CheckMethodOverrideReturn(Sema &S, ObjCMethodDecl *MethodImpl, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl, bool IsOverridingMode, bool Warn)

static void DiagnoseCategoryDirectMembersProtocolConformance(Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl)

static bool checkTypeParamListConsistency(Sema &S, ObjCTypeParamList *prevTypeParams, ObjCTypeParamList *newTypeParams, TypeParamListContext newContext)

Check consistency between two Objective-C type parameter lists, e.g., between a category/extension an...

static void HelperSelectorsForTypoCorrection(SmallVectorImpl< const ObjCMethodDecl * > &BestMethod, StringRef Typo, const ObjCMethodDecl *Method)

static bool objcModifiersConflict(Decl::ObjCDeclQualifier x, Decl::ObjCDeclQualifier y)

Determine whether two set of Objective-C declaration qualifiers conflict.

static bool shouldWarnUndefinedMethod(const ObjCMethodDecl *M)

static bool FilterMethodsByTypeBound(ObjCMethodDecl *Method, const ObjCObjectType *TypeBound)

Return true if the given method is wthin the type bound.

static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, SourceLocation ImplLoc)

static void findProtocolsWithExplicitImpls(const ObjCProtocolDecl *PDecl, ProtocolNameSet &PNS)

static bool matchTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, QualType leftQT, QualType rightQT)

static void DiagnoseRetainableFlexibleArrayMember(Sema &S, ObjCInterfaceDecl *ID)

Diagnose attempts to use flexible array member with retainable object type.

static void mergeInterfaceMethodToImpl(Sema &S, ObjCMethodDecl *method, ObjCMethodDecl *prevMethod)

Merge information from the declaration of a method in the @interface (or a category/extension) into t...

static bool HelperIsMethodInObjCType(Sema &S, Selector Sel, QualType ObjectType)

static SemaObjC::ResultTypeCompatibilityKind CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method, ObjCInterfaceDecl *CurrentClass)

Check whether the declared result type of the given Objective-C method declaration is compatible with...

static ObjCIvarDecl::AccessControl TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility)

TranslateIvarVisibility - Translate visibility from a token ID to an AST enum value.

static void CheckProtocolMethodDefs(Sema &S, ObjCImplDecl *Impl, ObjCProtocolDecl *PDecl, bool &IncompleteImpl, const SemaObjC::SelectorSet &InsMap, const SemaObjC::SelectorSet &ClsMap, ObjCContainerDecl *CDecl, LazyProtocolNameSet &ProtocolsExplictImpl)

CheckProtocolMethodDefs - This routine checks unimplemented methods Declared in protocol,...

static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl, ObjCMethodDecl *method, bool &IncompleteImpl, unsigned DiagID, NamedDecl *NeededFor=nullptr)

static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl, ObjCProtocolDecl *&UndefinedProtocol)

static bool isObjCTypeSubstitutable(ASTContext &Context, const ObjCObjectPointerType *A, const ObjCObjectPointerType *B, bool rejectId)

Determines if type B can be substituted for type A.

llvm::DenseSet< IdentifierInfo * > ProtocolNameSet

FIXME: Type hierarchies in Objective-C can be deep.

static QualType mergeTypeNullabilityForRedecl(Sema &S, SourceLocation loc, QualType type, bool usesCSKeyword, SourceLocation prevLoc, QualType prevType, bool prevUsesCSKeyword)

Merge type nullability from for a redeclaration of the same entity, producing the updated type of the...

static bool diagnoseNoescape(const ParmVarDecl *NewD, const ParmVarDecl *OldD, Sema &S)

Issue a warning if the parameter of the overridden method is non-escaping but the parameter of the ov...

static bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen, ObjCMethodDecl *other)

Determines if this is an "acceptable" loose mismatch in the global method pool.

static void mergeObjCDirectMembers(Sema &S, Decl *CD, ObjCMethodDecl *Method)

static void DiagnoseWeakIvars(Sema &S, ObjCImplementationDecl *ID)

Diagnose attempts to define ARC-__weak ivars when __weak is disabled.

static void checkObjCMethodX86VectorTypes(Sema &SemaRef, const ObjCMethodDecl *Method)

Verify that the method parameters/return value have types that are supported by the x86 target.

static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl, ObjCMethodDecl *decl)

In ARC, check whether the conventional meanings of the two methods match.

static bool isMethodContextSameForKindofLookup(ObjCMethodDecl *Method, ObjCMethodDecl *MethodInList)

static bool tryMatchRecordTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, const Type *left, const Type *right)

static Decl::ObjCDeclQualifier CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal)

CvtQTToAstBitMask - utility routine to produce an AST bitmask for objective-c's type qualifier from t...

static void diagnoseUseOfProtocols(Sema &TheSema, ObjCContainerDecl *CD, ObjCProtocolDecl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs)

This file declares semantic analysis for Objective-C.

Defines the SourceManager interface.

__DEVICE__ long long abs(long long __n)

virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D)

Handle the specified top-level declaration that occurred inside and ObjC container.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

SourceManager & getSourceManager()

TranslationUnitDecl * getTranslationUnitDecl() const

bool AnyObjCImplementation()

Return true if there is at least one @implementation in the TU.

QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const

getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.

void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig, ObjCTypeParamDecl *New) const

bool ObjCQualifiedIdTypesAreCompatible(const ObjCObjectPointerType *LHS, const ObjCObjectPointerType *RHS, bool ForCompare)

ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an ObjCQualifiedIDType.

QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType, const Attr *attr=nullptr) const

CanQualType getCanonicalType(QualType T) const

Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)

canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...

QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const

Return the unique reference to the type for the specified type declaration.

const LangOptions & getLangOpts() const

SelectorTable & Selectors

QualType getObjCInstanceType()

Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;.

QualType getBaseElementType(const ArrayType *VAT) const

Return the innermost element type of an array type.

void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, SmallVectorImpl< const ObjCIvarDecl * > &Ivars) const

DeepCollectObjCIvars - This routine first collects all declared, but not synthesized,...

TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const

Allocate a TypeSourceInfo where all locations have been initialized to a given location,...

TypeInfo getTypeInfo(const Type *T) const

Get the size and alignment of the specified complete type in bits.

QualType getObjCObjectPointerType(QualType OIT) const

Return a ObjCObjectPointerType type for the given ObjCObjectType.

const clang::PrintingPolicy & getPrintingPolicy() const

QualType getObjCIdType() const

Represents the Objective-CC id type.

bool hasSameUnqualifiedType(QualType T1, QualType T2) const

Determine whether the given types are equivalent after cvr-qualifiers have been removed.

QualType getAdjustedParameterType(QualType T) const

Perform adjustment on the parameter type of a function.

const TargetInfo & getTargetInfo() const

QualType getLifetimeQualifiedType(QualType type, Qualifiers::ObjCLifetime lifetime)

Return a type with the given lifetime qualifier.

bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)

Compatibility predicates used to check assignment expressions.

bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT, bool IsParam) const

void CollectInheritedProtocols(const Decl *CDecl, llvm::SmallPtrSet< ObjCProtocolDecl *, 8 > &Protocols)

CollectInheritedProtocols - Collect all protocols in current class and those inherited by it.

The result of parsing/analyzing an expression, statement etc.

A factory, from which one makes pools, from which one creates individual attributes which are dealloc...

Type source information for an attributed type.

static std::optional< NullabilityKind > stripOuterNullability(QualType &T)

Strip off the top-level nullability annotation on the given type, if it's there.

Represents a C++ base or member initializer.

Represents a C++ destructor within a class.

Represents a C++ struct/union/class.

CanQual< T > getUnqualifiedType() const

Retrieve the unqualified form of this type.

const T * getTypePtr() const

Retrieve the underlying type pointer, which refers to a canonical type.

Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...

specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

bool isFileContext() const

void makeDeclVisibleInContext(NamedDecl *D)

Makes a declaration visible within this context.

bool isObjCContainer() const

DeclContext * getRedeclContext()

getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...

void addDecl(Decl *D)

Add the declaration D into this context.

Decl::Kind getDeclKind() const

Simple template class for restricting typo correction candidates to ones having a single Decl* of the...

Captures information about "declaration specifiers".

static const TST TST_typename

SourceLocation getStorageClassSpecLoc() const

SCS getStorageClassSpec() const

bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)

void SetRangeEnd(SourceLocation Loc)

void SetRangeStart(SourceLocation Loc)

SCS

storage-class-specifier

bool isInlineSpecified() const

static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)

Turn a type-specifier-type into a string like "_Bool" or "union".

SourceLocation getInlineSpecLoc() const

Decl - This represents one declaration (or definition), e.g.

SourceLocation getEndLoc() const LLVM_READONLY

ASTContext & getASTContext() const LLVM_READONLY

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

bool isUnavailable(std::string *Message=nullptr) const

Determine whether this declaration is marked 'unavailable'.

AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const

Determine the availability of the given declaration.

void setInvalidDecl(bool Invalid=true)

setInvalidDecl - Indicates the Decl had a semantic error.

bool isUnconditionallyVisible() const

Determine whether this declaration is definitely visible to name lookup, independent of whether the o...

void setTopLevelDeclInObjCContainer(bool V=true)

bool isReferenced() const

Whether any declaration of this entity was referenced.

ObjCDeclQualifier

ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...

@ OBJC_TQ_CSNullability

The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...

bool isInvalidDecl() const

SourceLocation getLocation() const

bool isDeprecated(std::string *Message=nullptr) const

Determine whether this declaration is marked 'deprecated'.

void setImplicit(bool I=true)

DeclContext * getDeclContext()

void setDeclContext(DeclContext *DC)

setDeclContext - Set both the semantic and lexical DeclContext to DC.

void setLexicalDeclContext(DeclContext *DC)

virtual SourceRange getSourceRange() const LLVM_READONLY

Source range that this declaration covers.

TypeSourceInfo * getTypeSourceInfo() const

Information about one declarator, including the parsed type information and the identifier.

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

Recursive AST visitor that supports extension via dynamic dispatch.

This represents one expression.

Represents a member of a struct/union/class.

bool isBitField() const

Determines whether this field is a bitfield.

unsigned getBitWidthValue() const

Computes the bit width of this field, if this is a bit field.

Expr * getBitWidth() const

Returns the expression that represents the bit width, if this field is a bit field.

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

Create a code modification hint that replaces the given source range with the given code string.

static FixItHint CreateRemoval(CharSourceRange RemoveRange)

Create a code modification hint that removes the given source range.

static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)

Create a code modification hint that inserts the given code string at a specific location.

One of these records is kept for each identifier that is lexed.

void RemoveDecl(NamedDecl *D)

RemoveDecl - Unlink the decl from its shadowed decl chain.

void AddDecl(NamedDecl *D)

AddDecl - Link the decl to its shadowed decl chain.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

Describes the kind of initialization being performed, along with location information for tokens rela...

static InitializationKind CreateDefault(SourceLocation InitLoc)

Create a default initialization.

Describes the sequence of initializations required to initialize a given object or reference with a s...

Describes an entity that is being initialized.

static InitializedEntity InitializeMember(FieldDecl *Member, const InitializedEntity *Parent=nullptr, bool Implicit=false)

Create the initialization entity for a member subobject.

clang::ObjCRuntime ObjCRuntime

Represents the results of name lookup.

NamedDecl * getFoundDecl() const

Fetch the unique decl found by this lookup.

bool isSingleResult() const

Determines if this names a single result which is not an unresolved value using decl.

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

void setModulePrivate()

Specify that this declaration was marked as being private to the module in which it was defined.

static ObjCAtDefsFieldDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW)

ObjCCategoryDecl - Represents a category declaration.

static ObjCCategoryDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())

void setProtocolList(ObjCProtocolDecl *const *List, unsigned Num, const SourceLocation *Locs, ASTContext &C)

setProtocolList - Set the list of protocols that this interface implements.

ObjCCategoryImplDecl * getImplementation() const

ObjCInterfaceDecl * getClassInterface()

bool IsClassExtension() const

const ObjCProtocolList & getReferencedProtocols() const

void setImplementation(ObjCCategoryImplDecl *ImplD)

ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.

ObjCCategoryDecl * getCategoryDecl() const

static ObjCCategoryImplDecl * Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc)

ObjCCompatibleAliasDecl - Represents alias of a class.

static ObjCCompatibleAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl *aliasedClass)

ObjCContainerDecl - Represents a container for method declarations.

ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const

method_range methods() const

SourceRange getAtEndRange() const

instmeth_range instance_methods() const

ObjCIvarDecl * getIvarDecl(IdentifierInfo *Id) const

getIvarDecl - This method looks up an ivar in this ContextDecl.

void setAtEndRange(SourceRange atEnd)

ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const

prop_range properties() const

classmeth_range class_methods() const

ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const

Captures information about "declaration specifiers" specific to Objective-C.

ObjCDeclQualifier

ObjCDeclQualifier - Qualifier used on types in method declarations.

ObjCDeclQualifier getObjCDeclQualifier() const

propimpl_range property_impls() const

const ObjCInterfaceDecl * getClassInterface() const

ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...

static ObjCImplementationDecl * Create(ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *classInterface, ObjCInterfaceDecl *superDecl, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation superLoc=SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())

void setIvarInitializers(ASTContext &C, CXXCtorInitializer **initializers, unsigned numInitializers)

const ObjCInterfaceDecl * getSuperClass() const

Represents an ObjC class declaration.

void mergeClassExtensionProtocolList(ObjCProtocolDecl *const *List, unsigned Num, ASTContext &C)

mergeClassExtensionProtocolList - Merge class extension's protocol list into the protocol list for th...

ObjCTypeParamList * getTypeParamList() const

Retrieve the type parameters of this class.

ObjCInterfaceDecl * lookupInheritedClass(const IdentifierInfo *ICName)

lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super class whose name is passe...

ivar_iterator ivar_end() const

llvm::iterator_range< specific_decl_iterator< ObjCIvarDecl > > ivar_range

static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)

unsigned ivar_size() const

ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)

void setProtocolList(ObjCProtocolDecl *const *List, unsigned Num, const SourceLocation *Locs, ASTContext &C)

setProtocolList - Set the list of protocols that this interface implements.

bool hasDefinition() const

Determine whether this class has been defined.

all_protocol_range all_referenced_protocols() const

visible_extensions_range visible_extensions() const

bool isImplicitInterfaceDecl() const

isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node.

ObjCIvarDecl * all_declared_ivar_begin()

all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...

ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const

FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...

ivar_iterator ivar_begin() const

void setImplementation(ObjCImplementationDecl *ImplD)

known_categories_range known_categories() const

void setSuperClass(TypeSourceInfo *superClass)

const ObjCProtocolList & getReferencedProtocols() const

ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const

lookupMethod - This method returns an instance/class method by looking in the class,...

ObjCImplementationDecl * getImplementation() const

void setEndOfDefinitionLoc(SourceLocation LE)

void startDefinition()

Starts the definition of this Objective-C class, taking it from a forward declaration (@class) to a d...

visible_categories_range visible_categories() const

ObjCInterfaceDecl * getCanonicalDecl() override

Retrieves the canonical declaration of this Objective-C class.

ObjCInterfaceDecl * getSuperClass() const

ObjCInterfaceDecl * getDefinition()

Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...

void startDuplicateDefinitionForComparison()

Starts the definition without sharing it with other redeclarations.

bool isSuperClassOf(const ObjCInterfaceDecl *I) const

isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...

Interfaces are the core concept in Objective-C for object oriented design.

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCIvarDecl * getNextIvar()

static ObjCIvarDecl * Create(ASTContext &C, ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW=nullptr, bool synthesized=false)

ObjCIvarRefExpr - A reference to an ObjC instance variable.

ObjCList - This is a simple template class used to hold various lists of decls etc,...

void set(T *const *InList, unsigned Elts, ASTContext &Ctx)

An expression that sends a message to the given Objective-C object or class.

@ Instance

The receiver is an object instance.

ObjCMethodDecl - Represents an instance or class method declaration.

bool isDesignatedInitializerForTheInterface(const ObjCMethodDecl **InitMethod=nullptr) const

Returns true if the method selector resolves to a designated initializer in the class's interface.

ImplicitParamDecl * getSelfDecl() const

void setObjCDeclQualifier(ObjCDeclQualifier QV)

void setDefined(bool isDefined)

ObjCDeclQualifier getObjCDeclQualifier() const

ArrayRef< ParmVarDecl * > parameters() const

unsigned param_size() const

bool isPropertyAccessor() const

static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)

const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const

Returns the property associated with this method's selector.

param_const_iterator param_end() const

param_const_iterator param_begin() const

ObjCMethodDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})

Sets the method's parameters and selector source locations.

void setAsRedeclaration(const ObjCMethodDecl *PrevMethod)

void setRelatedResultType(bool RRT=true)

Note whether this method has a related result type.

bool isSynthesizedAccessorStub() const

SourceLocation getSelectorLoc(unsigned Index) const

SourceRange getReturnTypeSourceRange() const

void setOverriding(bool IsOver)

const ParmVarDecl *const * param_const_iterator

bool hasRelatedResultType() const

Determine whether this method has a result type that is related to the message receiver's type.

SourceLocation getBeginLoc() const LLVM_READONLY

bool isDirectMethod() const

True if the method is tagged as objc_direct.

Selector getSelector() const

ImplicitParamDecl * getCmdDecl() const

bool isInstanceMethod() const

void setReturnType(QualType T)

ObjCMethodFamily getMethodFamily() const

Determines the family of this method.

void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)

createImplicitParams - Used to lazily create the self and cmd implicit parameters.

QualType getReturnType() const

ParmVarDecl *const * param_iterator

ObjCImplementationControl getImplementationControl() const

bool isClassMethod() const

ObjCInterfaceDecl * getClassInterface()

Wraps an ObjCPointerType with source location information.

void setStarLoc(SourceLocation Loc)

Represents a pointer to an Objective C object.

bool isObjCQualifiedIdType() const

True if this is equivalent to 'id.

bool isObjCIdType() const

True if this is equivalent to the 'id' type, i.e.

const ObjCInterfaceType * getInterfaceType() const

If this pointer points to an Objective C @interface type, gets the type for that interface.

Represents a class type in Objective C.

ObjCInterfaceDecl * getInterface() const

Gets the interface declaration for this object type, if the base type really is an interface.

Represents one property declaration in an Objective-C interface.

ObjCIvarDecl * getPropertyIvarDecl() const

ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...

Represents an Objective-C protocol declaration.

void startDuplicateDefinitionForComparison()

Starts the definition without sharing it with other redeclarations.

bool hasDefinition() const

Determine whether this protocol has a definition.

bool isThisDeclarationADefinition() const

Determine whether this particular declaration is also the definition.

static ObjCProtocolDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl)

const ObjCProtocolList & getReferencedProtocols() const

void setProtocolList(ObjCProtocolDecl *const *List, unsigned Num, const SourceLocation *Locs, ASTContext &C)

setProtocolList - Set the list of protocols that this interface implements.

ObjCProtocolDecl * getDefinition()

Retrieve the definition of this protocol, if any.

void startDefinition()

Starts the definition of this Objective-C protocol.

protocol_range protocols() const

A list of Objective-C protocols, along with the source locations at which they were referenced.

The basic abstraction for the target Objective-C runtime.

bool isNeXTFamily() const

Is this runtime basically of the NeXT family of runtimes?

bool isNonFragile() const

Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?

bool isFragile() const

The inverse of isNonFragile(): does this runtime follow the set of implied behaviors for a "fragile" ...

Represents the declaration of an Objective-C type parameter.

static ObjCTypeParamDecl * Create(ASTContext &ctx, DeclContext *dc, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, SourceLocation nameLoc, IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo)

bool hasExplicitBound() const

Whether this type parameter has an explicitly-written type bound, e.g., "T : NSView".

ObjCTypeParamVariance getVariance() const

Determine the variance of this type parameter.

void setVariance(ObjCTypeParamVariance variance)

Set the variance of this type parameter.

SourceLocation getVarianceLoc() const

Retrieve the location of the variance keyword.

Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...

SourceRange getSourceRange() const

unsigned size() const

Determine the number of type parameters in this list.

ObjCTypeParamDecl * back() const

static ObjCTypeParamList * create(ASTContext &ctx, SourceLocation lAngleLoc, ArrayRef< ObjCTypeParamDecl * > typeParams, SourceLocation rAngleLoc)

Create a new Objective-C type parameter list.

SourceLocation getLAngleLoc() const

Represents a parameter to a function.

void setObjCDeclQualifier(ObjCDeclQualifier QTVal)

ObjCDeclQualifier getObjCDeclQualifier() const

void setObjCMethodScopeInfo(unsigned parameterIndex)

static const ParsedAttributesView & none()

PointerType - C99 6.7.5.1 - Pointer Declarators.

A (possibly-)qualified type.

bool hasQualifiers() const

Determine whether this type has any qualifiers.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

Qualifiers::ObjCLifetime getObjCLifetime() const

Returns lifetime attribute of this type.

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)

The collection of all-type qualifiers we support.

void removeCVRQualifiers(unsigned mask)

@ OCL_ExplicitNone

This object can be modified without requiring retains or releases.

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

@ OCL_Autoreleasing

Assigning into this object requires a lifetime extension.

std::string getAsString() const

Represents a struct/union/class.

field_iterator field_end() const

field_iterator field_begin() const

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

Base for LValueReferenceType and RValueReferenceType.

Scope - A scope is a transient data structure that is used while parsing the program.

Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)

Can create any sort of selector.

Smart pointer class that efficiently represents Objective-C method names.

StringRef getNameForSlot(unsigned argIndex) const

Retrieve the name at a given position in the selector.

std::string getAsString() const

Derive the full selector name (e.g.

ObjCMethodFamily getMethodFamily() const

Derive the conventional family of this method.

bool isUnarySelector() const

unsigned getNumArgs() const

A generic diagnostic builder for errors which may or may not be deferred.

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)

Emit a diagnostic.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

ASTContext & getASTContext() const

const LangOptions & getLangOpts() const

DiagnosticsEngine & getDiagnostics() const

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,...

void ActOnSuperClassOfClassInterface(Scope *S, SourceLocation AtInterfaceLoc, ObjCInterfaceDecl *IDecl, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, ArrayRef< ParsedType > SuperTypeArgs, SourceRange SuperTypeArgsRange)

VarDecl * BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, bool Invalid=false)

Build a type-check a new Objective-C exception variable declaration.

void DiagnoseUnusedBackingIvarInAccessor(Scope *S, const ObjCImplementationDecl *ImplD)

DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which backs the property is n...

void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation)

SetIvarInitializers - This routine builds initialization ASTs for the Objective-C implementation whos...

void WarnExactTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl)

WarnExactTypedMethods - This routine issues a warning if method implementation declaration matches ex...

const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())

void ProcessPropertyDecl(ObjCPropertyDecl *property)

Process the specified property declaration and create decls for the setters and getters as needed.

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.

void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method)

Add the given method to the list of globally-known methods.

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 diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)

Diagnose any null-resettable synthesized setters.

void updateOutOfDateSelector(Selector Sel)

void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList)

ObjCImplementationDecl * ActOnStartClassImplementation(SourceLocation AtClassImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *SuperClassname, SourceLocation SuperClassLoc, const ParsedAttributesView &AttrList)

bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl< ObjCMethodDecl * > &Methods)

Decl * ActOnObjCExceptionDecl(Scope *S, Declarator &D)

bool CheckObjCDeclScope(Decl *D)

Checks that the Objective-C declaration is declared in the global scope.

DeclResult actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, IdentifierInfo *paramName, SourceLocation paramLoc, SourceLocation colonLoc, ParsedType typeBound)

ObjCIvarDecl * GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, const ObjCPropertyDecl *&PDecl) const

GetIvarBackingPropertyAccessor - If method is a property setter/getter and it property has a backing ...

bool CheckARCMethodDecl(ObjCMethodDecl *method)

Check a method declaration for compatibility with the Objective-C ARC conventions.

ObjCContainerKind getObjCContainerKind() const

ObjCInterfaceDecl * getObjCInterfaceDecl(const IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)

Look for an Objective-C class in the translation unit.

ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)

LookupMethodInType - Look up a method in an ObjCObjectType.

ParmVarDecl * ActOnMethodParmDeclaration(Scope *S, ObjCArgInfo &ArgInfo, int ParamIndex, bool MethodDefinition)

DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef< Decl * > Decls)

ObjCContainerDecl * getObjCDeclContext() const

void WarnConflictingTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl)

bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, MethodMatchStrategy strategy=MMS_strict)

MatchTwoMethodDeclarations - Checks if two methods' type match and returns true, or false,...

void MatchAllMethodDeclarations(const SelectorSet &InsMap, const SelectorSet &ClsMap, SelectorSet &InsMapSeen, SelectorSet &ClsMapSeen, ObjCImplDecl *IMPDecl, ObjCContainerDecl *IDecl, bool &IncompleteImpl, bool ImmediateClass, bool WarnCategoryMethodImpl=false)

MatchAllMethodDeclarations - Check methods declaraed in interface or or protocol against those declar...

llvm::MapVector< Selector, SourceLocation > ReferencedSelectors

Method selectors used in a @selector expression.

void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)

void ActOnObjCContainerFinishDefinition()

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

void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID)

DiagnoseDuplicateIvars - Check for duplicate ivars in the entire class at the start of @implementatio...

bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall)

Check whether the given method, which must be in the 'init' family, is a valid member of that family.

void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, ObjCMethodDecl *Overridden, bool IsProtocolMethodDecl)

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)

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

bool CheckForwardProtocolDeclarationForCircularDependency(IdentifierInfo *PName, SourceLocation &PLoc, SourceLocation PrevLoc, const ObjCList< ObjCProtocolDecl > &PList)

void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, bool SynthesizeProperties)

DiagnoseUnimplementedProperties - This routine warns on those properties which must be implemented by...

void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl)

AtomicPropertySetterGetterRules - This routine enforces the rule (via warning) when atomic property h...

void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, ObjCInterfaceDecl *ID)

DiagnoseClassExtensionDupMethods - Check for duplicate declaration of a class method in its extension...

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

bool inferObjCARCLifetime(ValueDecl *decl)

void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, const ObjCMethodDecl *Overridden)

Check whether the given new method is a valid override of the given overridden method,...

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)

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

void DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD)

void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, SmallVectorImpl< ObjCIvarDecl * > &Ivars)

CollectIvarsToConstructOrDestruct - Collect those ivars which require initialization.

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.

QualType AdjustParameterTypeForObjCAutoRefCount(QualType T, SourceLocation NameLoc, TypeSourceInfo *TSInfo)

GlobalMethodPool MethodPool

Method Pool - allows efficient lookup when typechecking messages to "id".

ObjCProtocolDecl * ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody)

ResultTypeCompatibilityKind

Describes the compatibility of a result type with its method.

void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl< ObjCMethodDecl * > &Methods, Selector Sel, SourceRange R, bool receiverIdOrClass)

DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, ArrayRef< ObjCTypeParamList * > TypeParamLists, unsigned NumElts)

void ReadMethodPool(Selector Sel)

Read the contents of the method pool for a given selector from external storage.

void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, const IdentifierInfo *ClassName, SmallVectorImpl< Decl * > &Decls)

Called whenever @defs(ClassName) is encountered in the source.

void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)

AddFactoryMethodToGlobalPool - Same as above, but for factory methods.

void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, SourceLocation ProtocolLoc, IdentifierInfo *TypeArgId, SourceLocation TypeArgLoc, bool SelectProtocolFirst=false)

bool CollectMultipleMethodsInGlobalPool(Selector Sel, SmallVectorImpl< ObjCMethodDecl * > &Methods, bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound=nullptr)

We first select the type of the method: Instance or Factory, then collect all methods with that type.

void CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, ObjCMethodDecl *overridden)

void DiagnoseUseOfUnimplementedSelectors()

Decl * ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef< Decl * > allMethods={}, ArrayRef< DeclGroupPtrTy > allTUVars={})

void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP)

CheckCategoryVsClassMethodMatches - Checks that methods implemented in category matches with those im...

void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl *IMPDecl, ObjCContainerDecl *IDecl, bool IncompleteImpl=false)

ImplMethodsVsClassMethods - This is main routine to warn if any method remains unimplemented in the c...

void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC)

void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, ObjCIvarDecl **Fields, unsigned nIvars, SourceLocation Loc)

CheckImplementationIvars - This routine checks if the instance variables listed in the implelementati...

ObjCMethodDecl * LookupImplementedMethodInGlobalPool(Selector Sel)

LookupImplementedMethodInGlobalPool - Returns the method which has an implementation.

void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)

AddInstanceMethodToGlobalPool - All instance methods in a translation unit are added to a global pool...

void AddAnyMethodToGlobalPool(Decl *D)

AddAnyMethodToGlobalPool - Add any method, instance or factory to global pool.

@ OCK_CategoryImplementation

bool isSelfExpr(Expr *RExpr)

Private Helper predicate to check for 'self'.

std::unique_ptr< NSAPI > NSAPIObj

Caches identifiers/selectors for NSFoundation APIs.

void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl)

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

bool shouldDelayDiagnostics()

Determines whether diagnostics should be delayed.

void add(const sema::DelayedDiagnostic &diag)

Adds a delayed diagnostic.

Sema - This implements semantic analysis and AST building for C.

ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)

Package the given type and TSI into a ParsedType.

bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false) const

isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...

LookupNameKind

Describes the kind of name lookup to perform.

@ LookupOrdinaryName

Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....

@ LookupObjCProtocolName

Look up the name of an Objective-C protocol.

@ LookupMemberName

Member name lookup, which finds the names of class/struct/union members.

@ LookupAnyName

Look up any declaration with any name.

void DiagnoseFunctionSpecifiers(const DeclSpec &DS)

Diagnose function specifiers on a declaration of an identifier that does not identify a function.

void AddPragmaAttributes(Scope *S, Decl *D)

Adds the attributes that have been specified using the '#pragma clang attribute push' directives to t...

void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)

class clang::Sema::DelayedDiagnostics DelayedDiagnostics

ExprResult VerifyBitField(SourceLocation FieldLoc, const IdentifierInfo *FieldName, QualType FieldTy, bool IsMsStruct, Expr *BitWidth)

VerifyBitField - verifies that a bit field expression is an ICE and has the correct width,...

NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)

Look up a name, looking for a single declaration.

AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())

void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)

Add this decl to the scope shadowed decl chains.

ASTContext & getASTContext() const

CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)

Look for the destructor of the given class.

ObjCMethodDecl * getCurMethodDecl()

getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...

void PushFunctionScope()

Enter a new function scope.

bool CheckFunctionReturnType(QualType T, SourceLocation Loc)

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

Calls Lexer::getLocForEndOfToken()

const LangOptions & getLangOpts() const

TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)

Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...

bool tryToFixVariablyModifiedVarType(TypeSourceInfo *&TInfo, QualType &T, SourceLocation Loc, unsigned FailedFoldDiagID)

Attempt to fold a variable-sized type to a constant-sized type, returning true if we were successful.

void CheckExtraCXXDefaultArguments(Declarator &D)

CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...

void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())

ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...

DeclContext * getCurLexicalContext() const

sema::FunctionScopeInfo * getCurFunction() const

DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)

BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

void ActOnDocumentableDecl(Decl *D)

Should be called on all declarations that might have attached documentation comments.

ParmVarDecl * CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, const IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, StorageClass SC)

void applyFunctionAttributesBeforeParsingBody(Decl *FD)

bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, bool OnlyNeedComplete=false)

Determine if D has a visible definition.

SourceManager & getSourceManager() const

TypeResult ActOnTypeName(Declarator &D)

ExternalSemaSource * getExternalSource() const

bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)

Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.

bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)

CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...

RedeclarationKind forRedeclarationInCurContext() const

void mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK=AMK_Redeclaration)

mergeDeclAttributes - Copy attributes from the Old decl to the New one.

IntrusiveRefCntPtr< ExternalSemaSource > ExternalSource

Source of additional semantic information.

TypeSourceInfo * GetTypeForDeclarator(Declarator &D)

GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.

void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)

bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type T is a complete type.

Scope * TUScope

Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...

Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)

MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...

SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts

A stack of expression evaluation contexts.

void PushDeclContext(Scope *S, DeclContext *DC)

Set the current declaration context until it gets popped.

DiagnosticsEngine & Diags

void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD)

ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in it, apply them to D.

llvm::BumpPtrAllocator BumpAlloc

void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)

Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...

void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old)

void ProcessAPINotes(Decl *D)

Map any API notes provided for this declaration to attributes on the declaration.

bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)

Perform unqualified name lookup starting from a given scope.

static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)

IdentifierResolver IdResolver

llvm::SmallVector< std::pair< SourceLocation, const BlockDecl * >, 1 > ImplicitlyRetainedSelfLocs

List of SourceLocations where 'self' is implicitly retained inside a block.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

bool isInSystemHeader(SourceLocation Loc) const

Returns if a SourceLocation is in a system header.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

SourceLocation getBeginLoc() const LLVM_READONLY

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

StringRef getPlatformName() const

Retrieve the name of the platform as it is used in the availability attribute.

VersionTuple getPlatformMinVersion() const

Retrieve the minimum desired version of the platform, to which the program should be compiled.

Represents a declaration of a type.

SourceLocation getBeginLoc() const LLVM_READONLY

TyLocType push(QualType T)

Pushes space for a new TypeLoc of the given type.

void pushFullCopy(TypeLoc L)

Pushes a copy of the given TypeLoc onto this builder.

TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)

Creates a TypeSourceInfo for the given type.

Base wrapper for a particular "section" of type source info.

TypeLoc findExplicitQualifierLoc() const

Find a type with the location of an explicit type qualifier.

T getAs() const

Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...

SourceRange getSourceRange() const LLVM_READONLY

Get the full source range.

SourceLocation getEndLoc() const

Get the end source location.

SourceLocation getBeginLoc() const

Get the begin source location.

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

The base class of the type hierarchy.

bool isIncompleteArrayType() const

bool isIntegerType() const

isIntegerType() does not include complex integers (a GCC extension).

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

const ObjCObjectPointerType * getAsObjCInterfacePointerType() const

bool isScalarType() const

bool isObjCQualifiedIdType() const

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

ScalarTypeKind getScalarTypeKind() const

Given that this is a scalar type, classify it.

bool containsErrors() const

Whether this type is an error type.

bool isObjCIdType() const

bool isVariablyModifiedType() const

Whether this type is a variably-modified type (C99 6.7.5).

bool isObjCObjectType() const

bool isObjCLifetimeType() const

Returns true if objects of this type have lifetime semantics under ARC.

Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const

Return the implicit lifetime for this type, which must not be dependent.

bool isIncompleteType(NamedDecl **Def=nullptr) const

Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...

bool isObjCObjectPointerType() const

bool isVectorType() const

bool isObjCQualifiedClassType() const

bool isObjCClassType() const

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

std::optional< NullabilityKind > getNullability() const

Determine the nullability of the given type.

bool isObjCIndependentClassType() const

Base class for declarations which introduce a typedef-name.

TypeSourceInfo * getTypeSourceInfo() const

QualType getUnderlyingType() const

Simple class containing the result of Sema::CorrectTypo.

DeclClass * getCorrectionDeclAs() const

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

void setType(QualType newType)

Represents a variable declaration or definition.

static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)

void setExceptionVariable(bool EV)

static DelayedDiagnostic makeForbiddenType(SourceLocation loc, unsigned diagnostic, QualType type, unsigned argument)

bool ObjCIsDesignatedInit

True when this is a method marked as a designated initializer.

bool ObjCShouldCallSuper

A flag that is set when parsing a method that must call super's implementation, such as -dealloc,...

bool ObjCWarnForNoInitDelegation

This starts true for a secondary initializer method and will be set to false if there is an invocatio...

bool ObjCIsSecondaryInit

True when this is an initializer method not marked as a designated initializer within a class that ha...

bool ObjCWarnForNoDesignatedInitChain

This starts true for a method marked as designated initializer and will be set to false if there is a...

Defines the clang::TargetInfo interface.

const internal::VariadicAllOfMatcher< Attr > attr

Matches attributes.

SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)

Returns the results of matching Matcher on Node.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicAllOfMatcher< Decl > decl

Matches declarations.

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.

ThreadStorageClassSpecifier

Thread storage-class-specifier.

ObjCMethodFamily

A family of Objective-C methods.

@ OMF_None

No particular method family.

@ Property

The type of a property.

Selector GetNullarySelector(StringRef name, ASTContext &Ctx)

Utility function for constructing a nullary selector.

@ Class

The "class" keyword.

AvailabilityResult

Captures the result of checking the availability of a declaration.

std::pair< NullabilityKind, bool > DiagNullabilityKind

A nullability kind paired with a bit indicating whether it used a context-sensitive keyword.

const FunctionProtoType * T

bool declaresSameEntity(const Decl *D1, const Decl *D2)

Determine whether two declarations declare the same entity.

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.

@ Interface

The "__interface" keyword introduces the elaborated-type-specifier.

@ Class

The "class" keyword introduces the elaborated-type-specifier.

Visibility

Describes the different kinds of visibility that a declaration may have.

DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...

ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.

static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)

Return a DeclaratorChunk for a pointer.

a linked list of methods with the same selector name but different signatures.

ObjCMethodDecl * getMethod() const

void setMethod(ObjCMethodDecl *M)

void setNext(ObjCMethodList *L)

bool hasMoreThanOneDecl() const

ObjCMethodList * getNext() const

ParsedAttributesView ArgAttrs

ArgAttrs - Attribute list for this argument.