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

124}

125

127

128 if (S.getLangOpts().getGC() != LangOptions::NonGC) {

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);

185 }

187

189

190

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

194 if (CDecl->IsClassExtension()) {

196 FD,

199 isReadWrite, Attributes,

201 T, TSI, MethodImplKind);

202 if (!Res)

203 return nullptr;

204 }

205 }

206

207 if (!Res) {

212 MethodImplKind);

213 if (lexicalDC)

215 }

216

217

219 (isa(ClassDecl) ||

220 isa(ClassDecl)));

221

222

225

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

228

229 bool FoundInSuper = false;

235 FoundInSuper = true;

236 break;

237 }

238 CurrentInterfaceDecl = Super;

239 }

240

241 if (FoundInSuper) {

242

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

245 }

246 } else {

247

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

250 }

251 }

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

253

254

255

256 if (!Cat->IsClassExtension())

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

259 } else {

263 }

264

266 return Res;

267}

268

271 unsigned attributesAsWritten = 0;

300

302}

303

307 return false;

308

310 std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(LParenLoc);

311

312 bool invalidTemp = false;

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

314 if (invalidTemp)

315 return false;

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

317

318

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

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

323 do {

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

327 return true;

328 }

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

330 return false;

331}

332

333

337 bool PropagateAtomicity) {

338

343 if (OldIsAtomic == NewIsAtomic) return;

344

345

346

348

349 auto Attrs = Property->getPropertyAttributes();

351 return false;

352

353

355 return false;

356

357

358 if (Property->getPropertyAttributesAsWritten() &

360 return false;

361

362 return true;

363 };

364

365

366

369 if (PropagateAtomicity &&

372 Attrs = Attrs & ~AtomicityMask;

373 if (OldIsAtomic)

375 else

377

379 return;

380 }

381

382

383

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

385 (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))

386 return;

387

388

391 if (auto Category = dyn_cast(OldDC))

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

393 else

394 OldContextName = cast(OldDC)->getIdentifier();

395

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

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

398 << OldContextName;

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

400}

401

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

409

413

414

415

416 if (!CCPrimary) {

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

418 return nullptr;

419 }

420

421 bool isClassProperty =

424

425

426

429

430

431 if (PIDecl && isa(PIDecl->getDeclContext())) {

432 Diag(AtLoc, diag::err_duplicate_property);

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

434 return nullptr;

435 }

436

437

438 if (PIDecl) {

439

440

441

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

443

444

445

446

447 unsigned diag =

451 ? diag::err_use_continuation_class_redeclaration_readwrite

452 : diag::err_use_continuation_class;

453 Diag(AtLoc, diag)

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

456 return nullptr;

457 }

458

459

461

463 Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)

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

466 }

467

468

471 }

472

473

474 unsigned ExistingOwnership

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

478

480 Diag(AtLoc, diag::warn_property_attr_mismatch);

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

482 }

483

484

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

486 }

487

488

494 Diag(AtLoc, diag::warn_property_implicitly_mismatched);

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

496 }

497 }

498

499

500

502 FD, GetterSel, GetterNameLoc,

503 SetterSel, SetterNameLoc,

504 isReadWrite,

505 Attributes, AttributesAsWritten,

506 T, TSI, MethodImplKind, DC);

508

509

510 if (!PIDecl) {

512 return PDecl;

513 }

514

516 bool IncompatibleObjC = false;

518

519

520

521

522

523

526 if (!isa(PrimaryClassPropertyT) ||

527 !isa(ClassExtPropertyT) ||

529 PrimaryClassPropertyT, ConvertedType,

530 IncompatibleObjC)) ||

531 IncompatibleObjC) {

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

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

535 return nullptr;

536 }

537 }

538

539

540

542

543

545 return PDecl;

546}

547

552 SourceLocation SetterNameLoc, const bool isReadWrite,

553 const unsigned Attributes, const unsigned AttributesAsWritten, QualType T,

558

559

560

561 bool isAssign;

564 isAssign = true;

566 isAssign = false;

567 } else {

568 isAssign = (getLangOpts().ObjCAutoRefCount ||

570 }

571

572

573

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

579 if (IDecl)

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

584 }

585 }

586

595 }

596

600 PropertyId, AtLoc,

601 LParenLoc, T, TInfo);

602

603 bool isClassProperty =

606

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

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

612 }

613 else {

615 if (lexicalDC)

617 }

618

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

622 }

623

624

625

630

632

635

638

641

642 if (isReadWrite)

644

647

650

653

656

659

660 if (isAssign)

662

663

666 else

668

669

672 if (isAssign)

674

675 if (MethodImplKind == tok::objc_required)

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

679

682

685

688

690 CDecl->hasAttr()) {

691 if (isa(CDecl)) {

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

695 } else {

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

698 }

699 }

700

701 return PDecl;

702}

703

708

711

712

716

717

718 if (propertyLifetime == ivarLifetime) return;

719

720

721

725 return;

726

727

728

729

730

740 return;

741 }

742 }

743

744 switch (propertyLifetime) {

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

747 << property->getDeclName()

749 << ivarLifetime;

750 break;

751

754 << property->getDeclName()

756 break;

757

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

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

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

763 break;

764

766 llvm_unreachable("properties cannot be autoreleasing");

767

769

770 return;

771 }

772

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

774 if (propertyImplLoc.isValid())

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

776}

777

778

779

780

781

782

789 return;

790

791 if (!ivar) {

792

794 return;

795 }

796

803}

804

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

808}

809

811 unsigned Kinds) {

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

813}

814

815

816

817

818

819

824 assert(isa(Property->getDeclContext()) &&

825 "Expected a property from a protocol");

830 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,

831 Properties);

832 }

834 while (SDecl) {

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

837 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,

838 Properties);

839 }

840 SDecl = SDecl->getSuperClass();

841 }

842 }

843

844 if (Properties.empty())

846

848 size_t SelectedIndex = 0;

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

850

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

853 SelectedIndex = Prop.index();

854 }

855 }

856 if (Property != OriginalProperty) {

857

858 Properties[SelectedIndex] = OriginalProperty;

859 }

860

862 unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();

863 enum MismatchKind {

864 IncompatibleType = 0,

865 HasNoExpectedAttribute,

866 HasUnexpectedAttribute,

867 DifferentGetter,

868 DifferentSetter

869 };

870

871

872 struct MismatchingProperty {

874 MismatchKind Kind;

875 StringRef AttributeName;

876 };

879

880 unsigned Attr = Prop->getPropertyAttributesAsWritten();

881 if (Attr != OriginalAttributes) {

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

883 MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute

884 : HasUnexpectedAttribute;

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

886 };

887

888

889 bool HasOwnership =

896 if (HasOwnership &&

900 continue;

901 }

903 OriginalAttributes, Attr,

908 "retain (or strong)");

909 continue;

910 }

914 continue;

915 }

916 }

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

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

919 continue;

920 }

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

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

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

924 continue;

925 }

928 bool IncompatibleObjC = false;

931 || IncompatibleObjC) {

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

933 continue;

934 }

935 }

936 }

937

938 if (Mismatches.empty())

940

941

942 {

943 bool HasIncompatibleAttributes = false;

944 for (const auto &Note : Mismatches)

945 HasIncompatibleAttributes =

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

947

948

950 Property != OriginalProperty || HasIncompatibleAttributes

951 ? diag::err_protocol_property_mismatch

952 : diag::warn_protocol_property_mismatch);

953 Diag << Mismatches[0].Kind;

954 switch (Mismatches[0].Kind) {

955 case IncompatibleType:

957 break;

958 case HasNoExpectedAttribute:

959 case HasUnexpectedAttribute:

960 Diag << Mismatches[0].AttributeName;

961 break;

962 case DifferentGetter:

964 break;

965 case DifferentSetter:

967 break;

968 }

969 }

970 for (const auto &Note : Mismatches) {

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

973 << Note.Kind;

974 switch (Note.Kind) {

975 case IncompatibleType:

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

977 break;

978 case HasNoExpectedAttribute:

979 case HasUnexpectedAttribute:

981 break;

982 case DifferentGetter:

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

984 break;

985 case DifferentSetter:

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

987 break;

988 }

989 }

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

992

994}

995

996

1000

1001

1002

1003

1004

1005

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

1007

1008

1010 if (Category || Category->IsClassExtension()) return false;

1011

1012

1013 auto OrigClass = Category->getClassInterface();

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

1016 return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;

1017 }

1018

1019

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

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

1023 return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;

1024 }

1025

1026 return false;

1027}

1028

1029

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

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

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

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

1049 Decl->getSelectorLocs(SelLocs);

1053 return ImplDecl;

1054}

1055

1056

1057

1058

1059

1067

1068 if (!ClassImpDecl) {

1069 Diag(AtLoc, diag::err_missing_property_context);

1070 return nullptr;

1071 }

1072 if (PropertyIvarLoc.isInvalid())

1073 PropertyIvarLoc = PropertyLoc;

1075 if (PropertyDiagLoc.isInvalid())

1076 PropertyDiagLoc = ClassImpDecl->getBeginLoc();

1079

1080

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

1085

1086

1087 assert(IDecl &&

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

1089

1090

1092 if (!property) {

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

1094 return nullptr;

1095 }

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

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

1098 return nullptr;

1099 }

1100 unsigned PIkind = property->getPropertyAttributesAsWritten();

1104 Diag(AtLoc, diag::warn_implicit_atomic_property);

1105 else

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

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

1108 }

1109

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

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

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

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

1115 return nullptr;

1116 }

1117 }

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

1120 bool ReadWriteProperty = false;

1121

1122

1126 PIkind = ExtProp->getPropertyAttributesAsWritten();

1128 ReadWriteProperty = true;

1129 break;

1130 }

1131 }

1132 }

1133

1134 if (!ReadWriteProperty) {

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

1136 << property;

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

1142 SourceRange ReadonlySourceRange(readonlyLoc, endLoc);

1143 Diag(property->getLocation(),

1144 diag::note_auto_readonly_iboutlet_fixup_suggest) <<

1146 }

1147 }

1148 }

1149 if (Synthesize && isa(property->getDeclContext()))

1151 property);

1152

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

1154 if (Synthesize) {

1155 Diag(AtLoc, diag::err_synthesize_category_decl);

1156 return nullptr;

1157 }

1159 if (!IDecl) {

1160 Diag(AtLoc, diag::err_missing_property_interface);

1161 return nullptr;

1162 }

1165

1166

1167

1169 return nullptr;

1170

1171 property = Category->FindPropertyDeclaration(PropertyId, QueryKind);

1172 if (!property) {

1173 Diag(PropertyLoc, diag::err_bad_category_property_decl)

1175 return nullptr;

1176 }

1177 } else {

1178 Diag(AtLoc, diag::err_bad_property_context);

1179 return nullptr;

1180 }

1182 bool CompleteTypeErr = false;

1183 bool compat = true;

1184

1185 if (Synthesize) {

1186

1187 if (!PropertyIvar)

1188 PropertyIvar = PropertyId;

1189

1192 QualType PropType = property->getType();

1194

1196 diag::err_incomplete_synthesized_property,

1197 property->getDeclName())) {

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

1199 CompleteTypeErr = true;

1200 }

1201

1203 (property->getPropertyAttributesAsWritten() &

1207 }

1208

1210

1211 bool isARCWeak = false;

1213

1215 assert(getLangOpts().ObjCAutoRefCount);

1217 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);

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

1219 } else {

1220 PropertyIvarType =

1222 }

1223

1224

1225

1226 } else {

1228

1229 if (!Ivar) {

1230 Diag(PropertyDiagLoc,

1232 ? diag::err_synthesizing_arc_weak_property_disabled

1233 : diag::err_synthesizing_arc_weak_property_no_runtime);

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

1235 }

1236 CompleteTypeErr = true;

1237 } else {

1238 isARCWeak = true;

1243 Diag(property->getLocation(),

1244 diag::err_arc_weak_unavailable_property)

1245 << PropertyIvarType;

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

1247 << ClassImpDecl->getName();

1248 }

1249 }

1250 }

1251 }

1252 }

1253

1255

1256

1257

1258

1262 ClassDeclared);

1263 if (originalIvar) {

1264 Diag(PropertyDiagLoc,

1265 diag::warn_autosynthesis_property_ivar_match)

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

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

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

1270 }

1271 }

1272

1273 if (!Ivar) {

1274

1275

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

1279

1280

1281

1284 Diag(PropertyDiagLoc,

1285 diag::err_arc_objc_property_default_assign_on_object);

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

1287 } else {

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

1291

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

1295 }

1296 }

1297

1299 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,

1300 PropertyIvarType, nullptr,

1302 (Expr *)nullptr, true);

1304 diag::err_abstract_type_in_decl,

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

1307

1308 CompleteTypeErr = true;

1309 }

1310 if (!CompleteTypeErr) {

1313 Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)

1314 << PropertyIvarType;

1315 CompleteTypeErr = true;

1316 }

1317 }

1318 if (CompleteTypeErr)

1320 ClassImpDecl->addDecl(Ivar);

1322

1324 Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)

1325 << PropertyId;

1326

1327

1330 Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)

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

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

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

1335

1336 }

1337 property->setPropertyIvarDecl(Ivar);

1338

1340

1341

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

1343 if (isa(PropertyIvarType)

1344 && isa(IvarType))

1348 else {

1350 PropertyIvarLoc, PropertyIvarType, IvarType) ==

1352 }

1353 if (!compat) {

1354 Diag(PropertyDiagLoc, diag::err_property_ivar_type)

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

1358

1359

1360 }

1361 else {

1362

1363

1364

1367 if (lhsType != rhsType &&

1369 Diag(PropertyDiagLoc, diag::err_property_ivar_type)

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

1373

1374 }

1375 }

1376

1379 Diag(PropertyDiagLoc, diag::err_weak_property)

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

1382

1383 }

1384

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

1388 Diag(PropertyDiagLoc, diag::err_strong_property)

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

1390

1391 }

1392 }

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

1396 } else if (PropertyIvar)

1397

1398 Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);

1399

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

1405 Ivar, PropertyIvarLoc);

1406

1407 if (CompleteTypeErr || !compat)

1409

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

1411 getterMethod->createImplicitParams(Context, IDecl);

1412

1413

1414 if (Synthesize) {

1415

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

1418 if (!OMD)

1420 PropertyLoc);

1422 }

1423

1426

1427

1428

1433 PropertyDiagLoc);

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

1438 Expr *IvarRefExpr =

1441 PropertyDiagLoc,

1443 LoadSelfExpr, true, true);

1446 getterMethod->getReturnType()),

1447 PropertyDiagLoc, IvarRefExpr);

1450 if (ResExpr)

1453 }

1454 }

1455 if (property->hasAttr() &&

1456 !getterMethod->hasAttr()) {

1457 Diag(getterMethod->getLocation(),

1458 diag::warn_property_getter_owning_mismatch);

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

1460 }

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

1462 switch (getterMethod->getMethodFamily()) {

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

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

1469 break;

1470 default:

1471 break;

1472 }

1473 }

1474

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

1476 setterMethod->createImplicitParams(Context, IDecl);

1477

1478

1479 if (Synthesize) {

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

1482 if (!OMD)

1484 AtLoc, PropertyLoc);

1486 }

1487

1490

1495 PropertyDiagLoc);

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

1503 PropertyDiagLoc,

1505 LoadSelfExpr, true, true);

1514 if (property->getPropertyAttributes() &

1518 dyn_cast_or_null(callExpr))

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

1520 if (!FuncDecl->isTrivial())

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

1522 Diag(PropertyDiagLoc,

1523 diag::err_atomic_property_nontrivial_assign_op)

1524 << property->getType();

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

1526 << FuncDecl;

1527 }

1528 }

1530 }

1531 }

1532

1533 if (IC) {

1534 if (Synthesize)

1537 Diag(PropertyLoc, diag::err_duplicate_ivar_use)

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

1539 << PropertyIvar;

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

1541 }

1542

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

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

1547 return nullptr;

1548 }

1550 if (getLangOpts().ObjCDefaultSynthProperties &&

1553

1554

1555

1558 if (!Synthesize)

1560 else {

1561 if (PropertyIvar && PropertyIvar != PropertyId)

1563 }

1564

1568 << PropertyId;

1570 }

1571 }

1572 } else {

1573 if (Synthesize)

1576 Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)

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

1578 << PropertyIvar;

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

1580 }

1581

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

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

1586 return nullptr;

1587 }

1589 }

1590

1594 Diag(PropertyLoc, diag::err_objc_direct_dynamic_property);

1596 diag::note_previous_declaration);

1597 return nullptr;

1598 }

1599

1600 return PIDecl;

1601}

1602

1603

1604

1605

1606

1607

1608

1609

1613 bool OverridingProtocolProperty) {

1617

1618

1619

1620

1621 if (!OverridingProtocolProperty &&

1623 ;

1624 else {

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

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

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

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

1638 bool CStrong = (CAttrRetain != 0);

1639 bool SStrong = (SAttrRetain != 0);

1640 if (CStrong != SStrong)

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

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

1643 }

1644 }

1645

1646

1647

1648

1650

1651

1654 isa(SuperProperty->getDeclContext()))) {

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

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

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

1658 }

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

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

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

1663 }

1664

1669

1671

1672

1673 bool IncompatibleObjC = false;

1676 IncompatibleObjC) ||

1677 IncompatibleObjC) {

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

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

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

1681 }

1682 }

1683}

1684

1689 if (!GetterMethod)

1690 return false;

1692 QualType PropertyRValueType =

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

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

1695 if (!compat) {

1698 if ((propertyObjCPtr =

1704 Diag(Loc, diag::err_property_accessor_type)

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

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

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

1708 return true;

1709 } else {

1710 compat = true;

1714 compat = false;

1715 }

1716 }

1717

1718 if (!compat) {

1719 Diag(Loc, diag::warn_accessor_property_type_mismatch)

1720 << property->getDeclName()

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

1723 return true;

1724 }

1725

1726 return false;

1727}

1728

1729

1730

1731static void

1735 bool CollectClassPropsOnly = false,

1736 bool IncludeProtocols = true) {

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

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

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

1740 continue;

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

1742 Prop;

1743 }

1744

1745

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

1748 CollectClassPropsOnly, IncludeProtocols);

1749

1750 if (IncludeProtocols) {

1751

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

1754 CollectClassPropsOnly);

1755 }

1756 }

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

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

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

1760 continue;

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

1762 Prop;

1763 }

1764 if (IncludeProtocols) {

1765

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

1768 CollectClassPropsOnly);

1769 }

1770 }

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

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

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

1774 continue;

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

1777 Prop->isClassProperty())];

1778

1779

1780 if (!PropertyFromSuper ||

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

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

1784 Prop->isClassProperty())];

1785 if (!PropEntry)

1786 PropEntry = Prop;

1787 }

1788 }

1789

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

1792 CollectClassPropsOnly);

1793 }

1794}

1795

1796

1797

1798

1802 while (SDecl) {

1803 SDecl->collectPropertiesToImplement(PropMap);

1804 SDecl = SDecl->getSuperClass();

1805 }

1806 }

1807}

1808

1809

1810

1811

1816 return false;

1820 return false;

1821

1822

1823

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

1828 return true;

1829 }

1830

1831

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

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

1837 return true;

1838 return false;

1839}

1840

1843 bool SuperClassImplementsGetter = false;

1844 bool SuperClassImplementsSetter = false;

1846 SuperClassImplementsSetter = true;

1847

1851 SuperClassImplementsGetter = true;

1852

1854 SuperClassImplementsSetter = true;

1855 if (SuperClassImplementsGetter && SuperClassImplementsSetter)

1856 return true;

1858 }

1859 return false;

1860}

1861

1862

1863

1870 if (PropMap.empty())

1871 return;

1874

1875 for (const auto &PropEntry : PropMap) {

1877

1881 continue;

1882

1885 continue;

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

1889 continue;

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

1892 continue;

1893 }

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

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

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

1900 continue;

1901 }

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

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

1907

1908

1909

1910

1913 diag::warn_auto_synthesizing_protocol_property)

1914 << Prop << Proto;

1916 std::string FixIt =

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

1918 Diag(AtEnd, diag::note_add_synthesize_directive)

1920 }

1921 continue;

1922 }

1923

1924 if (PropInSuperClass) {

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

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

1934 } else {

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

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

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

1939 }

1940 continue;

1941 }

1942

1943

1944

1945

1948 true,

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

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

1955 }

1956 }

1957}

1958

1961 if (getLangOpts().ObjCDefaultSynthProperties ||

1963 return;

1965 if (!IC)

1966 return;

1968 if (!IDecl->isObjCRequiresPropertyDefs())

1970}

1971

1977

1978

1982 });

1983

1984

1985

1986

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

1988 (PrimaryClass == nullptr ||

1991 unsigned diag =

1992 isa(CDecl)

1994 ? diag::warn_impl_required_in_category_for_class_property

1995 : diag::warn_setter_getter_impl_required_in_category)

1997 ? diag::warn_impl_required_for_class_property

1998 : diag::warn_setter_getter_impl_required);

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

2001 if (S.LangOpts.ObjCDefaultSynthProperties &&

2004 if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())

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

2006 }

2007}

2008

2011 bool SynthesizeProperties) {

2014

2015

2016

2018

2019

2020 if (!IDecl)

2022

2023

2024

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

2027 }

2028 }

2029 if (IDecl)

2031

2032

2034 SynthesizeProperties);

2035

2036

2037

2038

2039 if (IDecl) {

2040 std::unique_ptrObjCContainerDecl::PropertyMap LazyMap;

2041

2043 if (!PDecl->hasAttr())

2044 continue;

2045

2046

2047

2048

2049

2050

2051

2052 if (!LazyMap) {

2056 false,

2057 false);

2058 }

2059

2060

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

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

2063 PropDecl->isClassProperty())])

2064 continue;

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

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

2067 }

2068 }

2069 }

2070

2071 if (PropMap.empty())

2072 return;

2073

2074 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;

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

2077

2079

2080 for (const auto *I : IMPDecl->methods())

2081 InsMap.insert(I);

2082

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

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

2087

2089

2090

2091

2092 for (const auto *I : IMP->methods())

2093 InsMap.insert(I);

2094 }

2095

2096 for (ObjCContainerDecl::PropertyMap::iterator

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

2099

2102 PropImplMap.count(Prop) ||

2104 continue;

2105

2106

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

2112 Prop, InsMap);

2113 }

2114}

2115

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

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

2120

2121

2122 if (propertyImpl->getPropertyImplementation() ==

2124 (property->getPropertyAttributes() &

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

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

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

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

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

2134

2135 Diag(loc, diag::warn_null_resettable_setter)

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

2137 }

2138 }

2139 }

2140}

2141

2144

2146 return;

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

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

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

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

2153

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

2155 I != E; ++I) {

2159

2160 unsigned Attributes = Property->getPropertyAttributes();

2161 unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten();

2162

2165 GetterMethod = Property->isClassProperty() ?

2168 SetterMethod = Property->isClassProperty() ?

2172 GetterMethod = nullptr;

2174 SetterMethod = nullptr;

2175 if (GetterMethod) {

2177 diag::warn_default_atomic_custom_getter_setter)

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

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

2180 }

2181 if (SetterMethod) {

2183 diag::warn_default_atomic_custom_getter_setter)

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

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

2186 }

2187 }

2188

2189

2192 continue;

2196 continue;

2197 GetterMethod = PIDecl->getGetterMethodDecl();

2198 SetterMethod = PIDecl->getSetterMethodDecl();

2200 GetterMethod = nullptr;

2202 SetterMethod = nullptr;

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

2205 (GetterMethod ? GetterMethod->getLocation()

2206 : SetterMethod->getLocation());

2207 Diag(MethodLoc, diag::warn_atomic_property_rule)

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

2209 << (SetterMethod != nullptr);

2210

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

2213

2216 StringRef NonatomicStr = AttributesAsWritten? "nonatomic, "

2217 : "nonatomic";

2219 diag::note_atomic_property_fixup_suggest)

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

2222

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

2226 diag::note_atomic_property_fixup_suggest)

2228 } else

2229 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);

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

2231 }

2232 }

2233 }

2234}

2235

2239 return;

2240

2241 for (const auto *PID : D->property_impls()) {

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

2247 continue;

2249 if (!method)

2250 continue;

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

2256 else

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

2258

2259

2260

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

2264 if (getterRedecl->isImplicit())

2265 continue;

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

2267 continue;

2268 noteLoc = getterRedecl->getLocation();

2269 fixItLoc = getterRedecl->getEndLoc();

2270 }

2271

2274 tok::kw___attribute, tok::l_paren, tok::l_paren,

2277 tok::r_paren, tok::r_paren

2278 };

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

2281 if (!macroName.empty())

2282 spelling = macroName;

2283

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

2286 if (fixItLoc.isValid()) {

2288 fixItText += spelling;

2290 }

2291 }

2292 }

2293 }

2294}

2295

2300 if (!SuperD)

2301 return;

2302

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

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

2307

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

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

2314

2315

2316 bool Ignore = false;

2319 } else {

2320

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

2323 Ignore = IMD->isUnavailable();

2324 break;

2325 }

2326 }

2327 if (!Ignore) {

2329 diag::warn_objc_implementation_missing_designated_init_override)

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

2332 }

2333 }

2334 }

2335}

2336

2337

2338

2341

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

2343 if (isa(A) ||

2344 isa(A) ||

2345 isa(A))

2347 }

2348}

2349

2350

2351

2352

2353

2359 return;

2360

2361 bool IsClassProperty = property->isClassProperty();

2362 GetterMethod = IsClassProperty ?

2365

2366

2367

2368 if (!GetterMethod)

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

2370 if (CatDecl->IsClassExtension())

2373 CatDecl->getClassInterface()->

2375

2376 SetterMethod = IsClassProperty ?

2379 if (!SetterMethod)

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

2381 if (CatDecl->IsClassExtension())

2384 CatDecl->getClassInterface()->

2388

2389

2390

2391 if (!GetterMethod) {

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

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

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

2395 if (ExistingGetter) {

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

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

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

2399 << ExistingGetter->isDirectMethod()

2400 << ExistingGetter->getDeclName();

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

2402 }

2403 }

2404 }

2405 }

2406

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

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

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

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

2411 if (ExistingSetter) {

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

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

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

2415 << ExistingSetter->isDirectMethod()

2416 << ExistingSetter->getDeclName();

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

2418 }

2419 }

2420 }

2421 }

2422

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

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

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

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

2432 diag::warn_accessor_property_type_mismatch)

2433 << property->getDeclName()

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

2436 }

2437 }

2438

2439

2440

2441

2442

2443

2444

2445 if (!GetterMethod) {

2446

2447

2448

2450

2451

2452

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

2454

2455

2458 QualType modifiedTy = resultTy;

2462 modifiedTy, modifiedTy);

2463 }

2464 }

2465

2468 !IsClassProperty, false,

2469 true, false,

2470 true, false,

2474 CD->addDecl(GetterMethod);

2475

2477

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

2480

2481 if (property->hasAttr())

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

2484

2485 if (property->hasAttr())

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

2488

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

2490 GetterMethod->addAttr(SectionAttr::CreateImplicit(

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

2492

2494

2497 } else

2498

2499

2501

2504 property->setGetterMethodDecl(GetterMethod);

2505

2506

2508

2509 if (!SetterMethod) {

2510

2511

2512

2513

2515

2518 CD, !IsClassProperty,

2519 false,

2520 true,

2521 false,

2522 true,

2523 false,

2527

2528

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

2531

2532

2533

2536 QualType modifiedTy = paramTy;

2540 modifiedTy, modifiedTy);

2541 }

2542 }

2543

2544

2545

2549 paramTy,

2550 nullptr,

2552 nullptr);

2554

2556

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

2559

2560 CD->addDecl(SetterMethod);

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

2562 SetterMethod->addAttr(SectionAttr::CreateImplicit(

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

2564

2566

2567

2568

2571 } else

2572

2573

2575

2578 property->setSetterMethodDecl(SetterMethod);

2579 }

2580

2581

2582

2583

2584

2585

2586

2587

2588

2589

2590

2591

2592 if (!IsClassProperty) {

2593 if (GetterMethod)

2595 if (SetterMethod)

2597 } else {

2598 if (GetterMethod)

2600 if (SetterMethod)

2602 }

2603

2604 ObjCInterfaceDecl *CurrentClass = dyn_cast(CD);

2605 if (!CurrentClass) {

2607 CurrentClass = Cat->getClassInterface();

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

2609 CurrentClass = Impl->getClassInterface();

2610 }

2611 if (GetterMethod)

2613 if (SetterMethod)

2615}

2616

2618 unsigned &Attributes,

2619 bool propertyInPrimaryClass) {

2620

2622 return;

2623

2626 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2627 << "readonly" << "readwrite";

2628

2629 ObjCPropertyDecl *PropertyDecl = cast(PDecl);

2631

2632

2633 if ((Attributes &

2638 !PropertyDecl->hasAttr()) {

2639 Diag(Loc, diag::err_objc_property_requires_object)

2641 ? "weak"

2643 ? "copy"

2644 : "retain (or strong)");

2645 Attributes &=

2650 }

2651

2652

2657 Diag(Loc, diag::warn_objc_property_assign_on_object);

2658 }

2659

2660

2663 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2664 << "assign" << "copy";

2665 Attributes &= ~ObjCPropertyAttribute::kind_copy;

2666 }

2668 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2669 << "assign" << "retain";

2670 Attributes &= ~ObjCPropertyAttribute::kind_retain;

2671 }

2673 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2674 << "assign" << "strong";

2675 Attributes &= ~ObjCPropertyAttribute::kind_strong;

2676 }

2679 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2680 << "assign" << "weak";

2681 Attributes &= ~ObjCPropertyAttribute::kind_weak;

2682 }

2683 if (PropertyDecl->hasAttr())

2684 Diag(Loc, diag::warn_iboutletcollection_property_assign);

2687 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2688 << "unsafe_unretained" << "copy";

2689 Attributes &= ~ObjCPropertyAttribute::kind_copy;

2690 }

2692 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2693 << "unsafe_unretained" << "retain";

2694 Attributes &= ~ObjCPropertyAttribute::kind_retain;

2695 }

2697 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2698 << "unsafe_unretained" << "strong";

2699 Attributes &= ~ObjCPropertyAttribute::kind_strong;

2700 }

2703 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2704 << "unsafe_unretained" << "weak";

2705 Attributes &= ~ObjCPropertyAttribute::kind_weak;

2706 }

2709 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2710 << "copy" << "retain";

2711 Attributes &= ~ObjCPropertyAttribute::kind_retain;

2712 }

2714 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2715 << "copy" << "strong";

2716 Attributes &= ~ObjCPropertyAttribute::kind_strong;

2717 }

2719 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2720 << "copy" << "weak";

2721 Attributes &= ~ObjCPropertyAttribute::kind_weak;

2722 }

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

2726 << "weak";

2727 Attributes &= ~ObjCPropertyAttribute::kind_retain;

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

2731 << "weak";

2732 Attributes &= ~ObjCPropertyAttribute::kind_weak;

2733 }

2734

2736

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

2739 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)

2740 << "nonnull" << "weak";

2741 }

2742 }

2743

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

2747 << "nonatomic";

2748 Attributes &= ~ObjCPropertyAttribute::kind_atomic;

2749 }

2750

2751

2752

2755

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

2757

2758

2763

2764

2766 ;

2767 else if (propertyInPrimaryClass) {

2768

2769

2770

2772 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);

2773

2774

2776 Diag(Loc, diag::warn_objc_property_default_assign_on_object);

2777 }

2778 }

2779

2780

2781

2782 }

2783

2788 Diag(Loc, diag::warn_objc_property_copy_missing_on_block);

2793 Diag(Loc, diag::warn_objc_property_retain_of_block);

2794

2797 Diag(Loc, diag::warn_objc_readonly_property_has_setter);

2798}

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

enum clang::sema::@1725::IndirectLocalPathEntry::EntryKind Kind

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)

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

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

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

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

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

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

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

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

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

static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T)

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

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

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

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

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

static unsigned getOwnershipRule(unsigned attr)

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

Create a synthesized property accessor stub inside the @implementation.

static bool hasWrittenStorageAttribute(ObjCPropertyDecl *Prop, ObjCPropertyQueryKind QueryKind)

Determine whether any storage attributes were written on the property.

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

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

static const unsigned OwnershipMask

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

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

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

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.

static ObjCPropertyAttribute::Kind makePropertyAttributesAsWritten(unsigned Attributes)

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

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

SourceManager & getSourceManager()

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 propertyTypesAreCompatible(QualType, QualType)

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

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

const LangOptions & getLangOpts() const

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

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

QualType getQualifiedType(SplitQualType split) const

Un-split a SplitQualType.

QualType getObjCObjectPointerType(QualType OIT) const

Return a ObjCObjectPointerType type for the given ObjCObjectType.

bool hasSameUnqualifiedType(QualType T1, QualType T2) const

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

QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const

Return the uniqued reference to the type for an Objective-C gc-qualified type.

Attr - This represents one attribute.

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

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

A call to an overloaded operator written using operator syntax.

CanQual< T > getUnqualifiedType() const

Retrieve the unqualified form of this type.

The results of name lookup within a DeclContext.

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.

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.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

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

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

instmeth_range instance_methods() const

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

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

instprop_range instance_properties() const

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

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

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

bool isInstanceMethod() 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.

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

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

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

RecordDecl * getDecl() 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.

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

Emit a diagnostic.

ASTContext & getASTContext() const

const LangOptions & getLangOpts() const

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

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

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

void ProcessPropertyDecl(ObjCPropertyDecl *property)

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

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.

void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)

Diagnose any null-resettable synthesized setters.

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

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

void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)

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

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

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

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

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

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.

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

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.

Preprocessor & getPreprocessor() const

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

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

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

Calls Lexer::getLocForEndOfToken()

const LangOptions & getLangOpts() const

bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)

const LangOptions & LangOpts

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.

@ Compatible

Compatible - the types are compatible according to the standard.

void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base=nullptr)

Perform reference-marking and odr-use handling for a DeclRefExpr.

TypeSourceInfo * GetTypeForDeclarator(Declarator &D)

GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.

bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type T is a complete type.

Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)

MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...

ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)

void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD)

ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in it, apply them to D.

ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)

@ AbstractSynthesizedIvarType

void ProcessAPINotes(Decl *D)

Map any API notes provided for this declaration to attributes on the declaration.

AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, QualType LHSType, QualType RHSType)

CheckAssignmentConstraints - Perform type checking for assignment, argument passing,...

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

Return a source location identifier for the specified offset in the current file.

bool is(tok::TokenKind K) const

is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....

bool isNot(tok::TokenKind K) const

StringRef getRawIdentifier() const

getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...

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

bool isArithmeticType() const

const T * castAs() const

Member-template castAs.

bool isObjCObjectType() const

bool isFunctionType() const

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)

@ kind_nullability

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

const internal::VariadicAllOfMatcher< Attr > attr

Matches attributes.

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.

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

ObjCMethodFamily

A family of Objective-C methods.

@ Property

The type of a property.

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

const FunctionProtoType * T

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

Determine whether two declarations declare the same entity.

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.