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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

24

25using namespace clang;

26

27

28

29

30

31

32

33

34

35

36

39

40

41 if (attrs &

49 }

50

51

52

54 type->isObjCRetainableType()) {

56 }

57

59}

60

61

62

66

69 = property->getType().getObjCLifetime();

70

72

75 if (!expectedLifetime) {

76

77

78

79

85 } else {

88 }

89 property->setPropertyAttributes(attr);

90 return;

91 }

92

93 if (propertyLifetime == expectedLifetime) return;

94

95 property->setInvalidDecl();

97 diag::err_arc_inconsistent_property_ownership)

98 << property->getDeclName()

99 << expectedLifetime

100 << propertyLifetime;

101}

102

103

104

105static void

108 llvm::SmallPtrSetImpl<ObjCProtocolDecl *> &Known) {

109

110 if (!Known.insert(Proto).second)

111 return;

112

113

117 true);

118 return;

119 }

120

121

122 for (auto *P : Proto->protocols())

124}

125

127

129 if (T.isObjCGCWeak())

131

132

133

134 } else if (auto ownership = T.getObjCLifetime()) {

135 switch (ownership) {

144 return 0;

145 }

146 llvm_unreachable("bad qualifier");

147 }

148

149 return 0;

150}

151

157

160

161

162

167 }

168

169 return result;

170}

171

180 0);

183 if (T.getPointerAuth().isPresent()) {

184 Diag(AtLoc, diag::err_ptrauth_qualifier_invalid) << T << 2;

185 }

188 }

190

192

193

196 if (ObjCCategoryDecl *CDecl = dyn_cast(ClassDecl)) {

197 if (CDecl->IsClassExtension()) {

199 FD,

202 isReadWrite, Attributes,

204 T, TSI, MethodImplKind);

205 if (!Res)

206 return nullptr;

207 }

208 }

209

210 if (!Res) {

215 MethodImplKind);

216 if (lexicalDC)

218 }

219

220

224

225

228

230 if (ObjCInterfaceDecl *IFace = dyn_cast(ClassDecl)) {

231

232 bool FoundInSuper = false;

238 FoundInSuper = true;

239 break;

240 }

241 CurrentInterfaceDecl = Super;

242 }

243

244 if (FoundInSuper) {

245

246 for (auto *P : CurrentInterfaceDecl->protocols()) {

248 }

249 } else {

250

251 for (auto *P : IFace->all_referenced_protocols()) {

253 }

254 }

255 } else if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl)) {

256

257

258

259 if (!Cat->IsClassExtension())

260 for (auto *P : Cat->protocols())

262 } else {

264 for (auto *P : Proto->protocols())

266 }

267

268 SemaRef.ActOnDocumentableDecl(Res);

269 return Res;

270}

271

274 unsigned attributesAsWritten = 0;

303

305}

306

310 return false;

311

314

315 bool invalidTemp = false;

316 StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);

317 if (invalidTemp)

318 return false;

319 const char *tokenBegin = file.data() + locInfo.second;

320

321

322 Lexer lexer(SM.getLocForStartOfFile(locInfo.first),

323 Context.getLangOpts(),

324 file.begin(), tokenBegin, file.end());

326 do {

328 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == attrName) {

329 Loc = Tok.getLocation();

330 return true;

331 }

332 } while (Tok.isNot(tok::r_paren));

333 return false;

334}

335

336

340 bool PropagateAtomicity) {

341

346 if (OldIsAtomic == NewIsAtomic) return;

347

348

349

350 auto isImplicitlyReadonlyAtomic = [](ObjCPropertyDecl *Property) -> bool {

351

352 auto Attrs = Property->getPropertyAttributes();

354 return false;

355

356

358 return false;

359

360

361 if (Property->getPropertyAttributesAsWritten() &

363 return false;

364

365 return true;

366 };

367

368

369

372 if (PropagateAtomicity &&

375 Attrs = Attrs & ~AtomicityMask;

376 if (OldIsAtomic)

378 else

380

382 return;

383 }

384

385

386

387 if ((OldIsAtomic && isImplicitlyReadonlyAtomic(OldProperty)) ||

388 (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))

389 return;

390

391

394 if (auto Category = dyn_cast(OldDC))

395 OldContextName = Category->getClassInterface()->getIdentifier();

396 else

398

399 S.Diag(NewProperty->getLocation(), diag::warn_property_attribute)

400 << NewProperty->getDeclName() << "atomic"

401 << OldContextName;

402 S.Diag(OldProperty->getLocation(), diag::note_property_declare);

403}

404

409 unsigned &Attributes, const unsigned AttributesAsWritten, QualType T,

412

416

417

418

419 if (!CCPrimary) {

420 Diag(CDecl->getLocation(), diag::err_continuation_class);

421 return nullptr;

422 }

423

424 bool isClassProperty =

427

428

429

432

433

435 Diag(AtLoc, diag::err_duplicate_property);

436 Diag(PIDecl->getLocation(), diag::note_property_declare);

437 return nullptr;

438 }

439

440

441 if (PIDecl) {

442

443

444

445 if (!(PIDecl->isReadOnly() && isReadWrite)) {

446

447

448

449

450 unsigned diag =

454 ? diag::err_use_continuation_class_redeclaration_readwrite

455 : diag::err_use_continuation_class;

458 Diag(PIDecl->getLocation(), diag::note_property_declare);

459 return nullptr;

460 }

461

462

464

466 Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)

468 Diag(PIDecl->getLocation(), diag::note_property_declare);

469 }

470

471

474 }

475

476

477 unsigned ExistingOwnership

480 if (ExistingOwnership && NewOwnership != ExistingOwnership) {

481

483 Diag(AtLoc, diag::warn_property_attr_mismatch);

484 Diag(PIDecl->getLocation(), diag::note_property_declare);

485 }

486

487

488 Attributes = (Attributes & ~OwnershipMask) | ExistingOwnership;

489 }

490

491

497 Diag(AtLoc, diag::warn_property_implicitly_mismatched);

498 Diag(PIDecl->getLocation(), diag::note_property_declare);

499 }

500 }

501

502

503

505 FD, GetterSel, GetterNameLoc,

506 SetterSel, SetterNameLoc,

507 isReadWrite,

508 Attributes, AttributesAsWritten,

509 T, TSI, MethodImplKind, DC);

511

512

513 if (!PIDecl) {

515 return PDecl;

516 }

517

518 if (!Context.hasSameType(PIDecl->getType(), PDecl->getType())) {

519 bool IncompatibleObjC = false;

521

522

523

524

525

526

531 (SemaRef.isObjCPointerConversion(ClassExtPropertyT,

532 PrimaryClassPropertyT, ConvertedType,

533 IncompatibleObjC)) ||

534 IncompatibleObjC) {

536 diag::err_type_mismatch_continuation_class) << PDecl->getType();

537 Diag(PIDecl->getLocation(), diag::note_property_declare);

538 return nullptr;

539 }

540 }

541

542

543

545

546

548 return PDecl;

549}

550

555 SourceLocation SetterNameLoc, const bool isReadWrite,

556 const unsigned Attributes, const unsigned AttributesAsWritten, QualType T,

561

562

563

564 bool isAssign;

567 isAssign = true;

569 isAssign = false;

570 } else {

571 isAssign = (getLangOpts().ObjCAutoRefCount ||

572 T->isObjCRetainableType());

573 }

574

575

576

581 ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();

582 if (IDecl)

584 LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc))

586 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;

587 }

588 }

589

590 if (T->isObjCObjectType()) {

592 StarLoc = SemaRef.getLocForEndOfToken(StarLoc);

595 T = Context.getObjCObjectPointerType(T);

597 TInfo = Context.getTrivialTypeSourceInfo(T, TLoc);

598 }

599

603 PropertyId, AtLoc,

604 LParenLoc, T, TInfo);

605

606 bool isClassProperty =

609

612 Diag(PDecl->getLocation(), diag::err_duplicate_property);

613 Diag(prevDecl->getLocation(), diag::note_property_declare);

615 }

616 else {

618 if (lexicalDC)

620 }

621

622 if (T->isArrayType() || T->isFunctionType()) {

623 Diag(AtLoc, diag::err_property_type) << T;

625 }

626

627

628

633

634 SemaRef.ProcessDeclAttributes(S, PDecl, FD.D);

635

638

641

644

645 if (isReadWrite)

647

650

653

656

659

662

663 if (isAssign)

665

666

669 else

671

672

675 if (isAssign)

677

678 if (MethodImplKind == tok::objc_required)

680 else if (MethodImplKind == tok::objc_optional)

682

685

688

691

693 CDecl->hasAttr()) {

695 Diag(PDecl->getLocation(), diag::err_objc_direct_on_protocol) << true;

698 } else {

699 Diag(PDecl->getLocation(), diag::warn_objc_direct_property_ignored)

701 }

702 }

703

704 return PDecl;

705}

706

711

714

715

719

720

721 if (propertyLifetime == ivarLifetime) return;

722

723

724

728 return;

729

730

731

732

733

743 return;

744 }

745 }

746

747 switch (propertyLifetime) {

749 S.Diag(ivar->getLocation(), diag::err_arc_strong_property_ownership)

750 << property->getDeclName()

752 << ivarLifetime;

753 break;

754

757 << property->getDeclName()

759 break;

760

762 S.Diag(ivar->getLocation(), diag::err_arc_assign_property_ownership)

763 << property->getDeclName() << ivar->getDeclName()

764 << ((property->getPropertyAttributesAsWritten() &

766 break;

767

769 llvm_unreachable("properties cannot be autoreleasing");

770

772

773 return;

774 }

775

776 S.Diag(property->getLocation(), diag::note_property_declare);

777 if (propertyImplLoc.isValid())

778 S.Diag(propertyImplLoc, diag::note_property_synthesize);

779}

780

781

782

783

784

785

792 return;

793

794 if (!ivar) {

795

797 return;

798 }

799

806}

807

810 return (Attr1 & Kind) != (Attr2 & Kind);

811}

812

814 unsigned Kinds) {

815 return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);

816}

817

818

819

820

821

822

828 "Expected a property from a protocol");

833 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,

834 Properties);

835 }

837 while (SDecl) {

838 for (const auto *PI : SDecl->all_referenced_protocols()) {

840 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,

841 Properties);

842 }

843 SDecl = SDecl->getSuperClass();

844 }

845 }

846

847 if (Properties.empty())

848 return Property;

849

851 size_t SelectedIndex = 0;

852 for (const auto &Prop : llvm::enumerate(Properties)) {

853

854 if (Property->isReadOnly() && !Prop.value()->isReadOnly()) {

855 Property = Prop.value();

856 SelectedIndex = Prop.index();

857 }

858 }

859 if (Property != OriginalProperty) {

860

861 Properties[SelectedIndex] = OriginalProperty;

862 }

863

865 unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();

866 enum MismatchKind {

867 IncompatibleType = 0,

868 HasNoExpectedAttribute,

869 HasUnexpectedAttribute,

870 DifferentGetter,

871 DifferentSetter

872 };

873

874

875 struct MismatchingProperty {

877 MismatchKind Kind;

878 StringRef AttributeName;

879 };

882

883 unsigned Attr = Prop->getPropertyAttributesAsWritten();

884 if (Attr != OriginalAttributes) {

885 auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {

886 MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute

887 : HasUnexpectedAttribute;

888 Mismatches.push_back({Prop, Kind, AttributeName});

889 };

890

891

892 bool HasOwnership =

899 if (HasOwnership &&

903 continue;

904 }

906 OriginalAttributes, Attr,

911 "retain (or strong)");

912 continue;

913 }

917 continue;

918 }

919 }

920 if (Property->getGetterName() != Prop->getGetterName()) {

921 Mismatches.push_back({Prop, DifferentGetter, ""});

922 continue;

923 }

924 if (!Property->isReadOnly() && !Prop->isReadOnly() &&

925 Property->getSetterName() != Prop->getSetterName()) {

926 Mismatches.push_back({Prop, DifferentSetter, ""});

927 continue;

928 }

931 bool IncompatibleObjC = false;

934 || IncompatibleObjC) {

935 Mismatches.push_back({Prop, IncompatibleType, ""});

936 continue;

937 }

938 }

939 }

940

941 if (Mismatches.empty())

942 return Property;

943

944

945 {

946 bool HasIncompatibleAttributes = false;

947 for (const auto &Note : Mismatches)

948 HasIncompatibleAttributes =

949 Note.Kind != IncompatibleType ? true : HasIncompatibleAttributes;

950

951

952 auto Diag = S.Diag(Property->getLocation(),

953 Property != OriginalProperty || HasIncompatibleAttributes

954 ? diag::err_protocol_property_mismatch

955 : diag::warn_protocol_property_mismatch);

956 Diag << Mismatches[0].Kind;

957 switch (Mismatches[0].Kind) {

958 case IncompatibleType:

959 Diag << Property->getType();

960 break;

961 case HasNoExpectedAttribute:

962 case HasUnexpectedAttribute:

963 Diag << Mismatches[0].AttributeName;

964 break;

965 case DifferentGetter:

966 Diag << Property->getGetterName();

967 break;

968 case DifferentSetter:

969 Diag << Property->getSetterName();

970 break;

971 }

972 }

973 for (const auto &Note : Mismatches) {

975 S.Diag(Note.Prop->getLocation(), diag::note_protocol_property_declare)

976 << Note.Kind;

977 switch (Note.Kind) {

978 case IncompatibleType:

979 Diag << Note.Prop->getType();

980 break;

981 case HasNoExpectedAttribute:

982 case HasUnexpectedAttribute:

984 break;

985 case DifferentGetter:

986 Diag << Note.Prop->getGetterName();

987 break;

988 case DifferentSetter:

989 Diag << Note.Prop->getSetterName();

990 break;

991 }

992 }

994 S.Diag(AtLoc, diag::note_property_synthesize);

995

996 return Property;

997}

998

999

1003

1004

1005

1006

1007

1008

1009 if (Prop->isReadOnly()) return false;

1010

1011

1012 auto Category = dyn_cast(Prop->getDeclContext());

1013 if (!Category || !Category->IsClassExtension()) return false;

1014

1015

1016 auto OrigClass = Category->getClassInterface();

1017 for (auto *Found : OrigClass->lookup(Prop->getDeclName())) {

1019 return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;

1020 }

1021

1022

1023 for (const auto *Proto : OrigClass->all_referenced_protocols()) {

1024 if (ObjCPropertyDecl *OrigProp = Proto->FindPropertyDeclaration(

1026 return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;

1027 }

1028

1029 return false;

1030}

1031

1032

1041 Decl->getSelector(), Decl->getReturnType(),

1042 Decl->getReturnTypeSourceInfo(), Impl, Decl->isInstanceMethod(),

1043 Decl->isVariadic(), Decl->isPropertyAccessor(),

1044 true, Decl->isImplicit(), Decl->isDefined(),

1045 Decl->getImplementationControl(), Decl->hasRelatedResultType());

1052 Decl->getSelectorLocs(SelLocs);

1056 return ImplDecl;

1057}

1058

1059

1060

1061

1062

1069 dyn_cast(SemaRef.CurContext);

1070

1071 if (!ClassImpDecl) {

1072 Diag(AtLoc, diag::err_missing_property_context);

1073 return nullptr;

1074 }

1075 if (PropertyIvarLoc.isInvalid())

1076 PropertyIvarLoc = PropertyLoc;

1078 if (PropertyDiagLoc.isInvalid())

1079 PropertyDiagLoc = ClassImpDecl->getBeginLoc();

1082

1083

1086 if ((IC = dyn_cast(ClassImpDecl))) {

1088

1089

1090 assert(IDecl &&

1091 "ActOnPropertyImplDecl - @implementation without @interface");

1092

1093

1095 if (!property) {

1096 Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->getDeclName();

1097 return nullptr;

1098 }

1099 if (property->isClassProperty() && Synthesize) {

1100 Diag(PropertyLoc, diag::err_synthesize_on_class_property) << PropertyId;

1101 return nullptr;

1102 }

1107 Diag(AtLoc, diag::warn_implicit_atomic_property);

1108 else

1109 Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property);

1110 Diag(property->getLocation(), diag::note_property_declare);

1111 }

1112

1114 dyn_cast(property->getDeclContext())) {

1115 if (!CD->IsClassExtension()) {

1116 Diag(PropertyLoc, diag::err_category_property) << CD->getDeclName();

1117 Diag(property->getLocation(), diag::note_property_declare);

1118 return nullptr;

1119 }

1120 }

1122 property->hasAttr() && !AtLoc.isValid()) {

1123 bool ReadWriteProperty = false;

1124

1125

1129 PIkind = ExtProp->getPropertyAttributesAsWritten();

1131 ReadWriteProperty = true;

1132 break;

1133 }

1134 }

1135 }

1136

1137 if (!ReadWriteProperty) {

1138 Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)

1139 << property;

1142 property->getLParenLoc(), readonlyLoc)) {

1145 SourceRange ReadonlySourceRange(readonlyLoc, endLoc);

1146 Diag(property->getLocation(),

1147 diag::note_auto_readonly_iboutlet_fixup_suggest) <<

1149 }

1150 }

1151 }

1154 property);

1155

1156 } else if ((CatImplClass = dyn_cast(ClassImpDecl))) {

1157 if (Synthesize) {

1158 Diag(AtLoc, diag::err_synthesize_category_decl);

1159 return nullptr;

1160 }

1162 if (!IDecl) {

1163 Diag(AtLoc, diag::err_missing_property_interface);

1164 return nullptr;

1165 }

1168

1169

1170

1171 if (!Category)

1172 return nullptr;

1173

1175 if (!property) {

1176 Diag(PropertyLoc, diag::err_bad_category_property_decl)

1177 << Category->getDeclName();

1178 return nullptr;

1179 }

1180 } else {

1181 Diag(AtLoc, diag::err_bad_property_context);

1182 return nullptr;

1183 }

1185 bool CompleteTypeErr = false;

1186 bool compat = true;

1187

1188 if (Synthesize) {

1189

1190 if (!PropertyIvar)

1191 PropertyIvar = PropertyId;

1192

1195 QualType PropType = property->getType();

1197

1198 if (SemaRef.RequireCompleteType(PropertyDiagLoc, PropertyIvarType,

1199 diag::err_incomplete_synthesized_property,

1200 property->getDeclName())) {

1201 Diag(property->getLocation(), diag::note_property_declare);

1202 CompleteTypeErr = true;

1203 }

1204

1206 (property->getPropertyAttributesAsWritten() &

1210 }

1211

1213

1214 bool isARCWeak = false;

1216

1218 assert(getLangOpts().ObjCAutoRefCount);

1220 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);

1221 Diag(property->getLocation(), diag::note_property_declare);

1222 } else {

1223 PropertyIvarType =

1224 Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak);

1225 }

1226

1227

1228

1229 } else {

1231

1232 if (!Ivar) {

1233 Diag(PropertyDiagLoc,

1235 ? diag::err_synthesizing_arc_weak_property_disabled

1236 : diag::err_synthesizing_arc_weak_property_no_runtime);

1237 Diag(property->getLocation(), diag::note_property_declare);

1238 }

1239 CompleteTypeErr = true;

1240 } else {

1241 isARCWeak = true;

1246 Diag(property->getLocation(),

1247 diag::err_arc_weak_unavailable_property)

1248 << PropertyIvarType;

1249 Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class)

1250 << ClassImpDecl->getName();

1251 }

1252 }

1253 }

1254 }

1255 }

1256

1258

1259

1260

1261

1265 ClassDeclared);

1266 if (originalIvar) {

1267 Diag(PropertyDiagLoc,

1268 diag::warn_autosynthesis_property_ivar_match)

1269 << PropertyId << (Ivar == nullptr) << PropertyIvar

1271 Diag(property->getLocation(), diag::note_property_declare);

1272 Diag(originalIvar->getLocation(), diag::note_ivar_decl);

1273 }

1274 }

1275

1276 if (!Ivar) {

1277

1278

1279 if ((getLangOpts().ObjCAutoRefCount || isARCWeak) &&

1282

1283

1284

1287 Diag(PropertyDiagLoc,

1288 diag::err_arc_objc_property_default_assign_on_object);

1289 Diag(property->getLocation(), diag::note_property_declare);

1290 } else {

1293 assert(lifetime && "no lifetime for property?");

1294

1297 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);

1298 }

1299 }

1300

1301 if (Context.getLangOpts().PointerAuthObjcInterfaceSel &&

1303 if (Context.isObjCSelType(QualType(PropertyIvarType.getTypePtr(), 0))) {

1304 if (auto PAQ = Context.getObjCMemberSelTypePtrAuth())

1305 PropertyIvarType =

1306 Context.getPointerAuthType(PropertyIvarType, PAQ);

1307 }

1308 }

1309

1311 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,

1312 PropertyIvarType, nullptr,

1314 (Expr *)nullptr, true);

1315 if (SemaRef.RequireNonAbstractType(PropertyIvarLoc, PropertyIvarType,

1316 diag::err_abstract_type_in_decl,

1318 Diag(property->getLocation(), diag::note_property_declare);

1319

1320 CompleteTypeErr = true;

1321 }

1322 if (!CompleteTypeErr) {

1323 if (const auto *RD = PropertyIvarType->getAsRecordDecl();

1325 Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)

1326 << PropertyIvarType;

1327 CompleteTypeErr = true;

1328 }

1329 }

1330 if (CompleteTypeErr)

1332 ClassImpDecl->addDecl(Ivar);

1334

1336 Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)

1337 << PropertyId;

1338

1339

1342 Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)

1343 << property->getDeclName() << Ivar->getDeclName()

1345 Diag(Ivar->getLocation(), diag::note_previous_access_declaration)

1346 << Ivar << Ivar->getName();

1347

1348 }

1349 property->setPropertyIvarDecl(Ivar);

1350

1352

1353

1354 if (!Context.hasSameType(PropertyIvarType, IvarType)) {

1357 compat = Context.canAssignObjCInterfaces(

1360 else {

1361 compat = SemaRef.IsAssignConvertCompatible(

1362 SemaRef.CheckAssignmentConstraints(PropertyIvarLoc,

1363 PropertyIvarType, IvarType));

1364 }

1365 if (!compat) {

1366 Diag(PropertyDiagLoc, diag::err_property_ivar_type)

1367 << property->getDeclName() << PropType

1370

1371

1372 }

1373 else {

1374

1375

1376

1379 if (lhsType != rhsType &&

1381 Diag(PropertyDiagLoc, diag::err_property_ivar_type)

1382 << property->getDeclName() << PropType

1385

1386 }

1387 }

1388

1391 Diag(PropertyDiagLoc, diag::err_weak_property)

1392 << property->getDeclName() << Ivar->getDeclName();

1394

1395 }

1396

1397 if ((property->getType()->isObjCObjectPointerType() ||

1400 Diag(PropertyDiagLoc, diag::err_strong_property)

1401 << property->getDeclName() << Ivar->getDeclName();

1402

1403 }

1404 }

1405 if (getLangOpts().ObjCAutoRefCount || isARCWeak ||

1408 } else if (PropertyIvar)

1409

1410 Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);

1411

1412 assert (property && "ActOnPropertyImplDecl - property declaration missing");

1414 Context, SemaRef.CurContext, AtLoc, PropertyLoc, property,

1417 Ivar, PropertyIvarLoc);

1418

1419 if (CompleteTypeErr || !compat)

1421

1422 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {

1423 getterMethod->createImplicitParams(Context, IDecl);

1424

1425

1426 if (Synthesize) {

1427

1429 getterMethod->getSelector(), getterMethod->isInstanceMethod());

1430 if (!OMD)

1432 PropertyLoc);

1434 }

1435

1438

1439

1440

1445 PropertyDiagLoc);

1446 SemaRef.MarkDeclRefReferenced(SelfExpr);

1448 Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,

1450 Expr *IvarRefExpr =

1453 PropertyDiagLoc,

1455 LoadSelfExpr, true, true);

1458 getterMethod->getReturnType()),

1459 PropertyDiagLoc, IvarRefExpr);

1462 if (ResExpr)

1463 ResExpr = SemaRef.MaybeCreateExprWithCleanups(ResExpr);

1465 }

1466 }

1467 if (property->hasAttr() &&

1468 !getterMethod->hasAttr()) {

1469 Diag(getterMethod->getLocation(),

1470 diag::warn_property_getter_owning_mismatch);

1471 Diag(property->getLocation(), diag::note_property_declare);

1472 }

1473 if (getLangOpts().ObjCAutoRefCount && Synthesize)

1474 switch (getterMethod->getMethodFamily()) {

1479 Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)

1480 << 1 << getterMethod->getSelector();

1481 break;

1482 default:

1483 break;

1484 }

1485 }

1486

1487 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {

1488 setterMethod->createImplicitParams(Context, IDecl);

1489

1490

1491 if (Synthesize) {

1493 setterMethod->getSelector(), setterMethod->isInstanceMethod());

1494 if (!OMD)

1496 AtLoc, PropertyLoc);

1498 }

1499

1502

1507 PropertyDiagLoc);

1508 SemaRef.MarkDeclRefReferenced(SelfExpr);

1510 Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,

1515 PropertyDiagLoc,

1517 LoadSelfExpr, true, true);

1520 QualType T = Param->getType().getNonReferenceType();

1523 SemaRef.MarkDeclRefReferenced(rhs);

1525 SemaRef.BuildBinOp(S, PropertyDiagLoc, BO_Assign, lhs, rhs);

1526 if (property->getPropertyAttributes() &

1530 dyn_cast_or_null(callExpr))

1531 if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())

1532 if (!FuncDecl->isTrivial())

1533 if (property->getType()->isReferenceType()) {

1534 Diag(PropertyDiagLoc,

1535 diag::err_atomic_property_nontrivial_assign_op)

1536 << property->getType();

1537 Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)

1538 << FuncDecl;

1539 }

1540 }

1542 }

1543 }

1544

1545 if (IC) {

1546 if (Synthesize)

1549 Diag(PropertyLoc, diag::err_duplicate_ivar_use)

1550 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()

1551 << PropertyIvar;

1552 Diag(PPIDecl->getLocation(), diag::note_previous_use);

1553 }

1554

1557 Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;

1558 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);

1559 return nullptr;

1560 }

1562 if (getLangOpts().ObjCDefaultSynthProperties &&

1565

1566

1567

1570 if (!Synthesize)

1572 else {

1573 if (PropertyIvar && PropertyIvar != PropertyId)

1575 }

1576

1580 << PropertyId;

1582 }

1583 }

1584 } else {

1585 if (Synthesize)

1588 Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)

1589 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()

1590 << PropertyIvar;

1591 Diag(PPIDecl->getLocation(), diag::note_previous_use);

1592 }

1593

1596 Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;

1597 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);

1598 return nullptr;

1599 }

1601 }

1602

1606 Diag(PropertyLoc, diag::err_objc_direct_dynamic_property);

1608 diag::note_previous_declaration);

1609 return nullptr;

1610 }

1611

1612 return PIDecl;

1613}

1614

1615

1616

1617

1618

1619

1620

1621

1625 bool OverridingProtocolProperty) {

1629

1630

1631

1632

1633 if (!OverridingProtocolProperty &&

1635 ;

1636 else {

1639 Diag(Property->getLocation(), diag::warn_readonly_property)

1640 << Property->getDeclName() << inheritedName;

1643 Diag(Property->getLocation(), diag::warn_property_attribute)

1644 << Property->getDeclName() << "copy" << inheritedName;

1650 bool CStrong = (CAttrRetain != 0);

1651 bool SStrong = (SAttrRetain != 0);

1652 if (CStrong != SStrong)

1653 Diag(Property->getLocation(), diag::warn_property_attribute)

1654 << Property->getDeclName() << "retain (or strong)" << inheritedName;

1655 }

1656 }

1657

1658

1659

1660

1662

1663

1667 Diag(Property->getLocation(), diag::warn_property_attribute)

1668 << Property->getDeclName() << "setter" << inheritedName;

1669 Diag(SuperProperty->getLocation(), diag::note_property_declare);

1670 }

1672 Diag(Property->getLocation(), diag::warn_property_attribute)

1673 << Property->getDeclName() << "getter" << inheritedName;

1674 Diag(SuperProperty->getLocation(), diag::note_property_declare);

1675 }

1676

1681

1682 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) {

1683

1684

1685 bool IncompatibleObjC = false;

1687 if (SemaRef.isObjCPointerConversion(RHSType, LHSType, ConvertedType,

1688 IncompatibleObjC) ||

1689 IncompatibleObjC) {

1690 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)

1691 << Property->getType() << SuperProperty->getType() << inheritedName;

1692 Diag(SuperProperty->getLocation(), diag::note_property_declare);

1693 }

1694 }

1695}

1696

1701 if (!GetterMethod)

1702 return false;

1704 QualType PropertyRValueType =

1705 property->getType().getNonReferenceType().getAtomicUnqualifiedType();

1706 bool compat = Context.hasSameType(PropertyRValueType, GetterType);

1707 if (!compat) {

1710 if ((propertyObjCPtr =

1713 compat = Context.canAssignObjCInterfaces(getterObjCPtr, propertyObjCPtr);

1714 else if (SemaRef.IsAssignConvertCompatible(

1715 SemaRef.CheckAssignmentConstraints(Loc, GetterType,

1716 PropertyRValueType))) {

1717 Diag(Loc, diag::err_property_accessor_type)

1718 << property->getDeclName() << PropertyRValueType

1719 << GetterMethod->getSelector() << GetterType;

1720 Diag(GetterMethod->getLocation(), diag::note_declared_at);

1721 return true;

1722 } else {

1723 compat = true;

1727 compat = false;

1728 }

1729 }

1730

1731 if (!compat) {

1732 Diag(Loc, diag::warn_accessor_property_type_mismatch)

1733 << property->getDeclName()

1735 Diag(GetterMethod->getLocation(), diag::note_declared_at);

1736 return true;

1737 }

1738

1739 return false;

1740}

1741

1742

1743

1744static void

1748 bool CollectClassPropsOnly = false,

1749 bool IncludeProtocols = true) {

1750 if (ObjCInterfaceDecl *IDecl = dyn_cast(CDecl)) {

1751 for (auto *Prop : IDecl->properties()) {

1752 if (CollectClassPropsOnly && !Prop->isClassProperty())

1753 continue;

1754 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =

1755 Prop;

1756 }

1757

1758

1759 for (auto *Ext : IDecl->visible_extensions())

1761 CollectClassPropsOnly, IncludeProtocols);

1762

1763 if (IncludeProtocols) {

1764

1765 for (auto *PI : IDecl->all_referenced_protocols())

1767 CollectClassPropsOnly);

1768 }

1769 }

1770 if (ObjCCategoryDecl *CATDecl = dyn_cast(CDecl)) {

1771 for (auto *Prop : CATDecl->properties()) {

1772 if (CollectClassPropsOnly && !Prop->isClassProperty())

1773 continue;

1774 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =

1775 Prop;

1776 }

1777 if (IncludeProtocols) {

1778

1779 for (auto *PI : CATDecl->protocols())

1781 CollectClassPropsOnly);

1782 }

1783 }

1784 else if (ObjCProtocolDecl *PDecl = dyn_cast(CDecl)) {

1785 for (auto *Prop : PDecl->properties()) {

1786 if (CollectClassPropsOnly && !Prop->isClassProperty())

1787 continue;

1789 SuperPropMap[std::make_pair(Prop->getIdentifier(),

1790 Prop->isClassProperty())];

1791

1792

1793 if (!PropertyFromSuper ||

1794 PropertyFromSuper->getIdentifier() != Prop->getIdentifier()) {

1796 PropMap[std::make_pair(Prop->getIdentifier(),

1797 Prop->isClassProperty())];

1798 if (!PropEntry)

1799 PropEntry = Prop;

1800 }

1801 }

1802

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

1805 CollectClassPropsOnly);

1806 }

1807}

1808

1809

1810

1811

1815 while (SDecl) {

1816 SDecl->collectPropertiesToImplement(PropMap);

1817 SDecl = SDecl->getSuperClass();

1818 }

1819 }

1820}

1821

1822

1823

1824

1829 return false;

1831 Method->isInstanceMethod());

1833 return false;

1834

1835

1836

1840 (Property->getPropertyIvarDecl() == IV))

1841 return true;

1842 }

1843

1844

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

1849 (Property->getPropertyIvarDecl() == IV))

1850 return true;

1851 return false;

1852}

1853

1856 bool SuperClassImplementsGetter = false;

1857 bool SuperClassImplementsSetter = false;

1859 SuperClassImplementsSetter = true;

1860

1864 SuperClassImplementsGetter = true;

1865

1867 SuperClassImplementsSetter = true;

1868 if (SuperClassImplementsGetter && SuperClassImplementsSetter)

1869 return true;

1871 }

1872 return false;

1873}

1874

1875

1876

1883 if (PropMap.empty())

1884 return;

1887

1888 for (const auto &PropEntry : PropMap) {

1890

1894 continue;

1895

1898 continue;

1900 if (ImpMethod && !ImpMethod->getBody()) {

1902 continue;

1904 if (ImpMethod && !ImpMethod->getBody())

1905 continue;

1906 }

1909 Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)

1911 if (PID->getLocation().isValid())

1912 Diag(PID->getLocation(), diag::note_property_synthesize);

1913 continue;

1914 }

1916 SuperPropMap[std::make_pair(Prop->getIdentifier(),

1919 dyn_cast(Prop->getDeclContext())) {

1920

1921

1922

1923

1926 diag::warn_auto_synthesizing_protocol_property)

1927 << Prop << Proto;

1929 std::string FixIt =

1930 (Twine("@synthesize ") + Prop->getName() + ";\n\n").str();

1931 Diag(AtEnd, diag::note_add_synthesize_directive)

1933 }

1934 continue;

1935 }

1936

1937 if (PropInSuperClass) {

1944 Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)

1946 Diag(PropInSuperClass->getLocation(), diag::note_property_declare);

1947 } else {

1948 Diag(Prop->getLocation(), diag::warn_autosynthesis_property_in_superclass)

1950 Diag(PropInSuperClass->getLocation(), diag::note_property_declare);

1951 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);

1952 }

1953 continue;

1954 }

1955

1956

1957

1958

1961 true,

1966 Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis);

1967 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);

1968 }

1969 }

1970}

1971

1974 if (getLangOpts().ObjCDefaultSynthProperties ||

1976 return;

1978 if (!IC)

1979 return;

1981 if (!IDecl->isObjCRequiresPropertyDefs())

1983}

1984

1990

1991

1995 });

1996

1997

1998

1999

2000 if (I == SMap.end() &&

2001 (PrimaryClass == nullptr ||

2004 unsigned diag =

2007 ? diag::warn_impl_required_in_category_for_class_property

2008 : diag::warn_setter_getter_impl_required_in_category)

2010 ? diag::warn_impl_required_for_class_property

2011 : diag::warn_setter_getter_impl_required);

2013 S.Diag(Prop->getLocation(), diag::note_property_declare);

2014 if (S.LangOpts.ObjCDefaultSynthProperties &&

2018 S.Diag(RID->getLocation(), diag::note_suppressed_class_declare);

2019 }

2020}

2021

2024 bool SynthesizeProperties) {

2027

2028

2029

2031

2032

2033 if (!IDecl)

2035

2036

2037

2038 if ((IDecl = C->getClassInterface())) {

2040 }

2041 }

2042 if (IDecl)

2044

2045

2047 SynthesizeProperties);

2048

2049

2050

2051

2052 if (IDecl) {

2053 std::unique_ptrObjCContainerDecl::PropertyMap LazyMap;

2054

2056 if (!PDecl->hasAttr())

2057 continue;

2058

2059

2060

2061

2062

2063

2064

2065 if (!LazyMap) {

2069 false,

2070 false);

2071 }

2072

2073

2074 for (auto *PropDecl : PDecl->properties()) {

2075 if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),

2076 PropDecl->isClassProperty())])

2077 continue;

2078 PropMap[std::make_pair(PropDecl->getIdentifier(),

2079 PropDecl->isClassProperty())] = PropDecl;

2080 }

2081 }

2082 }

2083

2084 if (PropMap.empty())

2085 return;

2086

2087 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;

2089 PropImplMap.insert(I->getPropertyDecl());

2090

2091

2094

2097 if (C && C->IsClassExtension())

2098 if ((PrimaryClass = C->getClassInterface()))

2099

2101

2102

2103

2104 InsMap.insert_range(IMP->methods());

2105 }

2106

2107 for (ObjCContainerDecl::PropertyMap::iterator

2108 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {

2110

2113 PropImplMap.count(Prop) ||

2115 continue;

2116

2117

2119 IMPDecl, CDecl, C, Prop, InsMap);

2123 Prop, InsMap);

2124 }

2125}

2126

2129 for (const auto *propertyImpl : impDecl->property_impls()) {

2130 const auto *property = propertyImpl->getPropertyDecl();

2131

2132

2133 if (propertyImpl->getPropertyImplementation() ==

2135 (property->getPropertyAttributes() &

2137 property->getGetterMethodDecl() && property->getSetterMethodDecl()) {

2138 auto *getterImpl = propertyImpl->getGetterMethodDecl();

2139 auto *setterImpl = propertyImpl->getSetterMethodDecl();

2140 if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&

2141 (!setterImpl || setterImpl->isSynthesizedAccessorStub())) {

2145

2146 Diag(loc, diag::warn_null_resettable_setter)

2147 << setterImpl->getSelector() << property->getDeclName();

2148 }

2149 }

2150 }

2151}

2152

2155

2157 return;

2159 for (auto *Prop : IDecl->properties())

2160 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;

2162 for (auto *Prop : Ext->properties())

2163 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;

2164

2165 for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();

2166 I != E; ++I) {

2170

2171 unsigned Attributes = Property->getPropertyAttributes();

2172 unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten();

2173

2176 GetterMethod = Property->isClassProperty() ?

2179 SetterMethod = Property->isClassProperty() ?

2183 GetterMethod = nullptr;

2185 SetterMethod = nullptr;

2186 if (GetterMethod) {

2188 diag::warn_default_atomic_custom_getter_setter)

2189 << Property->getIdentifier() << 0;

2190 Diag(Property->getLocation(), diag::note_property_declare);

2191 }

2192 if (SetterMethod) {

2194 diag::warn_default_atomic_custom_getter_setter)

2195 << Property->getIdentifier() << 1;

2196 Diag(Property->getLocation(), diag::note_property_declare);

2197 }

2198 }

2199

2200

2203 continue;

2207 continue;

2208 GetterMethod = PIDecl->getGetterMethodDecl();

2209 SetterMethod = PIDecl->getSetterMethodDecl();

2211 GetterMethod = nullptr;

2213 SetterMethod = nullptr;

2214 if ((bool)GetterMethod ^ (bool)SetterMethod) {

2216 (GetterMethod ? GetterMethod->getLocation()

2217 : SetterMethod->getLocation());

2218 Diag(MethodLoc, diag::warn_atomic_property_rule)

2219 << Property->getIdentifier() << (GetterMethod != nullptr)

2220 << (SetterMethod != nullptr);

2221

2222 if (Property->getLParenLoc().isValid() &&

2224

2227 StringRef NonatomicStr = AttributesAsWritten? "nonatomic, "

2228 : "nonatomic";

2230 diag::note_atomic_property_fixup_suggest)

2232 } else if (Property->getLParenLoc().isInvalid()) {

2233

2235 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();

2237 diag::note_atomic_property_fixup_suggest)

2239 } else

2240 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);

2241 Diag(Property->getLocation(), diag::note_property_declare);

2242 }

2243 }

2244 }

2245}

2246

2250 return;

2251

2254 if (PD && !PD->hasAttr() &&

2258 continue;

2260 if (!method)

2261 continue;

2266 Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule);

2267 else

2268 Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule);

2269

2270

2271

2274 for (auto *getterRedecl : method->redecls()) {

2275 if (getterRedecl->isImplicit())

2276 continue;

2277 if (getterRedecl->getDeclContext() != PD->getDeclContext())

2278 continue;

2279 noteLoc = getterRedecl->getLocation();

2280 fixItLoc = getterRedecl->getEndLoc();

2281 }

2282

2285 tok::kw___attribute, tok::l_paren, tok::l_paren,

2288 tok::r_paren, tok::r_paren

2289 };

2290 StringRef spelling = "__attribute__((objc_method_family(none)))";

2292 if (!macroName.empty())

2293 spelling = macroName;

2294

2295 auto noteDiag = Diag(noteLoc, diag::note_cocoa_naming_declare_family)

2297 if (fixItLoc.isValid()) {

2299 fixItText += spelling;

2301 }

2302 }

2303 }

2304 }

2305}

2306

2311 if (!SuperD)

2312 return;

2313

2316 if (I->getMethodFamily() == OMF_init)

2317 InitSelSet.insert(I->getSelector());

2318

2322 I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {

2324 if (!InitSelSet.count(MD->getSelector())) {

2325

2326

2327 bool Ignore = false;

2329 Ignore = IMD->isUnavailable();

2330 } else {

2331

2333 if (auto *IMD = Ext->getInstanceMethod(MD->getSelector())) {

2334 Ignore = IMD->isUnavailable();

2335 break;

2336 }

2337 }

2338 if (!Ignore) {

2340 diag::warn_objc_implementation_missing_designated_init_override)

2342 Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here);

2343 }

2344 }

2345 }

2346}

2347

2348

2349

2352

2353 for (const auto *A : Property->attrs()) {

2358 }

2359}

2360

2361

2362

2363

2364

2370 return;

2371

2372 bool IsClassProperty = property->isClassProperty();

2373 GetterMethod = IsClassProperty ?

2376

2377

2378

2379 if (!GetterMethod)

2380 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD))

2381 if (CatDecl->IsClassExtension())

2382 GetterMethod = IsClassProperty ? CatDecl->getClassInterface()->

2384 CatDecl->getClassInterface()->

2386

2387 SetterMethod = IsClassProperty ?

2390 if (!SetterMethod)

2391 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD))

2392 if (CatDecl->IsClassExtension())

2393 SetterMethod = IsClassProperty ? CatDecl->getClassInterface()->

2395 CatDecl->getClassInterface()->

2399

2400

2401

2402 if (!GetterMethod) {

2403 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD)) {

2404 auto *ExistingGetter = CatDecl->getClassInterface()->lookupMethod(

2405 property->getGetterName(), !IsClassProperty, true, false, CatDecl);

2406 if (ExistingGetter) {

2407 if (ExistingGetter->isDirectMethod() || property->isDirectProperty()) {

2408 Diag(property->getLocation(), diag::err_objc_direct_duplicate_decl)

2409 << property->isDirectProperty() << 1

2410 << ExistingGetter->isDirectMethod()

2411 << ExistingGetter->getDeclName();

2412 Diag(ExistingGetter->getLocation(), diag::note_previous_declaration);

2413 }

2414 }

2415 }

2416 }

2417

2418 if (!property->isReadOnly() && !SetterMethod) {

2419 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD)) {

2420 auto *ExistingSetter = CatDecl->getClassInterface()->lookupMethod(

2421 property->getSetterName(), !IsClassProperty, true, false, CatDecl);

2422 if (ExistingSetter) {

2423 if (ExistingSetter->isDirectMethod() || property->isDirectProperty()) {

2424 Diag(property->getLocation(), diag::err_objc_direct_duplicate_decl)

2425 << property->isDirectProperty() << 1

2426 << ExistingSetter->isDirectMethod()

2427 << ExistingSetter->getDeclName();

2428 Diag(ExistingSetter->getLocation(), diag::note_previous_declaration);

2429 }

2430 }

2431 }

2432 }

2433

2434 if (!property->isReadOnly() && SetterMethod) {

2435 if (Context.getCanonicalType(SetterMethod->getReturnType()) !=

2436 Context.VoidTy)

2437 Diag(SetterMethod->getLocation(), diag::err_setter_type_void);

2438 if (SetterMethod->param_size() != 1 ||

2439 !Context.hasSameUnqualifiedType(

2440 (*SetterMethod->param_begin())->getType().getNonReferenceType(),

2443 diag::warn_accessor_property_type_mismatch)

2444 << property->getDeclName()

2446 Diag(SetterMethod->getLocation(), diag::note_declared_at);

2447 }

2448 }

2449

2450

2451

2452

2453

2454

2455

2456 if (!GetterMethod) {

2457

2458

2459

2461

2462

2463

2464 QualType resultTy = property->getType().getAtomicUnqualifiedType();

2465

2466

2469 QualType modifiedTy = resultTy;

2470 if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {

2473 modifiedTy, modifiedTy);

2474 }

2475 }

2476

2478 Context, Loc, Loc, property->getGetterName(), resultTy, nullptr, CD,

2479 !IsClassProperty, false,

2480 true, false,

2481 true, false,

2485 CD->addDecl(GetterMethod);

2486

2488

2490 GetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));

2491

2492 if (property->hasAttr())

2493 GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,

2494 Loc));

2495

2496 if (property->hasAttr())

2498 ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));

2499

2500 if (const SectionAttr *SA = property->getAttr())

2501 GetterMethod->addAttr(SectionAttr::CreateImplicit(

2502 Context, SA->getName(), Loc, SectionAttr::GNU_section));

2503

2504 SemaRef.ProcessAPINotes(GetterMethod);

2505

2508 } else

2509

2510

2512

2515 property->setGetterMethodDecl(GetterMethod);

2516

2517

2519

2520 if (!SetterMethod) {

2521

2522

2523

2524

2526

2528 Context, Loc, Loc, property->getSetterName(), Context.VoidTy, nullptr,

2529 CD, !IsClassProperty,

2530 false,

2531 true,

2532 false,

2533 true,

2534 false,

2538

2539

2541 property->getType().getUnqualifiedType().getAtomicUnqualifiedType();

2542

2543

2544

2547 QualType modifiedTy = paramTy;

2548 if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){

2551 modifiedTy, modifiedTy);

2552 }

2553 }

2554

2555

2556

2558 Loc, Loc,

2560 paramTy,

2561 nullptr,

2563 nullptr);

2565

2567

2569 SetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));

2570

2571 CD->addDecl(SetterMethod);

2572 if (const SectionAttr *SA = property->getAttr())

2573 SetterMethod->addAttr(SectionAttr::CreateImplicit(

2574 Context, SA->getName(), Loc, SectionAttr::GNU_section));

2575

2576 SemaRef.ProcessAPINotes(SetterMethod);

2577

2578

2579

2582 } else

2583

2584

2586

2589 property->setSetterMethodDecl(SetterMethod);

2590 }

2591

2592

2593

2594

2595

2596

2597

2598

2599

2600

2601

2602

2603 if (!IsClassProperty) {

2604 if (GetterMethod)

2606 if (SetterMethod)

2608 } else {

2609 if (GetterMethod)

2611 if (SetterMethod)

2613 }

2614

2615 ObjCInterfaceDecl *CurrentClass = dyn_cast(CD);

2616 if (!CurrentClass) {

2618 CurrentClass = Cat->getClassInterface();

2619 else if (ObjCImplDecl *Impl = dyn_cast(CD))

2620 CurrentClass = Impl->getClassInterface();

2621 }

2622 if (GetterMethod)

2624 if (SetterMethod)

2626}

2627

2629 unsigned &Attributes,

2630 bool propertyInPrimaryClass) {

2631

2633 return;

2634

2637 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2638 << "readonly" << "readwrite";

2639

2642

2643

2644 if ((Attributes &

2649 !PropertyDecl->hasAttr()) {

2650 Diag(Loc, diag::err_objc_property_requires_object)

2652 ? "weak"

2654 ? "copy"

2655 : "retain (or strong)");

2656 Attributes &=

2661 }

2662

2663

2668 Diag(Loc, diag::warn_objc_property_assign_on_object);

2669 }

2670

2671

2674 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2675 << "assign" << "copy";

2677 }

2679 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2680 << "assign" << "retain";

2682 }

2684 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2685 << "assign" << "strong";

2687 }

2690 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2691 << "assign" << "weak";

2693 }

2694 if (PropertyDecl->hasAttr())

2695 Diag(Loc, diag::warn_iboutletcollection_property_assign);

2698 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2699 << "unsafe_unretained" << "copy";

2701 }

2703 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2704 << "unsafe_unretained" << "retain";

2706 }

2708 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2709 << "unsafe_unretained" << "strong";

2711 }

2714 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2715 << "unsafe_unretained" << "weak";

2717 }

2720 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2721 << "copy" << "retain";

2723 }

2725 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2726 << "copy" << "strong";

2728 }

2730 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2731 << "copy" << "weak";

2733 }

2736 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "retain"

2737 << "weak";

2741 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "strong"

2742 << "weak";

2744 }

2745

2747

2748 if (auto nullability = PropertyTy->getNullability()) {

2750 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2751 << "nonnull" << "weak";

2752 }

2753 }

2754

2757 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "atomic"

2758 << "nonatomic";

2760 }

2761

2762

2763

2766

2767 } else if (getLangOpts().ObjCAutoRefCount) {

2768

2769

2774

2775

2777 ;

2778 else if (propertyInPrimaryClass) {

2779

2780

2781

2783 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);

2784

2785

2787 Diag(Loc, diag::warn_objc_property_default_assign_on_object);

2788 }

2789 }

2790

2791

2792

2793 }

2794

2799 Diag(Loc, diag::warn_objc_property_copy_missing_on_block);

2804 Diag(Loc, diag::warn_objc_property_retain_of_block);

2805

2808 Diag(Loc, diag::warn_objc_readonly_property_has_setter);

2809}

llvm::DenseMap< const Stmt *, CFGBlock * > SMap

Defines the clang::Expr interface and subclasses for C++ expressions.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

Defines the clang::Preprocessor interface.

static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, ObjCPropertyDecl *Prop)

Definition SemaObjCProperty.cpp:1854

static bool areIncompatiblePropertyAttributes(unsigned Attr1, unsigned Attr2, unsigned Kinds)

Definition SemaObjCProperty.cpp:813

static Qualifiers::ObjCLifetime getImpliedARCOwnership(ObjCPropertyAttribute::Kind attrs, QualType type)

getImpliedARCOwnership - Given a set of property attributes and a type, infer an expected lifetime.

Definition SemaObjCProperty.cpp:38

static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, ObjCPropertyDecl *property, ObjCIvarDecl *ivar)

Definition SemaObjCProperty.cpp:707

static bool LocPropertyAttribute(ASTContext &Context, const char *attrName, SourceLocation LParenLoc, SourceLocation &Loc)

Definition SemaObjCProperty.cpp:307

static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, ObjCPropertyDecl *Property)

AddPropertyAttrs - Propagates attributes from a property to the implicitly-declared getter or setter ...

Definition SemaObjCProperty.cpp:2350

static void checkPropertyDeclWithOwnership(Sema &S, ObjCPropertyDecl *property)

Check the internal consistency of a property declaration with an explicit ownership qualifier.

Definition SemaObjCProperty.cpp:63

static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T)

Definition SemaObjCProperty.cpp:126

static void CollectImmediateProperties(ObjCContainerDecl *CDecl, ObjCContainerDecl::PropertyMap &PropMap, ObjCContainerDecl::PropertyMap &SuperPropMap, bool CollectClassPropsOnly=false, bool IncludeProtocols=true)

CollectImmediateProperties - This routine collects all properties in the class and its conforming pro...

Definition SemaObjCProperty.cpp:1745

static void checkAtomicPropertyMismatch(Sema &S, ObjCPropertyDecl *OldProperty, ObjCPropertyDecl *NewProperty, bool PropagateAtomicity)

Check for a mismatch in the atomicity of the given properties.

Definition SemaObjCProperty.cpp:337

static void setImpliedPropertyAttributeForReadOnlyProperty(ObjCPropertyDecl *property, ObjCIvarDecl *ivar)

setImpliedPropertyAttributeForReadOnlyProperty - This routine evaludates life-time attributes for a '...

Definition SemaObjCProperty.cpp:786

static unsigned getOwnershipRule(unsigned attr)

Definition SemaObjCProperty.cpp:158

static ObjCMethodDecl * RedeclarePropertyAccessor(ASTContext &Context, ObjCImplementationDecl *Impl, ObjCMethodDecl *AccessorDecl, SourceLocation AtLoc, SourceLocation PropertyLoc)

Create a synthesized property accessor stub inside the @implementation.

Definition SemaObjCProperty.cpp:1034

static bool hasWrittenStorageAttribute(ObjCPropertyDecl *Prop, ObjCPropertyQueryKind QueryKind)

Determine whether any storage attributes were written on the property.

Definition SemaObjCProperty.cpp:1000

static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, ObjCInterfaceDecl::PropertyMap &PropMap)

CollectSuperClassPropertyImplementations - This routine collects list of properties to be implemented...

Definition SemaObjCProperty.cpp:1812

static const unsigned OwnershipMask

Definition SemaObjCProperty.cpp:152

static void DiagnoseUnimplementedAccessor(Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C, ObjCPropertyDecl *Prop, llvm::SmallPtrSet< const ObjCMethodDecl *, 8 > &SMap)

Definition SemaObjCProperty.cpp:1985

static ObjCPropertyDecl * SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc, ObjCInterfaceDecl *ClassDecl, ObjCPropertyDecl *Property)

SelectPropertyForSynthesisFromProtocols - Finds the most appropriate property declaration that should...

Definition SemaObjCProperty.cpp:824

static void CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop, ObjCProtocolDecl *Proto, llvm::SmallPtrSetImpl< ObjCProtocolDecl * > &Known)

Check this Objective-C property against a property declared in the given protocol.

Definition SemaObjCProperty.cpp:106

static ObjCPropertyAttribute::Kind makePropertyAttributesAsWritten(unsigned Attributes)

Definition SemaObjCProperty.cpp:273

static bool isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2, ObjCPropertyAttribute::Kind Kind)

Definition SemaObjCProperty.cpp:808

This file declares semantic analysis for Objective-C.

Defines the SourceManager interface.

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

static CanQualType getCanonicalType(QualType T)

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

bool propertyTypesAreCompatible(QualType, QualType)

QualType getQualifiedType(SplitQualType split) const

Un-split a SplitQualType.

Attr - This represents one attribute.

A call to an overloaded operator written using operator syntax.

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

void makeDeclVisibleInContext(NamedDecl *D)

Makes a declaration visible within this context.

DeclContextLookupResult lookup_result

void addDecl(Decl *D)

Add the declaration D into this context.

A reference to a declared variable, function, enum, etc.

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

SourceLocation getEndLoc() const LLVM_READONLY

bool isImplicit() const

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

void setAttrs(const AttrVec &Attrs)

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 isInvalidDecl() const

SourceLocation getLocation() const

redecl_range redecls() const

Returns an iterator range for all the redeclarations of the same decl.

DeclContext * getDeclContext()

SourceLocation getBeginLoc() const LLVM_READONLY

void setLexicalDeclContext(DeclContext *DC)

SourceLocation getIdentifierLoc() const

void setObjCWeakProperty(bool Val=true)

const IdentifierInfo * getIdentifier() const

This represents one expression.

Represents difference between two FPOptions values.

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 CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)

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

Represents a function declaration or definition.

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

static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)

static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)

Create the initialization entity for the result of a function.

clang::ObjCRuntime ObjCRuntime

Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.

bool LexFromRawLexer(Token &Result)

LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...

IdentifierInfo * getIdentifier() const

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

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

DeclarationName getDeclName() const

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

ObjCCategoryDecl - Represents a category declaration.

ObjCInterfaceDecl * getClassInterface()

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

ObjCContainerDecl - Represents a container for method declarations.

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

method_range methods() const

instmeth_range instance_methods() const

llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet

ObjCPropertyDecl * getProperty(const IdentifierInfo *Id, bool IsInstance) const

instprop_range instance_properties() const

llvm::MapVector< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap

ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const

FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...

llvm::SmallVector< ObjCPropertyDecl *, 8 > PropertyDeclOrder

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

prop_range properties() const

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

bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const

This routine returns 'true' if a user declared setter method was found in the class,...

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

ObjCPropertyAttribute::Kind getPropertyAttributes() const

SourceLocation getGetterNameLoc() const

SourceLocation getSetterNameLoc() const

void addPropertyImplementation(ObjCPropertyImplDecl *property)

propimpl_range property_impls() const

ObjCPropertyImplDecl * FindPropertyImplDecl(IdentifierInfo *propertyId, ObjCPropertyQueryKind queryKind) const

FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl added to the list of thos...

const ObjCInterfaceDecl * getClassInterface() const

ObjCPropertyImplDecl * FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const

FindPropertyImplIvarDecl - This method lookup the ivar in the list of properties implemented in this ...

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

Represents an ObjC class declaration.

ObjCPropertyDecl * FindPropertyVisibleInPrimaryClass(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const

FindPropertyVisibleInPrimaryClass - Finds declaration of the property with name 'PropertyId' in the p...

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

all_protocol_range all_referenced_protocols() const

visible_extensions_range visible_extensions() const

ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const

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

protocol_range protocols() const

const ObjCInterfaceDecl * isObjCRequiresPropertyDefs() const

isObjCRequiresPropertyDefs - Checks that a class or one of its super classes must not be auto-synthes...

ObjCMethodDecl * lookupPropertyAccessor(const Selector Sel, const ObjCCategoryDecl *Cat, bool IsClassProperty) const

Lookup a setter or getter in the class hierarchy, including in all categories except for category pas...

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

bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, bool lookupCategory, bool RHSIsQualifiedID=false)

ClassImplementsProtocol - Checks that 'lProto' protocol has been implemented in IDecl class,...

ObjCImplementationDecl * getImplementation() const

bool hasDesignatedInitializers() const

Returns true if this interface decl contains at least one initializer marked with the 'objc_designate...

void getDesignatedInitializers(llvm::SmallVectorImpl< const ObjCMethodDecl * > &Methods) const

Returns the designated initializers for the interface.

void collectPropertiesToImplement(PropertyMap &PM) const override

This routine collects list of properties to be implemented in the class.

bool isArcWeakrefUnavailable() const

isArcWeakrefUnavailable - Checks for a class or one of its super classes to be incompatible with __we...

ObjCInterfaceDecl * getSuperClass() const

known_extensions_range known_extensions() const

ObjCIvarDecl - Represents an ObjC instance variable.

AccessControl getAccessControl() const

bool getSynthesize() const

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)

QualType getUsageType(QualType objectType) const

Retrieve the type of this instance variable when viewed as a member of a specific object type.

ObjCIvarRefExpr - A reference to an ObjC instance variable.

ObjCMethodDecl - Represents an instance or class method declaration.

void setDefined(bool isDefined)

unsigned param_size() const

void setSelfDecl(ImplicitParamDecl *SD)

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)

param_const_iterator param_begin() const

void setCmdDecl(ImplicitParamDecl *CD)

Stmt * getBody() const override

Retrieve the body of this method, if it has one.

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

Sets the method's parameters and selector source locations.

bool isSynthesizedAccessorStub() const

void setPropertyAccessor(bool isAccessor)

Selector getSelector() const

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

bool isClassMethod() const

ObjCInterfaceDecl * getClassInterface()

Represents a pointer to an Objective C object.

Represents one property declaration in an Objective-C interface.

ObjCPropertyQueryKind getQueryKind() const

bool isClassProperty() const

void setPropertyImplementation(PropertyControl pc)

void setSetterName(Selector Sel, SourceLocation Loc=SourceLocation())

ObjCMethodDecl * getGetterMethodDecl() const

bool isInstanceProperty() const

void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal)

bool isReadOnly() const

isReadOnly - Return true iff the property has a setter.

static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)

Lookup a property by name in the specified DeclContext.

bool isDirectProperty() const

Selector getSetterName() const

void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal)

void overwritePropertyAttributes(unsigned PRVal)

Selector getGetterName() const

ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const

IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const

Get the default name of the synthesized ivar.

ObjCPropertyAttribute::Kind getPropertyAttributes() const

static ObjCPropertyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, TypeSourceInfo *TSI, PropertyControl propControl=None)

void setGetterName(Selector Sel, SourceLocation Loc=SourceLocation())

PropertyControl getPropertyImplementation() const

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

Kind getPropertyImplementation() const

void setSetterMethodDecl(ObjCMethodDecl *MD)

ObjCPropertyDecl * getPropertyDecl() const

void setSetterCXXAssignment(Expr *setterCXXAssignment)

static ObjCPropertyImplDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc)

void setGetterMethodDecl(ObjCMethodDecl *MD)

void setGetterCXXConstructor(Expr *getterCXXConstructor)

Represents an Objective-C protocol declaration.

ObjCProtocolDecl * getDefinition()

Retrieve the definition of this protocol, if any.

protocol_range protocols() const

The basic abstraction for the target Objective-C runtime.

bool isNonFragile() const

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

bool allowsDirectDispatch() const

Does this runtime supports direct dispatch.

bool isFragile() const

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

Represents a parameter to a function.

static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const

Return the name of the macro defined before Loc that has spelling Tokens.

A (possibly-)qualified type.

PointerAuthQualifier getPointerAuth() const

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

Qualifiers::ObjCLifetime getObjCLifetime() const

Returns lifetime attribute of this type.

QualType getNonReferenceType() const

If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...

QualType getCanonicalType() const

QualType getUnqualifiedType() const

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

SplitQualType split() const

Divides a QualType into its unqualified type and a set of local qualifiers.

bool isObjCGCStrong() const

true when Type is objc's strong.

bool isObjCGCWeak() const

true when Type is objc's weak.

The collection of all-type qualifiers we support.

@ OCL_Strong

Assigning into this object requires the old value to be released and the new value to be retained.

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

bool hasObjCLifetime() const

void addObjCLifetime(ObjCLifetime type)

void setObjCLifetime(ObjCLifetime type)

bool hasFlexibleArrayMember() const

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

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

ASTContext & getASTContext() const

const LangOptions & getLangOpts() const

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Emit a diagnostic.

void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl, SourceLocation AtEnd)

DefaultSynthesizeProperties - This routine default synthesizes all properties which must be synthesiz...

Definition SemaObjCProperty.cpp:1877

bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)

Definition SemaObjCProperty.cpp:1697

void ProcessPropertyDecl(ObjCPropertyDecl *property)

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

Definition SemaObjCProperty.cpp:2365

ObjCPropertyDecl * HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, unsigned &Attributes, const unsigned AttributesAsWritten, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind)

Called by ActOnProperty to handle @property declarations in class extensions.

Definition SemaObjCProperty.cpp:405

void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)

Diagnose any null-resettable synthesized setters.

Definition SemaObjCProperty.cpp:2127

llvm::SmallPtrSet< Selector, 8 > SelectorSet

ObjCPropertyDecl * CreatePropertyDecl(Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, const unsigned Attributes, const unsigned AttributesAsWritten, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)

Called by ActOnProperty and HandlePropertyInClassExtension to handle creating the ObjcPropertyDecl fo...

Definition SemaObjCProperty.cpp:551

bool CheckARCMethodDecl(ObjCMethodDecl *method)

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

bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)

IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...

Definition SemaObjCProperty.cpp:1825

void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)

Definition SemaObjCProperty.cpp:2247

Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)

Definition SemaObjCProperty.cpp:172

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

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

Definition SemaObjCProperty.cpp:2022

void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl)

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

Definition SemaObjCProperty.cpp:2153

Decl * ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, bool ImplKind, IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, SourceLocation PropertyIvarLoc, ObjCPropertyQueryKind QueryKind)

ActOnPropertyImplDecl - This routine performs semantic checks and builds the AST node for a property ...

Definition SemaObjCProperty.cpp:1063

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

Definition SemaObjCProperty.cpp:2307

ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)

Find the protocol with the given name, if any.

void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, unsigned &Attributes, bool propertyInPrimaryClass)

Ensure attributes are consistent with type.

Definition SemaObjCProperty.cpp:2628

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

AddFactoryMethodToGlobalPool - Same as above, but for factory methods.

void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, const IdentifierInfo *Name, bool OverridingProtocolProperty)

DiagnosePropertyMismatch - Compares two properties for their attributes and types and warns on a vari...

Definition SemaObjCProperty.cpp:1622

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

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

AddInstanceMethodToGlobalPool - All instance methods in a translation unit are added to a global pool...

RAII object to handle the state changes required to synthesize a function body.

Sema - This implements semantic analysis and AST building for C.

bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)

isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.

const LangOptions & getLangOpts() const

const LangOptions & LangOpts

@ AbstractSynthesizedIvarType

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

Stores token information for comparing actual tokens with predefined values.

Token - This structure provides full information about a lexed token.

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.

bool isBlockPointerType() const

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

bool isArithmeticType() const

const T * castAs() const

Member-template castAs.

bool isObjCObjectPointerType() const

bool isObjCQualifiedClassType() const

bool isObjCClassType() const

const T * getAs() const

Member-template getAs'.

bool isObjCARCImplicitlyUnretainedType() const

Determines if this type, which must satisfy isObjCLifetimeType(), is implicitly __unsafe_unretained r...

bool isRecordType() const

bool isObjCRetainableType() const

std::optional< NullabilityKind > getNullability() const

Determine the nullability of the given type.

void setType(QualType newType)

ObjCPropertyAttribute::Kind - list of property attributes.

@ kind_nullability

Indicates that the nullability of the type was spelled with a property attribute rather than a type q...

const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr

Matches call expressions.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

ObjCKeywordKind

Provides a namespace for Objective-C keywords which start with an '@'.

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

@ Nullable

Values of this type can be null.

@ Unspecified

Whether values of this type can be null is (explicitly) unspecified.

@ NonNull

Values of this type can never be null.

std::pair< FileID, unsigned > FileIDAndOffset

ObjCMethodFamily

A family of Objective-C methods.

@ Property

The type of a property.

const FunctionProtoType * T

@ VK_PRValue

A pr-value expression (in the C++11 taxonomy) produces a temporary value.

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

bool declaresSameEntity(const Decl *D1, const Decl *D2)

Determine whether two declarations declare the same entity.

U cast(CodeGen::Address addr)

ActionResult< Expr * > ExprResult

This little struct is used to capture information about structure field declarators,...

A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...

Qualifiers Quals

The local qualifiers.