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

1

2

3

4

5

6

7

8

9

10

11

12

30#include "llvm/Support/ConvertUTF.h"

31#include

32

33using namespace clang;

34using namespace sema;

36

40

41

42

43

45

46

47 if (Strings.size() != 1) {

48

51

52 for (Expr *E : Strings) {

54

55

57 Diag(S->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)

59 return true;

60 }

61

62

64

65

67 }

68

69

70

72 assert(CAT && "String literal not of constant array type!");

73 QualType StrTy = Context.getConstantArrayType(

74 CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr,

77 false, StrTy, StrLocs);

78 }

79

81}

82

86

88 return true;

89

90

91

92

93

94 QualType Ty = Context.getObjCConstantStringInterface();

96 Ty = Context.getObjCObjectPointerType(Ty);

97 } else if (getLangOpts().NoConstantCFStrings) {

99 std::string StringClass(getLangOpts().ObjCConstantStringClass);

100

101 if (StringClass.empty())

102 NSIdent = &Context.Idents.get("NSConstantString");

103 else

104 NSIdent = &Context.Idents.get(StringClass);

105

108 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) {

109 Context.setObjCConstantStringInterface(StrIF);

110 Ty = Context.getObjCConstantStringInterface();

111 Ty = Context.getObjCObjectPointerType(Ty);

112 } else {

113

114

115 Diag(S->getBeginLoc(), diag::err_no_nsconstant_string_class)

117 Ty = Context.getObjCIdType();

118 }

119 } else {

123 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) {

124 Context.setObjCConstantStringInterface(StrIF);

125 Ty = Context.getObjCConstantStringInterface();

126 Ty = Context.getObjCObjectPointerType(Ty);

127 } else {

128

129

130

131

132 Ty = Context.getObjCNSStringType();

136 Context.getTranslationUnitDecl(),

139 Ty = Context.getObjCInterfaceType(NSStringIDecl);

140 Context.setObjCNSStringType(Ty);

141 }

142 Ty = Context.getObjCObjectPointerType(Ty);

143 }

144 }

145

147}

148

149

150

154 if (!Method) {

155

156 S.Diag(Loc, diag::err_undeclared_boxing_method) << Sel << Class->getName();

157 return false;

158 }

159

160

161 QualType ReturnType = Method->getReturnType();

163 S.Diag(Loc, diag::err_objc_literal_method_sig)

164 << Sel;

165 S.Diag(Method->getLocation(), diag::note_objc_literal_method_return)

166 << ReturnType;

167 return false;

168 }

169

170 return true;

171}

172

173

176 switch (LiteralKind) {

187

188

189

192 break;

193 }

194 llvm_unreachable("LiteralKind can't be converted into a ClassKind");

195}

196

197

198

199

200static bool

207 S.Diag(Loc, diag::err_undeclared_objc_literal_class)

208 << II->getName() << LiteralKind;

209 return false;

210 } else if (Decl->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {

211 S.Diag(Loc, diag::err_undeclared_objc_literal_class)

212 << Decl->getName() << LiteralKind;

214 return false;

215 }

216

217 return true;

218}

219

220

221

222

231 if (!ID && S.getLangOpts().DebuggerObjCLiteral) {

236 }

237

239 ID = nullptr;

240 }

241

242 return ID;

243}

244

245

246

249 bool isLiteral = false,

251 std::optionalNSAPI::NSNumberLiteralMethodKind Kind =

252 S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);

253

254 if (!Kind) {

255 if (isLiteral) {

256 S.Diag(Loc, diag::err_invalid_nsnumber_type)

257 << NumberType << R;

258 }

259 return nullptr;

260 }

261

262

265

267 false);

268

270

271

272

277 return nullptr;

278 }

279 }

280

282

285 }

286

287

289 if (!Method && S.getLangOpts().DebuggerObjCLiteral) {

290

295 false, false,

296 false,

297 false,

298 true,

300 false);

304 NumberType, nullptr, SC_None, nullptr);

305 Method->setMethodParams(S.SemaRef.Context, value, {});

306 }

307

309 return nullptr;

310

311

312

313

315 return Method;

316}

317

318

319

321 Expr *Number) {

323

325 if (CharacterLiteral *Char = dyn_cast(Number)) {

326

327

328 switch (Char->getKind()) {

331 NumberType = Context.CharTy;

332 break;

333

335 NumberType = Context.getWideCharType();

336 break;

337

339 NumberType = Context.Char16Ty;

340 break;

341

343 NumberType = Context.Char32Ty;

344 break;

345 }

346 }

347

348

349

352 true, NR);

355

356

359 ParamDecl);

364 Number = ConvertedNumber.get();

365

366

369}

370

376 Inner = SemaRef.ActOnCXXBoolLiteral(ValueLoc,

377 Value ? tok::kw_true : tok::kw_false);

378 } else {

379

380

381 Inner = SemaRef.ActOnIntegerConstant(ValueLoc, Value ? 1 : 0);

382 Inner = SemaRef.ImpCastExprToType(Inner.get(), Context.BoolTy,

383 CK_IntegralToBoolean);

384 }

385

387}

388

389

390

393 bool ArrayLiteral = false) {

394

396 return Element;

397

399 if (Result.isInvalid())

401 Element = Result.get();

402

403

404

408 false);

412 if (Seq.Failed())

413 return Seq.Perform(S, Entity, Kind, Element);

414 }

415

416 Expr *OrigElement = Element;

417

418

420 if (Result.isInvalid())

422 Element = Result.get();

423

424

427 bool Recovered = false;

428

429

435 if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind(

436 OrigElement->getType())) {

440 : 3;

441

442 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)

445

447 OrigElement);

448 if (Result.isInvalid())

450

451 Element = Result.get();

452 Recovered = true;

453 }

454 }

455

456 else if (StringLiteral *String = dyn_cast(OrigElement)) {

457 if (String->isOrdinary()) {

458 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)

461

462 Result =

464 if (Result.isInvalid())

466

467 Element = Result.get();

468 Recovered = true;

469 }

470 }

471

472 if (!Recovered) {

473 S.Diag(Element->getBeginLoc(), diag::err_invalid_collection_element)

476 }

477 }

478 if (ArrayLiteral)

480 dyn_cast(OrigElement)) {

482 unsigned numConcat = SL->getNumConcatenated();

483 if (numConcat > 1) {

484

485 bool hasMacro = false;

486 for (unsigned i = 0; i < numConcat ; ++i)

487 if (SL->getStrTokenLoc(i).isMacroID()) {

488 hasMacro = true;

489 break;

490 }

491 if (!hasMacro)

493 diag::warn_concatenated_nsarray_literal)

495 }

496 }

497 }

498

499

500

503 false),

505}

506

511 new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR);

512 return BoxedExpr;

513 }

516

517 ExprResult RValue = SemaRef.DefaultFunctionArrayLvalueConversion(ValueExpr);

520 }

522 ValueExpr = RValue.get();

526 if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {

527

533 }

535 NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);

536 }

537

538

539

540 if (auto *CE = dyn_cast(ValueExpr))

541 if (CE->getCastKind() == CK_ArrayToPointerDecay)

542 if (auto *SL =

543 dyn_cast(CE->getSubExpr()->IgnoreParens())) {

544 assert((SL->isOrdinary() || SL->isUTF8()) &&

545 "unexpected character encoding");

546 StringRef Str = SL->getString();

547 const llvm::UTF8 *StrBegin = Str.bytes_begin();

548 const llvm::UTF8 *StrEnd = Str.bytes_end();

549

550 if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {

553 return new (Context) ObjCBoxedExpr(CE, BoxedType, nullptr, SR);

554 }

555

556 Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)

558 }

559

561 IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");

562 Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);

563

564

565 BoxingMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);

566 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {

567

572 false, false,

573 false,

574 false,

575 true,

577 false);

582 &Context.Idents.get("value"),

583 Context.getPointerType(ConstCharType),

584 nullptr,

587 BoxingMethod = M;

588 }

589

591 stringWithUTF8String, BoxingMethod))

593

595 }

596

599

600 std::optional Nullability =

602 if (Nullability)

603 BoxedType =

604 Context.getAttributedType(*Nullability, BoxedType, BoxedType);

605 }

606 } else if (ValueType->isBuiltinType()) {

607

608

609

610

611

612

614 dyn_cast(ValueExpr->IgnoreParens())) {

615

616

617 switch (Char->getKind()) {

620 ValueType = Context.CharTy;

621 break;

622

624 ValueType = Context.getWideCharType();

625 break;

626

628 ValueType = Context.Char16Ty;

629 break;

630

632 ValueType = Context.Char32Ty;

633 break;

634 }

635 }

636

637

638

641 } else if (const auto *ED = ValueType->getAsEnumDecl()) {

642 if (!ED->isComplete()) {

643 Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)

646 }

647

650 } else if (ValueType->isObjCBoxableRecordType()) {

651

652

653

654

655

660 }

661

662

664 NSValuePointer = Context.getObjCObjectPointerType(NSValueObject);

665 }

666

668 const IdentifierInfo *II[] = {&Context.Idents.get("valueWithBytes"),

669 &Context.Idents.get("objCType")};

670 Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II);

671

672

673 BoxingMethod = NSValueDecl->lookupClassMethod(ValueWithBytesObjCType);

674 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {

675

680 false,

681 false,

682 false,

683 false,

684 true,

686 false);

687

689

693 &Context.Idents.get("bytes"),

694 Context.VoidPtrTy.withConst(),

695 nullptr,

697 Params.push_back(bytes);

698

703 &Context.Idents.get("type"),

704 Context.getPointerType(ConstCharType),

705 nullptr,

707 Params.push_back(type);

708

710 BoxingMethod = M;

711 }

712

714 ValueWithBytesObjCType, BoxingMethod))

716

718 }

719

720 if (!ValueType.isTriviallyCopyableType(Context)) {

721 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)

724 }

725

728 }

729

730 if (!BoxingMethod) {

731 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)

734 }

735

736 SemaRef.DiagnoseUseOfDecl(BoxingMethod, Loc);

737

739 if (ValueType->isObjCBoxableRecordType()) {

741 ConvertedValueExpr = SemaRef.PerformCopyInitialization(

742 IE, ValueExpr->getExprLoc(), ValueExpr);

743 } else {

744

747 ParamDecl);

748 ConvertedValueExpr =

750 }

751

752 if (ConvertedValueExpr.isInvalid())

754 ValueExpr = ConvertedValueExpr.get();

755

757 new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,

758 BoxingMethod, SR);

759 return SemaRef.MaybeBindToTemporary(BoxedExpr);

760}

761

762

763

767 assert(getLangOpts().isSubscriptPointerArithmetic());

769

770

771

773 "base or index cannot have dependent type here");

774

775

776

778 if (Result.isInvalid())

780 IndexExpr = Result.get();

781

782

783 Result = SemaRef.DefaultLvalueConversion(BaseExpr);

784 if (Result.isInvalid())

786 BaseExpr = Result.get();

787

788

791 getterMethod, setterMethod, RB);

792}

793

798

804 }

805 }

806

807

808 QualType IdT = Context.getObjCIdType();

817 Context.getTranslationUnitDecl(), false ,

818 false ,

819 false, false,

820 true, false,

826 &Context.Idents.get("objects"),

827 Context.getPointerType(IdT),

828 nullptr,

830 Params.push_back(objects);

834 &Context.Idents.get("cnt"),

835 Context.UnsignedLongTy,

836 nullptr, SC_None,

837 nullptr);

838 Params.push_back(cnt);

839 Method->setMethodParams(Context, Params, {});

840 }

841

844

845

848 if (!PtrT ||

849 !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {

850 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)

851 << Sel;

852 Diag(Method->parameters()[0]->getLocation(),

853 diag::note_objc_literal_method_param)

854 << 0 << T

855 << Context.getPointerType(IdT.withConst());

857 }

858

859

860 if (Method->parameters()[1]->getType()->isIntegerType()) {

861 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)

862 << Sel;

863 Diag(Method->parameters()[1]->getLocation(),

864 diag::note_objc_literal_method_param)

865 << 1

866 << Method->parameters()[1]->getType()

867 << "integral";

869 }

870

871

873 }

874

877

878

879

880 Expr **ElementsBuffer = Elements.data();

881 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {

883 SemaRef, ElementsBuffer[I], RequiredType, true);

886

887 ElementsBuffer[I] = Converted.get();

888 }

889

891 = Context.getObjCObjectPointerType(

892 Context.getObjCInterfaceType(NSArrayDecl));

893

896}

897

898

899

900static void

903 if (Literal->isValueDependent() || Literal->isTypeDependent())

904 return;

905

906

907

908

909 struct APSIntCompare {

910 bool operator()(const llvm::APSInt &LHS, const llvm::APSInt &RHS) const {

911 return llvm::APSInt::compareValues(LHS, RHS) < 0;

912 }

913 };

914

915 llvm::DenseMap<StringRef, SourceLocation> StringKeys;

916 std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;

917

918 auto checkOneKey = [&](auto &Map, const auto &Key, SourceLocation Loc) {

919 auto Pair = Map.insert({Key, Loc});

920 if (!Pair.second) {

921 S.Diag(Loc, diag::warn_nsdictionary_duplicate_key);

922 S.Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);

923 }

924 };

925

926 for (unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {

927 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();

928

929 if (auto *StrLit = dyn_cast(Key)) {

930 StringRef Bytes = StrLit->getString()->getBytes();

932 checkOneKey(StringKeys, Bytes, Loc);

933 }

934

935 if (auto *BE = dyn_cast(Key)) {

936 Expr *Boxed = BE->getSubExpr();

938

939

941 checkOneKey(StringKeys, Str->getBytes(), Loc);

942 continue;

943 }

944

948 checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);

949 }

950 }

951 }

952}

953

958

964 }

965 }

966

967

968

969 QualType IdT = Context.getObjCIdType();

977 nullptr , Context.getTranslationUnitDecl(),

978 false , false ,

979 false,

980 false,

981 true, false,

987 &Context.Idents.get("objects"),

988 Context.getPointerType(IdT),

989 nullptr, SC_None,

990 nullptr);

991 Params.push_back(objects);

995 &Context.Idents.get("keys"),

996 Context.getPointerType(IdT),

997 nullptr, SC_None,

998 nullptr);

999 Params.push_back(keys);

1003 &Context.Idents.get("cnt"),

1004 Context.UnsignedLongTy,

1005 nullptr, SC_None,

1006 nullptr);

1007 Params.push_back(cnt);

1008 Method->setMethodParams(Context, Params, {});

1009 }

1010

1014

1015

1016 QualType ValueT = Method->parameters()[0]->getType();

1018 if (!PtrValue ||

1019 !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {

1020 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)

1021 << Sel;

1022 Diag(Method->parameters()[0]->getLocation(),

1023 diag::note_objc_literal_method_param)

1024 << 0 << ValueT

1025 << Context.getPointerType(IdT.withConst());

1027 }

1028

1029

1032 if (!PtrKey ||

1033 !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),

1034 IdT)) {

1035 bool err = true;

1036 if (PtrKey) {

1038

1043 Context.ObjCBuiltinIdTy, {},

1046 }

1047 }

1049 err = !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),

1051 }

1052

1053 if (err) {

1054 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)

1055 << Sel;

1056 Diag(Method->parameters()[1]->getLocation(),

1057 diag::note_objc_literal_method_param)

1058 << 1 << KeyT

1059 << Context.getPointerType(IdT.withConst());

1061 }

1062 }

1063

1064

1065 QualType CountType = Method->parameters()[2]->getType();

1067 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)

1068 << Sel;

1069 Diag(Method->parameters()[2]->getLocation(),

1070 diag::note_objc_literal_method_param)

1071 << 2 << CountType

1072 << "integral";

1074 }

1075

1076

1078 }

1079

1084

1085

1086

1087 bool HasPackExpansions = false;

1089

1094

1095

1098 if (Value.isInvalid())

1100

1101 Element.Key = Key.get();

1102 Element.Value = Value.get();

1103

1104 if (Element.EllipsisLoc.isInvalid())

1105 continue;

1106

1107 if (!Element.Key->containsUnexpandedParameterPack() &&

1108 !Element.Value->containsUnexpandedParameterPack()) {

1109 Diag(Element.EllipsisLoc,

1110 diag::err_pack_expansion_without_parameter_packs)

1111 << SourceRange(Element.Key->getBeginLoc(),

1112 Element.Value->getEndLoc());

1114 }

1115

1116 HasPackExpansions = true;

1117 }

1118

1119 QualType Ty = Context.getObjCObjectPointerType(

1121

1122 auto *Literal =

1126 return SemaRef.MaybeBindToTemporary(Literal);

1127}

1128

1136 StrTy = Context.DependentTy;

1137 else {

1138 if (!EncodedType->getAsArrayTypeUnsafe() &&

1139 !EncodedType->isVoidType())

1140 if (SemaRef.RequireCompleteType(AtLoc, EncodedType,

1141 diag::err_incomplete_type_objc_at_encode,

1144

1145 std::string Str;

1147 Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT);

1148 if (!NotEncodedT.isNull())

1149 Diag(AtLoc, diag::warn_incomplete_encoded_type)

1150 << EncodedType << NotEncodedT;

1151

1152

1153

1154 StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());

1155 }

1156

1157 return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);

1158}

1159

1166

1168 QualType EncodedType = SemaRef.GetTypeFromParser(ty, &TInfo);

1169 if (!TInfo)

1170 TInfo = Context.getTrivialTypeSourceInfo(

1171 EncodedType, SemaRef.getLocForEndOfToken(LParenLoc));

1172

1174}

1175

1183 bool Warned = false;

1186 if (MatchingMethodDecl == Method ||

1188 MatchingMethodDecl->getSelector() != Method->getSelector())

1189 continue;

1192 if (!Warned) {

1193 Warned = true;

1194 S.Diag(AtLoc, diag::warn_multiple_selectors)

1197 S.Diag(Method->getLocation(), diag::note_method_declared_at)

1198 << Method->getDeclName();

1199 }

1200 S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)

1202 }

1203 }

1204 return Warned;

1205}

1206

1211 bool WarnMultipleSelectors) {

1212 if (!WarnMultipleSelectors ||

1214 return;

1215 bool Warned = false;

1216 for (SemaObjC::GlobalMethodPool::iterator b = S.ObjC().MethodPool.begin(),

1218 b != e; b++) {

1219

1222 Method, InstMethList))

1223 Warned = true;

1224

1225

1228 Method, ClsMethList) || Warned)

1229 return;

1230 }

1231}

1232

1235 bool &onlyDirect,

1236 bool &anyDirect) {

1237 (void)Sel;

1240 for (; M; M = M->getNext()) {

1242 if (!Method)

1243 continue;

1244 assert(Method->getSelector() == Sel && "Method with wrong selector in method list");

1245 if (Method->isDirectMethod()) {

1246 anyDirect = true;

1247 DirectMethod = Method;

1248 } else

1249 onlyDirect = false;

1250 }

1251

1252 return DirectMethod;

1253}

1254

1255

1256

1257

1258

1260 bool &onlyDirect,

1261 bool &anyDirect) {

1264 return nullptr;

1265

1267 S, Sel, Iter->second.first, onlyDirect, anyDirect);

1269 S, Sel, Iter->second.second, onlyDirect, anyDirect);

1270

1271 return DirectInstance ? DirectInstance : DirectClass;

1272}

1273

1276 if (!CurMD)

1277 return nullptr;

1279

1280

1281

1282

1284 return MD;

1286 return MD;

1288 return MD;

1290 return MD;

1291

1292 return nullptr;

1293}

1294

1300 bool WarnMultipleSelectors) {

1309 Selector MatchedSel = OM->getSelector();

1312 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)

1313 << Sel << MatchedSel

1315

1316 } else

1317 Diag(SelLoc, diag::warn_undeclared_selector) << Sel;

1318 } else {

1320 WarnMultipleSelectors);

1321

1322 bool onlyDirect = true;

1323 bool anyDirect = false;

1326

1327 if (onlyDirect) {

1328 Diag(AtLoc, diag::err_direct_selector_expression)

1329 << Method->getSelector();

1330 Diag(Method->getLocation(), diag::note_direct_method_declared_at)

1331 << Method->getDeclName();

1332 } else if (anyDirect) {

1333

1334

1335

1338 if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) {

1339 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;

1341 diag::note_direct_method_declared_at)

1343 } else if (!LikelyTargetMethod) {

1344

1345

1346 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)

1347 << Sel;

1349 diag::note_direct_method_declared_at)

1351 }

1352 }

1353 }

1354

1356 Method->getImplementationControl() !=

1358 SemaRef.getSourceManager().isInSystemHeader(Method->getLocation()))

1360

1361

1362

1370 Diag(AtLoc, diag::err_arc_illegal_selector) <<

1371 Sel << SourceRange(LParenLoc, RParenLoc);

1372 break;

1373

1384 break;

1385 }

1386 }

1387 QualType Ty = Context.getObjCSelType();

1388 return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);

1389}

1390

1399 if (!PDecl) {

1400 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;

1401 return true;

1402 }

1404 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)

1405 << PDecl;

1407 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;

1408 Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;

1409 } else {

1411 }

1412

1413 QualType Ty = Context.getObjCProtoType();

1415 return true;

1416 Ty = Context.getObjCObjectPointerType(Ty);

1417 return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);

1418}

1419

1420

1423

1424

1425

1426

1427 ObjCMethodDecl *method = dyn_cast(DC);

1428 if (!method)

1429 return nullptr;

1430

1432

1433 return method;

1434}

1435

1438 if (auto nullability = AttributedType::stripOuterNullability(T)) {

1439 if (T == Context.getObjCInstanceType()) {

1440 return Context.getAttributedType(*nullability, Context.getObjCIdType(),

1441 Context.getObjCIdType());

1442 }

1443

1444 return origType;

1445 }

1446

1447 if (T == Context.getObjCInstanceType())

1448 return Context.getObjCIdType();

1449

1450 return origType;

1451}

1452

1453

1454

1455

1456

1457

1461 bool isClassMessage,

1462 bool isSuperMessage) {

1463 assert(Method && "Must have a method");

1464 if (!Method->hasRelatedResultType())

1465 return Method->getSendResultType(ReceiverType);

1466

1468

1469

1470

1472

1473 if (auto nullability =

1474 Method->getSendResultType(ReceiverType)->getNullability()) {

1475

1476 (void)AttributedType::stripOuterNullability(type);

1477

1478

1479 return Context.getAttributedType(*nullability, type, type);

1480 }

1481

1482 return type;

1483 };

1484

1485

1486

1487

1488

1489 if (Method->isInstanceMethod() && isClassMessage)

1491 Method->getSendResultType(ReceiverType));

1492

1493

1494

1495 if (isSuperMessage) {

1497 if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface()) {

1498 return transferNullability(

1499 Context.getObjCObjectPointerType(

1500 Context.getObjCInterfaceType(Class)));

1501 }

1502 }

1503

1504

1506 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));

1507

1508

1512 Method->getSendResultType(ReceiverType));

1513

1514

1515

1516

1517 return transferNullability(ReceiverType);

1518}

1519

1523 bool isClassMessage,

1524 bool isSuperMessage) {

1526

1528 SemaRef, ReceiverType, Method, isClassMessage, isSuperMessage);

1529

1530

1531 if (isClassMessage) {

1532

1533

1534

1535

1536

1538 assert(ReceiverType->isObjCClassType() && "expected a Class self");

1540 AttributedType::stripOuterNullability(T);

1541 if (T == Context.getObjCInstanceType()) {

1545 ->getDeclContext());

1546 assert(MD->isClassMethod() && "expected a class method");

1547 QualType NewResultType = Context.getObjCObjectPointerType(

1549 if (auto Nullability = resultType->getNullability())

1550 NewResultType = Context.getAttributedType(*Nullability, NewResultType,

1551 NewResultType);

1552 return NewResultType;

1553 }

1554 }

1555 return resultType;

1556 }

1557

1558

1559

1561 return resultType;

1562

1563

1564 unsigned receiverNullabilityIdx = 0;

1565 if (std::optional nullability =

1569 receiverNullabilityIdx = 1 + static_cast<unsigned>(*nullability);

1570 }

1571

1572 unsigned resultNullabilityIdx = 0;

1573 if (std::optional nullability =

1577 resultNullabilityIdx = 1 + static_cast<unsigned>(*nullability);

1578 }

1579

1580

1581

1582 static const uint8_t None = 0;

1583 static const uint8_t NonNull = 1;

1584 static const uint8_t Nullable = 2;

1586 static const uint8_t nullabilityMap[4][4] = {

1587

1592 };

1593

1594 unsigned newResultNullabilityIdx

1595 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];

1596 if (newResultNullabilityIdx == resultNullabilityIdx)

1597 return resultType;

1598

1599

1600

1601 do {

1602 if (auto attributed = dyn_cast(resultType.getTypePtr())) {

1603 resultType = attributed->getModifiedType();

1604 } else {

1606 }

1608

1609

1610 if (newResultNullabilityIdx > 0) {

1611 auto newNullability

1612 = static_cast<NullabilityKind>(newResultNullabilityIdx-1);

1613 return Context.getAttributedType(newNullability, resultType, resultType);

1614 }

1615

1616 return resultType;

1617}

1618

1619

1624 return MD;

1625

1626

1627

1632 dyn_cast(impl)) {

1633 iface = catImpl->getCategoryDecl();

1634 } else {

1635 iface = impl->getClassInterface();

1636 }

1637

1641 }

1642

1645 for (unsigned i = 0, e = overrides.size(); i != e; ++i) {

1648 return result;

1649 }

1650

1651 return nullptr;

1652}

1653

1656

1657

1660 Context.hasSameUnqualifiedType(destType, MD->getReturnType()))

1661 return;

1662

1663

1664

1667 SourceRange range = overridden->getReturnTypeSourceRange();

1670 loc = overridden->getLocation();

1671 Diag(loc, diag::note_related_result_type_explicit)

1672 << 1 << range;

1673 return;

1674 }

1675

1676

1677

1679 Diag(MD->getLocation(), diag::note_related_result_type_family)

1680 << 1

1681 << family;

1682}

1683

1687 const ObjCMessageExpr *MsgSend = dyn_cast(E);

1688 if (!MsgSend)

1689 return;

1690

1693 return;

1694

1695 if (Method->hasRelatedResultType())

1696 return;

1697

1698 if (Context.hasSameUnqualifiedType(

1699 Method->getReturnType().getNonReferenceType(), MsgSend->getType()))

1700 return;

1701

1702 if (!Context.hasSameUnqualifiedType(Method->getReturnType(),

1703 Context.getObjCInstanceType()))

1704 return;

1705

1706 Diag(Method->getLocation(), diag::note_related_result_type_inferred)

1707 << Method->isInstanceMethod() << Method->getSelector()

1709}

1710

1714 bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,

1719 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())

1720 SelLoc = SelectorLocs.front();

1721 else

1722 SelLoc = lbrac;

1723

1725

1726 for (unsigned i = 0, e = Args.size(); i != e; i++) {

1727 if (Args[i]->isTypeDependent())

1728 continue;

1729

1732 QualType paramTy;

1733 result = SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);

1734 } else {

1735 result = SemaRef.DefaultArgumentPromotion(Args[i]);

1736 }

1738 return true;

1739 Args[i] = result.get();

1740 }

1741

1742 unsigned DiagID;

1744 DiagID = diag::err_arc_method_not_found;

1745 else

1746 DiagID = isClassMessage ? diag::warn_class_method_not_found

1747 : diag::warn_inst_method_not_found;

1752 DiagID = diag::err_method_not_found_with_typo;

1753 else

1754 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo

1755 : diag::warn_instance_method_not_found_with_typo;

1757 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());

1759 Diag(SelLoc, DiagID)

1760 << Sel<< isClassMessage << MatchedSel

1762 else

1763 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;

1764 }

1765 else

1766 Diag(SelLoc, DiagID)

1767 << Sel << isClassMessage << SourceRange(SelectorLocs.front(),

1768 SelectorLocs.back());

1769

1772 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);

1774 if (ThisClass->lookupClassMethod(Sel))

1775 Diag(RecRange.getBegin(), diag::note_receiver_expr_here)

1777 ThisClass->getNameAsString());

1778 }

1779 }

1780 }

1781

1782

1783

1785 ReturnType = Context.UnknownAnyTy;

1786 } else {

1787 ReturnType = Context.getObjCIdType();

1788 }

1790 return false;

1791 }

1792

1794 isClassMessage, isSuperMessage);

1796

1797 unsigned NumNamedArgs = Sel.getNumArgs();

1798

1799

1801 NumNamedArgs = Method->param_size();

1802

1803 if (Args.size() < NumNamedArgs) {

1804 Diag(SelLoc, diag::err_typecheck_call_too_few_args)

1805 << 2 << NumNamedArgs << static_cast(Args.size())

1806 << 0;

1807 return false;

1808 }

1809

1810

1811

1812 std::optional<ArrayRef> typeArgs =

1814 bool IsError = false;

1815 for (unsigned i = 0; i < NumNamedArgs; i++) {

1816

1817 if (Args[i]->isTypeDependent())

1818 continue;

1819

1820 Expr *argExpr = Args[i];

1821

1823 assert(argExpr && "CheckMessageArgumentTypes(): missing expression");

1824

1825 if (param->hasAttr() &&

1827 if (auto *BE = dyn_cast(

1829 BE->getBlockDecl()->setDoesNotEscape();

1830

1831

1832

1834 !param->hasAttr())

1836

1837

1838

1839 if (param->getType() == Context.UnknownAnyTy) {

1841 ExprResult argE = SemaRef.checkUnknownAnyArg(SelLoc, argExpr, paramType);

1843 IsError = true;

1844 } else {

1845 Args[i] = argE.get();

1846

1847

1848 param->setType(paramType);

1849 }

1850 continue;

1851 }

1852

1855 if (typeArgs)

1857 Context,

1858 *typeArgs,

1860

1861 if (SemaRef.RequireCompleteType(

1863 diag::err_call_incomplete_argument, argExpr))

1864 return true;

1865

1871 IsError = true;

1872 else {

1874

1875

1876

1877

1878 if (typeArgs && Args[i]->isPRValue() && paramType->isBlockPointerType() &&

1879 Args[i]->getType()->isBlockPointerType() &&

1882 SemaRef.maybeExtendBlockObject(arg);

1883 Args[i] = arg.get();

1884 }

1885 }

1886 }

1887

1888

1889 if (Method->isVariadic()) {

1890 for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {

1891 if (Args[i]->isTypeDependent())

1892 continue;

1893

1897 Args[i] = Arg.get();

1898 }

1899 } else {

1900

1901 if (Args.size() != NumNamedArgs) {

1902 Diag(Args[NumNamedArgs]->getBeginLoc(),

1903 diag::err_typecheck_call_too_many_args)

1904 << 2 << NumNamedArgs << static_cast(Args.size())

1905 << Method->getSourceRange() << 0

1906 << SourceRange(Args[NumNamedArgs]->getBeginLoc(),

1907 Args.back()->getEndLoc());

1908 }

1909 }

1910

1911 SemaRef.DiagnoseSentinelCalls(Method, SelLoc, Args);

1912

1913

1914 IsError |=

1916

1917 return IsError;

1918}

1919

1921

1923 SemaRef.CurContext->getNonClosureAncestor());

1925}

1926

1928 if (!method) return false;

1929

1931 if (DeclRefExpr *DRE = dyn_cast(receiver))

1932 if (DRE->getDecl() == method->getSelfDecl())

1933 return true;

1934 return false;

1935}

1936

1937

1939 bool isInstance) {

1942

1943 if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))

1944 return method;

1945

1946

1947

1948 if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))

1949 return method;

1950 }

1951

1952

1953 for (const auto *I : objType->quals())

1954 if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))

1955 return method;

1956

1957 return nullptr;

1958}

1959

1960

1961

1965 for (const auto *PROTO : OPT->quals()) {

1966 if ((MD = PROTO->lookupMethod(Sel, Instance))) {

1967 return MD;

1968 }

1969 }

1970 return nullptr;

1971}

1972

1973

1974

1981 assert(IFaceT && "Expected an Interface");

1983

1985 Diag(MemberLoc, diag::err_invalid_property_name)

1986 << MemberName << QualType(OPT, 0);

1988 }

1989

1991

1995 diag::err_property_not_found_forward_class,

1996 MemberName, BaseRange))

1998

2001

2002 if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))

2004 if (Super)

2005 return new (Context)

2008 else

2009 return new (Context)

2012 }

2013

2014 for (const auto *I : OPT->quals())

2017

2018 if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))

2020

2021 if (Super)

2024 SuperLoc, SuperType);

2025 else

2026 return new (Context)

2029 }

2030

2031

2032

2033

2034

2035

2038

2039

2040 if (!Getter)

2042

2043

2044 if (!Getter)

2046

2047 if (Getter) {

2048

2049 if (SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))

2051 }

2052

2053

2057

2058

2059 if (!Setter)

2061

2062 if (!Setter) {

2063

2064

2066 }

2067

2068 if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))

2070

2071

2072

2073

2078

2079

2080 if (!(PDecl->getPropertyAttributes() &

2082 Diag(MemberLoc,

2083 diag::warn_property_access_suggest)

2084 << MemberName << QualType(OPT, 0) << PDecl->getName()

2086 }

2087 }

2088

2089 if (Getter || Setter) {

2090 if (Super)

2091 return new (Context)

2094 else

2095 return new (Context)

2098

2099 }

2100

2101

2106 OPT)) {

2110

2112 Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();

2115

2116

2117 Diag(MemberLoc, diag::err_class_property_found) << MemberName

2122 }

2123 } else {

2124 SemaRef.diagnoseTypo(Corrected,

2125 PDiag(diag::err_property_not_found_suggest)

2126 << MemberName << QualType(OPT, 0));

2128 TypoResult, MemberLoc,

2129 SuperLoc, SuperType, Super);

2130 }

2131 }

2137 T->getAsObjCInterfacePointerType()) {

2138 if (SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),

2139 diag::err_property_not_as_forward_class,

2140 MemberName, BaseExpr))

2142 }

2143 Diag(MemberLoc,

2144 diag::err_ivar_access_using_property_syntax_suggest)

2145 << MemberName << QualType(OPT, 0) << Ivar->getDeclName()

2148 }

2149

2150 Diag(MemberLoc, diag::err_property_not_found)

2151 << MemberName << QualType(OPT, 0);

2152 if (Setter)

2153 Diag(Setter->getLocation(), diag::note_getter_unavailable)

2156}

2157

2162 const IdentifierInfo *receiverNamePtr = &receiverName;

2164 receiverNameLoc);

2165

2167 if (!IFace) {

2168

2169

2170 if (receiverNamePtr->isStr("super")) {

2172 if (auto classDecl = CurMethod->getClassInterface()) {

2173 SuperType = QualType(classDecl->getSuperClassType(), 0);

2174 if (CurMethod->isInstanceMethod()) {

2175 if (SuperType.isNull()) {

2176

2177 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)

2178 << CurMethod->getClassInterface()->getIdentifier();

2180 }

2181 QualType T = Context.getObjCObjectPointerType(SuperType);

2182

2184 nullptr,

2186 &propertyName,

2187 propertyNameLoc,

2188 receiverNameLoc, T, true);

2189 }

2190

2191

2192

2193 IFace = CurMethod->getClassInterface()->getSuperClass();

2194 }

2195 }

2196 }

2197

2198 if (!IFace) {

2199 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier

2200 << tok::l_paren;

2202 }

2203 }

2204

2209 GetterSel = PD->getGetterName();

2210 SetterSel = PD->getSetterName();

2211 } else {

2212 GetterSel = SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);

2214 SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(),

2215 &propertyName);

2216 }

2217

2218

2220

2221

2222 if (!Getter)

2224

2225 if (Getter) {

2226

2227

2228 if (SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))

2230 }

2231

2232

2234 if (!Setter) {

2235

2236

2238 }

2239

2240 if (!Setter)

2242

2243 if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))

2245

2246 if (Getter || Setter) {

2247 if (!SuperType.isNull())

2248 return new (Context)

2251 SuperType);

2252

2255 propertyNameLoc, receiverNameLoc, IFace);

2256 }

2257 return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)

2258 << &propertyName << Context.getObjCInterfaceType(IFace));

2259}

2260

2261namespace {

2262

2264 public:

2266

2268 WantObjCSuper = Method->getClassInterface()->getSuperClass();

2269 }

2270

2271 bool ValidateCandidate(const TypoCorrection &candidate) override {

2274 }

2275

2276 std::unique_ptr clone() override {

2277 return std::make_unique(*this);

2278 }

2279};

2280

2281}

2282

2286 bool HasTrailingDot, ParsedType &ReceiverType) {

2288 ReceiverType = nullptr;

2289

2290

2291

2292

2295

2298

2299 switch (Result.getResultKind()) {

2301

2302

2303

2304

2306 if (Method->getClassInterface()) {

2307

2309 }

2310

2312 if (Method->getClassInterface()->lookupInstanceVariable(Name,

2313 ClassDeclared))

2315 }

2316

2317

2318 break;

2319

2324 Result.suppressDiagnostics();

2326

2328

2329

2330 if (HasTrailingDot)

2332

2333

2337 T = Context.getObjCInterfaceType(Class);

2338 else if (TypeDecl *Type = dyn_cast(ND)) {

2339 SemaRef.DiagnoseUseOfDecl(Type, NameLoc);

2341 std::nullopt, Type);

2342 } else

2344

2345

2346

2347 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);

2348 ReceiverType = SemaRef.CreateParsedType(T, TSInfo);

2350 }

2351 }

2352

2353 ObjCInterfaceOrSuperCCC CCC(SemaRef.getCurMethodDecl());

2355 Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,

2357 if (Corrected.isKeyword()) {

2358

2359

2360 SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)

2361 << Name);

2365

2366

2367 SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)

2368 << Name);

2370 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);

2371 ReceiverType = SemaRef.CreateParsedType(T, TSInfo);

2373 }

2374 }

2375

2376

2378}

2379

2386

2389 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);

2391 }

2392

2395 Diag(SuperLoc, diag::err_no_super_class_message)

2396 << Method->getDeclName();

2398 }

2399

2400 QualType SuperTy(Class->getSuperClassType(), 0);

2401 if (SuperTy.isNull()) {

2402

2403 Diag(SuperLoc, diag::err_root_class_cannot_use_super)

2404 << Class->getIdentifier();

2406 }

2407

2408

2409

2410 if (Method->getSelector() == Sel)

2411 SemaRef.getCurFunction()->ObjCShouldCallSuper = false;

2412

2413 if (Method->isInstanceMethod()) {

2414

2415

2416 SuperTy = Context.getObjCObjectPointerType(SuperTy);

2418 Sel, nullptr,

2419 LBracLoc, SelectorLocs, RBracLoc, Args);

2420 }

2421

2422

2423

2425 SuperTy,

2426 SuperLoc, Sel, nullptr,

2427 LBracLoc, SelectorLocs, RBracLoc, Args);

2428}

2429

2431 bool isSuperReceiver,

2437 if (!ReceiverType.isNull())

2438 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);

2439

2440 assert(((isSuperReceiver && Loc.isValid()) || receiverTypeInfo) &&

2441 "Either the super receiver location needs to be valid or the receiver "

2442 "needs valid type source information");

2444 isSuperReceiver ? Loc : SourceLocation(),

2445 Sel, Method, Loc, Loc, Loc, Args,

2446 true);

2447}

2448

2450 unsigned DiagID,

2455 return;

2456

2459 if (refactor(Msg, *S.ObjC().NSAPIObj, ECommit)) {

2460 auto Builder = S.Diag(MsgLoc, DiagID)

2462

2464 return;

2468 switch (Edit.Kind) {

2473 break;

2475 Builder.AddFixItHint(

2479 break;

2482 break;

2483 }

2484 }

2485 }

2486}

2487

2492

2496 bool IsClassObjectCall) {

2497

2498

2500 Args.empty())

2501 return;

2502 const auto *SE = dyn_cast(Args[0]->IgnoreParens());

2503 if (!SE)

2504 return;

2506 if (!IsClassObjectCall) {

2508 if (!OPT || !OPT->getInterfaceDecl())

2509 return;

2510 ImpliedMethod =

2511 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());

2512 if (!ImpliedMethod)

2513 ImpliedMethod =

2514 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());

2515 } else {

2517 if (!IT)

2518 return;

2519 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());

2520 if (!ImpliedMethod)

2521 ImpliedMethod =

2522 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());

2523 }

2524 if (!ImpliedMethod)

2525 return;

2527 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {

2528 S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)

2529 << Method->getSelector()

2530 << (!Ret->isRecordType()

2531 ? 2

2532 : Ret->isUnionType() ? 1 : 0);

2534 diag::note_objc_unsafe_perform_selector_method_declared_here)

2536 }

2537}

2538

2539

2540

2541static void

2545 Expr **Args, unsigned NumArgs) {

2546 unsigned Idx = 0;

2547 bool Format = false;

2550 Idx = 0;

2551 Format = true;

2552 }

2553 else if (Method) {

2554 for (const auto *I : Method->specific_attrs()) {

2556 Format = true;

2557 break;

2558 }

2559 }

2560 }

2561 if (!Format || NumArgs <= Idx)

2562 return;

2563

2564 Expr *FormatExpr = Args[Idx];

2569 S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)

2570 << "%s" << 0 << 0;

2571 if (Method)

2572 S.Diag(Method->getLocation(), diag::note_method_declared_at)

2573 << Method->getDeclName();

2574 }

2575 }

2576}

2577

2578

2579

2580

2581

2582

2583

2584

2585

2586

2587

2588

2589

2590

2591

2592

2593

2594

2595

2596

2597

2598

2599

2600

2601

2602

2603

2604

2605

2615 Diag(Loc, diag::err_missing_open_square_message_send)

2617 LBracLoc = Loc;

2618 }

2620 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())

2621 SelectorSlotLocs = SelectorLocs;

2622 else

2623 SelectorSlotLocs = Loc;

2625

2627

2628

2629 unsigned NumArgs = ArgsIn.size();

2630 Expr **Args = ArgsIn.data();

2631 assert(SuperLoc.isInvalid() && "Message to super with dependent type");

2633 ReceiverTypeInfo, Sel, SelectorLocs,

2634 nullptr, ArrayRef(Args, NumArgs),

2635 RBracLoc, isImplicit);

2636 }

2637

2638

2641 if (!ClassType || !(Class = ClassType->getInterface())) {

2642 Diag(Loc, diag::err_invalid_receiver_class_message)

2643 << ReceiverType;

2645 }

2646 assert(Class && "We don't know which class we're messaging?");

2647

2649 (void)SemaRef.DiagnoseUseOfDecl(Class, SelectorSlotLocs);

2650

2655 if (SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(Class),

2657 ? diag::err_arc_receiver_forward_class

2658 : diag::warn_receiver_forward_class),

2659 TypeRange)) {

2660

2664 Diag(Method->getLocation(), diag::note_method_sent_forward_class)

2665 << Method->getDeclName();

2666 }

2669

2670

2672 Method = Class->lookupPrivateClassMethod(Sel);

2673

2674 if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr,

2675 false, false, Class))

2677 }

2678

2679

2682

2683 unsigned NumArgs = ArgsIn.size();

2684 Expr **Args = ArgsIn.data();

2686 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,

2690

2691 if (Method && Method->getReturnType()->isVoidType() &&

2692 SemaRef.RequireCompleteType(

2693 LBracLoc, Method->getReturnType(),

2694 diag::err_illegal_message_expr_incomplete_type))

2696

2698 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)

2700 SuperLoc, getLangOpts().ObjCAutoRefCount

2701 ? "self"

2702 : Method->getClassInterface()->getName());

2703 Diag(Method->getLocation(), diag::note_direct_method_declared_at)

2704 << Method->getDeclName();

2705 }

2706

2707

2709 if (!SuperLoc.isValid()) {

2711 dyn_cast(Method->getDeclContext());

2712 if (ID == Class) {

2713 Diag(Loc, diag::warn_direct_initialize_call);

2714 Diag(Method->getLocation(), diag::note_method_declared_at)

2715 << Method->getDeclName();

2716 }

2718

2720 Diag(Loc, diag::warn_direct_super_initialize_call);

2721 Diag(Method->getLocation(), diag::note_method_declared_at)

2722 << Method->getDeclName();

2723 Diag(CurMeth->getLocation(), diag::note_method_declared_at)

2724 << CurMeth->getDeclName();

2725 }

2726 }

2727 }

2728

2730

2731

2735 Context, ReturnType, VK, LBracLoc, SuperLoc, false,

2736 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),

2737 RBracLoc, isImplicit);

2738 else {

2740 Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,

2741 Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit);

2742 if (!isImplicit)

2744 }

2747 ReceiverType, true);

2749}

2750

2751

2752

2753

2762 SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);

2763 if (ReceiverType.isNull())

2765

2766 if (!ReceiverTypeInfo)

2767 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);

2768

2771 nullptr, LBracLoc, SelectorLocs, RBracLoc,

2772 Args);

2773}

2774

2780 Sel, Method, Loc, Loc, Loc, Args,

2781 true);

2782}

2783

2786 return false;

2787 const auto *Protocol = dyn_cast(M->getDeclContext());

2788 if (!Protocol)

2789 return false;

2792 if (const auto *RootClass = dyn_cast_or_null(

2795 for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {

2796 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())

2797 return true;

2798 }

2799 }

2800 return false;

2801}

2802

2803

2804

2805

2806

2807

2808

2809

2810

2811

2812

2813

2814

2815

2816

2817

2818

2819

2820

2821

2822

2823

2824

2825

2826

2827

2828

2829

2830

2836 assert((Receiver || SuperLoc.isValid()) && "If the Receiver is null, the "

2837 "SuperLoc must be valid so we can "

2838 "use it instead.");

2840

2841

2846 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())

2847 SelectorSlotLocs = SelectorLocs;

2848 else

2849 SelectorSlotLocs = Loc;

2851

2853 Diag(Loc, diag::err_missing_open_square_message_send)

2855 LBracLoc = Loc;

2856 }

2857

2858

2859

2860 if (Receiver) {

2863 if (Receiver->getType() == Context.UnknownAnyTy)

2865 SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());

2866 else

2867 Result = SemaRef.CheckPlaceholderExpr(Receiver);

2869 Receiver = Result.get();

2870 }

2871

2873

2874

2875 unsigned NumArgs = ArgsIn.size();

2876 Expr **Args = ArgsIn.data();

2877 assert(SuperLoc.isInvalid() && "Message to super with dependent type");

2879 Context, Context.DependentTy, VK_PRValue, LBracLoc, Receiver, Sel,

2880 SelectorLocs, nullptr, ArrayRef(Args, NumArgs), RBracLoc,

2881 isImplicit);

2882 }

2883

2884

2885

2887 if (Result.isInvalid())

2889 Receiver = Result.get();

2890 ReceiverType = Receiver->getType();

2891

2892

2893

2894

2896

2897 } else if (getLangOpts().ObjCAutoRefCount &&

2898 !Context.getObjCIdType().isNull() &&

2901

2902

2903 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;

2906 .ImpCastExprToType(Receiver, Context.getObjCIdType(),

2907 CK_CPointerToObjCPointerCast)

2908 .get();

2909 } else {

2910

2913 CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;

2914 Receiver =

2915 SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)

2916 .get();

2917 }

2918 ReceiverType = Receiver->getType();

2920

2921 if (SemaRef.RequireCompleteType(Loc, Receiver->getType(),

2922 diag::err_incomplete_receiver_type))

2924

2926 SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);

2928 Receiver = result.get();

2929 ReceiverType = Receiver->getType();

2930 }

2931 }

2932 }

2933

2934

2935

2936

2937

2939

2940

2943 typeBound);

2945 (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {

2947

2949 true, typeBound);

2950 if (!Methods.empty()) {

2951

2952

2953 Method = Methods[0];

2954

2956 Sel, ArgsIn, Method->isInstanceMethod(), Methods))

2957 Method = BestMethod;

2958

2961 receiverIsIdLike, Methods))

2962 SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs);

2963 }

2966

2967

2968

2969

2973

2977

2979 Diag(SelLoc, diag::warn_instance_method_on_class_found)

2980 << Method->getSelector() << Sel;

2981 Diag(Method->getLocation(), diag::note_method_declared_at)

2982 << Method->getDeclName();

2983 }

2984 }

2985 } else {

2987 if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {

2988

2989

2990

2991

2992 Method = ClassDecl->lookupClassMethod(Sel);

2993

2995 Method = ClassDecl->lookupPrivateClassMethod(Sel);

2996

2999 }

3000 }

3002

3003 if (!Receiver || isSelfExpr(Receiver)) {

3004

3005

3008 false,

3009 true);

3010 if (!Methods.empty()) {

3011

3012

3013 Method = Methods[0];

3014

3015

3016 if (Method->isInstanceMethod()) {

3018 dyn_cast(Method->getDeclContext())) {

3019 if (ID->getSuperClass())

3020 Diag(SelLoc, diag::warn_root_inst_method_not_found)

3021 << Sel << SourceRange(LBracLoc, RBracLoc);

3022 }

3023 }

3024

3026 Sel, ArgsIn, Method->isInstanceMethod(), Methods))

3027 Method = BestMethod;

3028 }

3029 }

3030 }

3031 }

3032 } else {

3034

3035

3036

3037

3040

3048

3049 ClassDecl = OCIType->getInterfaceDecl();

3050

3051

3052

3053

3054

3056 if (SemaRef.RequireCompleteType(

3057 Loc, OCIType->getPointeeType(),

3059 ? diag::err_arc_receiver_forward_instance

3060 : diag::warn_receiver_forward_instance,

3061 RecRange)) {

3064

3065 forwardClass = OCIType->getInterfaceDecl();

3067 diag::note_receiver_is_id);

3069 } else {

3071 }

3072

3074

3076

3078

3080

3082 Diag(SelLoc, diag::err_arc_may_not_respond)

3083 << OCIType->getPointeeType() << Sel << RecRange

3084 << SourceRange(SelectorLocs.front(), SelectorLocs.back());

3086 }

3087

3089

3090

3091

3092 if (OCIType->qual_empty()) {

3095 true,

3096 false);

3097 if (!Methods.empty()) {

3098

3099

3100 Method = Methods[0];

3101

3103 Sel, ArgsIn, Method->isInstanceMethod(), Methods))

3104 Method = BestMethod;

3105

3108 true,

3109 Methods);

3110 }

3111 if (Method && !forwardClass)

3112 Diag(SelLoc, diag::warn_maynot_respond)

3113 << OCIType->getInterfaceDecl()->getIdentifier()

3114 << Sel << RecRange;

3115 }

3116 }

3117 }

3119 SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass))

3121 } else {

3122

3123 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;

3125 }

3126 }

3127 }

3128

3131 ? SemaRef.getEnclosingFunction()

3132 : nullptr;

3133

3135 if (ReceiverType->isObjCIdType() && !isImplicit) {

3137 diag::err_messaging_unqualified_id_with_direct_method);

3138 Diag(Method->getLocation(), diag::note_direct_method_declared_at)

3139 << Method->getDeclName();

3140 }

3141

3142

3143

3144

3147 {

3149 diag::err_messaging_class_with_direct_method);

3152 RecRange, Method->getClassInterface()->getName()));

3153 }

3154 }

3155 Diag(Method->getLocation(), diag::note_direct_method_declared_at)

3156 << Method->getDeclName();

3157 }

3158

3159 if (SuperLoc.isValid()) {

3160 {

3161 auto Builder =

3162 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);

3165 SuperLoc, Method->getClassInterface()->getName()));

3166 } else {

3168 }

3169 }

3170 Diag(Method->getLocation(), diag::note_direct_method_declared_at)

3171 << Method->getDeclName();

3172 }

3173 } else if (ReceiverType->isObjCIdType() && !isImplicit) {

3174 Diag(Receiver->getExprLoc(), diag::warn_messaging_unqualified_id);

3175 }

3176

3177 if (DIFunctionScopeInfo &&

3180 bool isDesignatedInitChain = false;

3181 if (SuperLoc.isValid()) {

3184 if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {

3185

3186

3187 if (!ID->declaresOrInheritsDesignatedInitializers() ||

3188 ID->isDesignatedInitializer(Sel)) {

3189 isDesignatedInitChain = true;

3191 }

3192 }

3193 }

3194 }

3195 if (!isDesignatedInitChain) {

3197 auto *CurMD = SemaRef.getCurMethodDecl();

3198 assert(CurMD && "Current method declaration should not be null");

3199 bool isDesignated =

3200 CurMD->isDesignatedInitializerForTheInterface(&InitMethod);

3201 assert(isDesignated && InitMethod);

3202 (void)isDesignated;

3204 diag::warn_objc_designated_init_non_designated_init_call :

3205 diag::warn_objc_designated_init_non_super_designated_init_call);

3207 diag::note_objc_designated_init_marked_here);

3208 }

3209 }

3210

3211 if (DIFunctionScopeInfo &&

3214 if (SuperLoc.isValid()) {

3215 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);

3216 } else {

3218 }

3219 }

3220

3221

3222 unsigned NumArgs = ArgsIn.size();

3223 Expr **Args = ArgsIn.data();

3229 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,

3231 LBracLoc, RBracLoc, RecRange, ReturnType, VK))

3233

3234 if (Method && Method->getReturnType()->isVoidType() &&

3235 SemaRef.RequireCompleteType(

3236 LBracLoc, Method->getReturnType(),

3237 diag::err_illegal_message_expr_incomplete_type))

3239

3240

3241

3245 switch (family) {

3249 break;

3250

3259 break;

3260

3266 Diag(SelLoc, diag::err_arc_illegal_explicit_message)

3267 << Sel << RecRange;

3268 break;

3269

3271 if (Method && NumArgs >= 1) {

3272 if (const auto *SelExp =

3273 dyn_cast(Args[0]->IgnoreParens())) {

3274 Selector ArgSel = SelExp->getSelector();

3277 SelExp->getSourceRange());

3278 if (!SelMethod)

3279 SelMethod =

3281 SelExp->getSourceRange());

3282 if (SelMethod) {

3284 switch (SelFamily) {

3290

3291 if (!SelMethod->hasAttr()) {

3292

3293 Diag(SelLoc,

3294 diag::err_arc_perform_selector_retains);

3295 Diag(SelMethod->getLocation(), diag::note_method_declared_at)

3297 }

3298 break;

3299 default:

3300

3301 if (SelMethod->hasAttr()) {

3302

3303 Diag(SelLoc,

3304 diag::err_arc_perform_selector_retains);

3305 Diag(SelMethod->getLocation(), diag::note_method_declared_at)

3307 }

3308 break;

3309 }

3310 }

3311 } else {

3312

3313 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);

3314 Diag(Args[0]->getExprLoc(), diag::note_used_here);

3315 }

3316 }

3317 break;

3318 }

3319 }

3320

3322

3323

3327 Context, ReturnType, VK, LBracLoc, SuperLoc, true,

3328 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),

3329 RBracLoc, isImplicit);

3330 else {

3332 Context, ReturnType, VK, LBracLoc, Receiver, Sel, SelectorLocs, Method,

3333 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);

3334 if (!isImplicit)

3336 }

3338 bool IsClassObjectCall = ClassMessage;

3339

3340

3341

3342

3343 if (Receiver && isSelfExpr(Receiver)) {

3345 if (OPT->getObjectType()->isObjCClass()) {

3346 if (const auto *CurMeth = SemaRef.getCurMethodDecl()) {

3347 IsClassObjectCall = true;

3348 ReceiverType =

3349 Context.getObjCInterfaceType(CurMeth->getClassInterface());

3350 }

3351 }

3352 }

3353 }

3355 ReceiverType, IsClassObjectCall);

3356 }

3357

3359

3362

3363

3366

3367

3368 Result->setDelegateInitCall(true);

3370 }

3371 }

3372

3373

3374

3376 }

3377

3379 if (!isImplicit && Method) {

3381 bool IsWeak =

3385 if (IsWeak && SemaRef.isUnevaluatedContext() &&

3386 getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak,

3387 LBracLoc))

3388 SemaRef.getCurFunction()->recordUseOfWeak(Result, Prop);

3389 }

3390 }

3391 }

3392

3394

3396}

3397

3401 Selector Sel = OSE->getSelector();

3406 }

3407}

3408

3409

3410

3411

3418 if (!Receiver)

3420

3421

3424 SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);

3426 Receiver = Result.get();

3427 }

3428

3430 IdentifierInfo *SelectorId = &Context.Idents.get("respondsToSelector");

3432 }

3435

3438 nullptr, LBracLoc, SelectorLocs,

3439 RBracLoc, Args);

3440}

3441

3443

3445

3446

3448

3449

3451

3452

3454

3455

3457};

3458

3464

3470

3472 bool isIndirect = false;

3473

3474

3476 type = ref->getPointeeType();

3477 isIndirect = true;

3478 }

3479

3480

3481 while (true) {

3483 type = ptr->getPointeeType();

3484

3485

3486 if (!isIndirect) {

3489 }

3490 } else if (const ArrayType *array = type->getAsArrayTypeUnsafe()) {

3491 type = QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);

3492 } else {

3493 break;

3494 }

3495 isIndirect = true;

3496 }

3497

3498 if (isIndirect) {

3499 if (type->isObjCARCBridgableType())

3502 }

3503

3504 if (type->isObjCARCBridgableType())

3506

3508}

3509

3510namespace {

3511

3512 enum ACCResult {

3513

3514 ACC_invalid,

3515

3516

3517 ACC_bottom,

3518

3519

3520 ACC_plusZero,

3521

3522

3523 ACC_plusOne

3524 };

3525 ACCResult merge(ACCResult left, ACCResult right) {

3526 if (left == right) return left;

3527 if (left == ACC_bottom) return right;

3528 if (right == ACC_bottom) return left;

3529 return ACC_invalid;

3530 }

3531

3532

3533

3534 class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {

3535 typedef StmtVisitor<ARCCastChecker, ACCResult> super;

3536

3537 ASTContext &Context;

3540 bool Diagnose;

3541

3542 static bool isCFType(QualType type) {

3543

3544 return type->isCARCBridgableType();

3545 }

3546

3547 public:

3550 : Context(Context), SourceClass(source), TargetClass(target),

3551 Diagnose(diagnose) {}

3552

3553 using super::Visit;

3554 ACCResult Visit(Expr *e) {

3556 }

3557

3558 ACCResult VisitStmt(Stmt *s) {

3559 return ACC_invalid;

3560 }

3561

3562

3563 ACCResult VisitExpr(Expr *e) {

3565 return ACC_bottom;

3566 return ACC_invalid;

3567 }

3568

3569

3570 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *e) {

3571

3572

3574

3575 return ACC_invalid;

3576 }

3577

3578

3579 ACCResult VisitCastExpr(CastExpr *e) {

3581 case CK_NullToPointer:

3582 return ACC_bottom;

3583

3584 case CK_NoOp:

3585 case CK_LValueToRValue:

3586 case CK_BitCast:

3587 case CK_CPointerToObjCPointerCast:

3588 case CK_BlockPointerToObjCPointerCast:

3589 case CK_AnyPointerToBlockPointerCast:

3591

3592 default:

3593 return ACC_invalid;

3594 }

3595 }

3596

3597

3598 ACCResult VisitUnaryExtension(UnaryOperator *e) {

3600 }

3601

3602

3603 ACCResult VisitBinComma(BinaryOperator *e) {

3604 return Visit(e->getRHS());

3605 }

3606

3607

3608 ACCResult VisitConditionalOperator(ConditionalOperator *e) {

3609 ACCResult left = Visit(e->getTrueExpr());

3610 if (left == ACC_invalid) return ACC_invalid;

3612 }

3613

3614

3615 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {

3616

3618 }

3619

3620

3621 ACCResult VisitStmtExpr(StmtExpr *e) {

3623 }

3624

3625

3626 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {

3627 VarDecl *var = dyn_cast(e->getDecl());

3628

3631 var &&

3632 var->hasDefinition(Context) &&

3633 var->getType().isConstQualified()) {

3634

3635

3636

3638 return ACC_bottom;

3639

3640 return ACC_plusZero;

3641 }

3642

3643

3644 return ACC_invalid;

3645 }

3646

3647

3648 ACCResult VisitCallExpr(CallExpr *e) {

3650 if (ACCResult result = checkCallToFunction(fn))

3651 return result;

3652

3653 return super::VisitCallExpr(e);

3654 }

3655

3656 ACCResult checkCallToFunction(FunctionDecl *fn) {

3657

3659 return ACC_invalid;

3660

3662 return ACC_invalid;

3663

3664

3665 if (fn->hasAttr())

3666 return ACC_plusZero;

3667

3668

3669

3670

3671 if (fn->hasAttr())

3672 return Diagnose ? ACC_plusOne

3673 : ACC_invalid;

3674

3675

3677 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)

3678 return ACC_bottom;

3679

3680

3681 if (!fn->hasAttr())

3682 return ACC_invalid;

3683

3684

3686 return Diagnose ? ACC_plusOne

3687 : ACC_invalid;

3688

3689 return ACC_plusZero;

3690 }

3691

3692 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {

3694 }

3695

3696 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {

3697 ObjCMethodDecl *method;

3700 else

3702 return checkCallToMethod(method);

3703 }

3704

3705 ACCResult checkCallToMethod(ObjCMethodDecl *method) {

3706 if (!method) return ACC_invalid;

3707

3708

3709

3710

3712 return ACC_invalid;

3713

3714

3715 if (method->hasAttr())

3716 return ACC_plusZero;

3717

3718

3719

3720 if (method->hasAttr())

3721 return ACC_plusOne;

3722

3728 return ACC_plusOne;

3729

3730 default:

3731

3732 return ACC_plusZero;

3733 }

3734 }

3735 };

3736}

3737

3740 if (name.empty())

3741 return false;

3744 return SemaRef.LookupName(R, SemaRef.TUScope, false);

3745}

3746

3747template

3751 Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {

3752

3753 switch (CCK) {

3758 break;

3760 return;

3761 }

3762

3763 if (CFBridgeName) {

3765 if (const CXXNamedCastExpr *NCE = dyn_cast(realCast)) {

3766 SourceRange range(NCE->getOperatorLoc(),

3767 NCE->getAngleBrackets().getEnd());

3769

3771 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));

3773 BridgeCall += ' ';

3774

3775 BridgeCall += CFBridgeName;

3777 }

3778 return;

3779 }

3781 if (CStyleCastExpr *CCE = dyn_cast(castedE))

3782 castedE = CCE->getSubExpr();

3785

3787

3789 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));

3791 BridgeCall += ' ';

3792

3793 BridgeCall += CFBridgeName;

3794

3797 BridgeCall));

3798 } else {

3799 BridgeCall += '(';

3801 BridgeCall));

3804 ")"));

3805 }

3806 return;

3807 }

3808

3812 if (const CXXNamedCastExpr *NCE = dyn_cast(realCast)) {

3813 std::string castCode = "(";

3814 castCode += bridgeKeyword;

3816 castCode += ")";

3817 SourceRange Range(NCE->getOperatorLoc(),

3818 NCE->getAngleBrackets().getEnd());

3820 }

3821 } else {

3822 std::string castCode = "(";

3823 castCode += bridgeKeyword;

3825 castCode += ")";

3830 castCode));

3831 } else {

3832 castCode += "(";

3834 castCode));

3837 ")"));

3838 }

3839 }

3840}

3841

3842template

3848 if (const RecordType *RT = QT->getAsCanonical()) {

3849 for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {

3850 if (auto *attr = Redecl->getAttr<T>())

3851 return attr;

3852 }

3853 }

3854 }

3855 return nullptr;

3856}

3857

3860 while (const auto *TD = T->getAs<TypedefType>()) {

3861 TDNDecl = TD->getDecl();

3862 if (ObjCBridgeRelatedAttr *ObjCBAttr =

3864 return ObjCBAttr;

3866 }

3867 return nullptr;

3868}

3869

3878

3880 UnavailableAttr::IR_ARCForbiddenConversion))

3881 return;

3882

3884

3885

3891 return;

3892

3893 unsigned srcKind = 0;

3894 switch (exprACTC) {

3898 srcKind = (castExprType->isPointerType() ? 1 : 0);

3899 break;

3902 break;

3904 srcKind = 4;

3905 break;

3906 }

3907

3908

3911

3912 unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1;

3913

3914

3916

3917 S.Diag(loc, diag::err_arc_cast_requires_bridge)

3918 << convKindForDiag

3919 << 2

3920 << castExprType

3922 << castType

3923 << castRange

3924 << castExpr->getSourceRange();

3926 ACCResult CreateRule =

3927 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);

3928 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");

3929 if (CreateRule != ACC_plusOne)

3930 {

3932 ? S.Diag(noteLoc, diag::note_arc_bridge)

3933 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);

3934

3936 castType, castExpr, realCast, "__bridge ",

3937 nullptr);

3938 }

3939 if (CreateRule != ACC_plusZero)

3940 {

3942 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)

3943 << castExprType

3944 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,

3945 diag::note_arc_bridge_transfer)

3946 << castExprType << br;

3947

3949 castType, castExpr, realCast, "__bridge_transfer ",

3950 br ? "CFBridgingRelease" : nullptr);

3951 }

3952

3953 return;

3954 }

3955

3956

3959 S.Diag(loc, diag::err_arc_cast_requires_bridge)

3960 << convKindForDiag

3962 << castExprType

3963 << 2

3964 << castType

3965 << castRange

3966 << castExpr->getSourceRange();

3967 ACCResult CreateRule =

3968 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);

3969 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");

3970 if (CreateRule != ACC_plusOne)

3971 {

3973 ? S.Diag(noteLoc, diag::note_arc_bridge)

3974 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);

3976 castType, castExpr, realCast, "__bridge ",

3977 nullptr);

3978 }

3979 if (CreateRule != ACC_plusZero)

3980 {

3982 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)

3983 << castType

3984 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,

3985 diag::note_arc_bridge_retained)

3986 << castType << br;

3987

3989 castType, castExpr, realCast, "__bridge_retained ",

3990 br ? "CFBridgingRetain" : nullptr);

3991 }

3992

3993 return;

3994 }

3995

3996 S.Diag(loc, diag::err_arc_mismatched_cast)

3997 << !convKindForDiag

3998 << srcKind << castExprType << castType

3999 << castRange << castExpr->getSourceRange();

4000}

4001

4002template

4004 bool &HadTheAttribute, bool warn) {

4006 HadTheAttribute = false;

4007 while (const auto *TD = T->getAs<TypedefType>()) {

4010 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {

4011 HadTheAttribute = true;

4012 if (Parm->isStr("id"))

4013 return true;

4014

4015

4025 = InterfacePointerType->getObjectType()->getInterface();

4026 if ((CastClass == ExprClass) ||

4027 (CastClass && CastClass->isSuperClassOf(ExprClass)))

4028 return true;

4029 if (warn)

4030 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)

4032 return false;

4035 castType, ExprClass)))

4036

4037

4038

4039 return true;

4040 else {

4041 if (warn) {

4042 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)

4043 << T << Target->getName() << castType;

4045 S.Diag(Target->getBeginLoc(), diag::note_declared_at);

4046 }

4047 return false;

4048 }

4049 }

4052 diag::err_objc_cf_bridged_not_interface)

4053 << castExpr->getType() << Parm;

4055 }

4056 return true;

4057 }

4058 return false;

4059 }

4061 }

4062 return true;

4063}

4064

4065template

4067 bool &HadTheAttribute, bool warn) {

4069 HadTheAttribute = false;

4070 while (const auto *TD = T->getAs<TypedefType>()) {

4073 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {

4074 HadTheAttribute = true;

4075 if (Parm->isStr("id"))

4076 return true;

4077

4079

4087 castExpr->getType()->getAsObjCInterfacePointerType()) {

4089 = InterfacePointerType->getObjectType()->getInterface();

4090 if ((CastClass == ExprClass) ||

4091 (ExprClass && CastClass->isSuperClassOf(ExprClass)))

4092 return true;

4093 if (warn) {

4095 diag::warn_objc_invalid_bridge_to_cf)

4096 << castExpr->getType()->getPointeeType() << T;

4098 }

4099 return false;

4100 } else if (castExpr->getType()->isObjCIdType() ||

4102 castExpr->getType(), CastClass)))

4103

4104

4105

4106 return true;

4107 else {

4108 if (warn) {

4110 diag::warn_objc_invalid_bridge_to_cf)

4111 << castExpr->getType() << castType;

4113 S.Diag(Target->getBeginLoc(), diag::note_declared_at);

4114 }

4115 return false;

4116 }

4117 }

4118 }

4120 diag::err_objc_ns_bridged_invalid_cfobject)

4121 << castExpr->getType() << castType;

4124 S.Diag(Target->getBeginLoc(), diag::note_declared_at);

4125 return true;

4126 }

4127 return false;

4128 }

4130 }

4131 return true;

4132}

4133

4136 return;

4137

4141 bool HasObjCBridgeAttr;

4144 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)

4145 return;

4146 bool HasObjCBridgeMutableAttr;

4147 bool ObjCBridgeMutableAttrWillNotWarn =

4149 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);

4150 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)

4151 return;

4152

4153 if (HasObjCBridgeAttr)

4155 HasObjCBridgeAttr, true);

4156 else if (HasObjCBridgeMutableAttr)

4158 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);

4159 }

4161 bool HasObjCBridgeAttr;

4164 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)

4165 return;

4166 bool HasObjCBridgeMutableAttr;

4167 bool ObjCBridgeMutableAttrWillNotWarn =

4169 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);

4170 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)

4171 return;

4172

4173 if (HasObjCBridgeAttr)

4175 HasObjCBridgeAttr, true);

4176 else if (HasObjCBridgeMutableAttr)

4178 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);

4179 }

4180}

4181

4185 if (PRE->isExplicitProperty()) {

4187 SrcType = PDecl->getType();

4188 }

4189 else if (PRE->isImplicitProperty()) {

4190 if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())

4191 SrcType = Getter->getReturnType();

4192 }

4193 }

4194

4198 return;

4201}

4202

4206 return false;

4214 : CK_CPointerToObjCPointerCast;

4215 return true;

4216 }

4217 return false;

4218}

4219

4224 bool Diagnose) {

4226 QualType T = CfToNs ? SrcType : DestType;

4228 if (!ObjCBAttr)

4229 return false;

4230

4231 IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();

4233 IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();

4234 if (!RCId)

4235 return false;

4237

4241 if (Diagnose) {

4242 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId

4243 << SrcType << DestType;

4245 }

4246 return false;

4247 }

4251 else {

4252 if (Diagnose) {

4253 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId

4254 << SrcType << DestType;

4257 Diag(Target->getBeginLoc(), diag::note_declared_at);

4258 }

4259 return false;

4260 }

4261

4262

4263 if (CfToNs && CMId) {

4264 Selector Sel = Context.Selectors.getUnarySelector(CMId);

4265 ClassMethod = RelatedClass->lookupMethod(Sel, false);

4266 if (!ClassMethod) {

4267 if (Diagnose) {

4268 Diag(Loc, diag::err_objc_bridged_related_known_method)

4269 << SrcType << DestType << Sel << false;

4271 }

4272 return false;

4273 }

4274 }

4275

4276

4277 if (!CfToNs && IMId) {

4278 Selector Sel = Context.Selectors.getNullarySelector(IMId);

4279 InstanceMethod = RelatedClass->lookupMethod(Sel, true);

4280 if (!InstanceMethod) {

4281 if (Diagnose) {

4282 Diag(Loc, diag::err_objc_bridged_related_known_method)

4283 << SrcType << DestType << Sel << true;

4285 }

4286 return false;

4287 }

4288 }

4289 return true;

4290}

4291

4295 Expr *&SrcExpr,

4296 bool Diagnose) {

4302 if (!CfToNs && !NsToCf)

4303 return false;

4304

4310 ClassMethod, InstanceMethod, TDNDecl,

4311 CfToNs, Diagnose))

4312 return false;

4313

4314 if (CfToNs) {

4315

4316 if (ClassMethod) {

4317 if (Diagnose) {

4318 std::string ExpressionString = "[";

4320 ExpressionString += " ";

4321 ExpressionString += ClassMethod->getSelector().getAsString();

4324

4325 Diag(Loc, diag::err_objc_bridged_related_known_method)

4326 << SrcType << DestType << ClassMethod->getSelector() << false

4328 ExpressionString)

4330 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);

4332

4333 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);

4334

4335 Expr *args[] = { SrcExpr };

4337 ClassMethod->getLocation(),

4338 ClassMethod->getSelector(), ClassMethod,

4340 SrcExpr = msg.get();

4341 }

4342 return true;

4343 }

4344 }

4345 else {

4346

4347 if (InstanceMethod) {

4348 if (Diagnose) {

4349 std::string ExpressionString;

4352 if (InstanceMethod->isPropertyAccessor())

4354 InstanceMethod->findPropertyDecl()) {

4355

4356 ExpressionString = ".";

4357 ExpressionString += PDecl->getNameAsString();

4358 Diag(Loc, diag::err_objc_bridged_related_known_method)

4359 << SrcType << DestType << InstanceMethod->getSelector() << true

4361 }

4362 if (ExpressionString.empty()) {

4363

4364 ExpressionString = " ";

4365 ExpressionString += InstanceMethod->getSelector().getAsString();

4366 ExpressionString += "]";

4367

4368 Diag(Loc, diag::err_objc_bridged_related_known_method)

4369 << SrcType << DestType << InstanceMethod->getSelector() << true

4372 }

4373 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);

4375

4377 SrcExpr, SrcType, InstanceMethod->getLocation(),

4378 InstanceMethod->getSelector(), InstanceMethod, {});

4379 SrcExpr = msg.get();

4380 }

4381 return true;

4382 }

4383 }

4384 return false;

4385}

4386

4390 bool Diagnose, bool DiagnoseCFAudited,

4394

4395

4396

4397 QualType effCastType = castType;

4400

4403 if (exprACTC == castACTC) {

4404

4405

4409 castType != castExprType) {

4412

4413

4414

4415 if (const ParenType *PT = dyn_cast(DT))

4416 QDT = PT->desugar();

4417 else if (const TypeOfType *TP = dyn_cast(DT))

4418 QDT = TP->desugar();

4419 else if (const AttributedType *AT = dyn_cast(DT))

4420 QDT = AT->desugar();

4421 if (QDT != castType &&

4423 if (Diagnose) {

4426 Diag(loc, diag::err_arc_nolifetime_behavior);

4427 }

4429 }

4430 }

4432 }

4433

4434

4435

4438

4440

4441

4442

4445

4446

4447

4448

4449

4450

4451

4452

4463

4464 switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {

4465

4466 case ACC_invalid:

4467 break;

4468

4469

4470 case ACC_bottom:

4471 case ACC_plusZero:

4473

4474

4475 case ACC_plusOne:

4477 CK_ARCConsumeObject, castExpr, nullptr,

4479 SemaRef.Cleanup.setExprNeedsCleanups(true);

4481 }

4482

4483

4484

4485

4489

4490

4491

4492

4496

4497

4498

4499

4500

4501 if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||

4504 (Opc == BO_NE || Opc == BO_EQ))) {

4505 if (Diagnose)

4509 }

4511}

4512

4513

4514

4516

4519

4523

4526 castType = cast->getTypeAsWritten();

4529 castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();

4530 castType = cast->getTypeAsWritten();

4532 } else {

4533 llvm_unreachable("Unexpected ImplicitCastExpr");

4534 }

4535

4538

4541

4544}

4545

4546

4547

4551

4552 if (ParenExpr *pe = dyn_cast(e)) {

4554 return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);

4555 } else if (UnaryOperator *uo = dyn_cast(e)) {

4556 assert(uo->getOpcode() == UO_Extension);

4560 uo->getOperatorLoc(), false,

4561 SemaRef.CurFPFeatureOverrides());

4563 assert(!gse->isResultDependent());

4564 assert(!gse->isTypePredicate());

4565

4566 unsigned n = gse->getNumAssocs();

4569 subExprs.reserve(n);

4570 subTypes.reserve(n);

4572 subTypes.push_back(assoc.getTypeSourceInfo());

4573 Expr *sub = assoc.getAssociationExpr();

4574 if (assoc.isSelected())

4576 subExprs.push_back(sub);

4577 }

4578

4580 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,

4581 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),

4582 gse->containsUnexpandedParameterPack(), gse->getResultIndex());

4583 } else {

4586 }

4587}

4588

4602 return !ObjI->isArcWeakrefUnavailable();

4603 }

4604 return true;

4605}

4606

4607

4609 Expr *curExpr = e, *prevExpr = nullptr;

4610

4611

4612

4613 while (true) {

4614 if (auto *pe = dyn_cast(curExpr)) {

4615 prevExpr = curExpr;

4616 curExpr = pe->getSubExpr();

4617 continue;

4618 }

4619

4620 if (auto *ce = dyn_cast(curExpr)) {

4621 if (auto *ice = dyn_cast(ce))

4622 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {

4623 if (!prevExpr)

4624 return ice->getSubExpr();

4625 if (auto *pe = dyn_cast(prevExpr))

4626 pe->setSubExpr(ice->getSubExpr());

4627 else

4628 cast(prevExpr)->setSubExpr(ice->getSubExpr());

4629 return e;

4630 }

4631

4632 prevExpr = curExpr;

4633 curExpr = ce->getSubExpr();

4634 continue;

4635 }

4636

4637

4638 break;

4639 }

4640

4641 return e;

4642}

4643

4648 Expr *SubExpr) {

4652 SubExpr = SubResult.get();

4653

4656

4658

4659 bool MustConsume = false;

4661

4662 CK = CK_Dependent;

4663 } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) {

4664

4665 CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast

4666 : CK_CPointerToObjCPointerCast);

4667 switch (Kind) {

4669 break;

4670

4672 bool br = isKnownName("CFBridgingRelease");

4673 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)

4674 << 2

4675 << FromType

4676 << (T->isBlockPointerType()? 1 : 0)

4677 << T

4679 << Kind;

4680 Diag(BridgeKeywordLoc, diag::note_arc_bridge)

4682 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)

4683 << FromType << br

4685 br ? "CFBridgingRelease "

4686 : "__bridge_transfer ");

4687

4689 break;

4690 }

4691

4693

4694 MustConsume = true;

4695 break;

4696 }

4698

4699 CK = CK_BitCast;

4700 switch (Kind) {

4702

4703

4705 break;

4706

4708

4712 break;

4713

4715 bool br = isKnownName("CFBridgingRetain");

4716 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)

4718 << FromType

4719 << 2

4720 << T

4722 << Kind;

4723

4724 Diag(BridgeKeywordLoc, diag::note_arc_bridge)

4726 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)

4727 << T << br

4729 br ? "CFBridgingRetain " : "__bridge_retained");

4730

4732 break;

4733 }

4734 }

4735 } else {

4736 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)

4737 << FromType << T << Kind

4741 }

4742

4744 BridgeKeywordLoc,

4745 TSInfo, SubExpr);

4746

4747 if (MustConsume) {

4748 SemaRef.Cleanup.setExprNeedsCleanups(true);

4751 }

4752

4754}

4755

4761 Expr *SubExpr) {

4767 if (!TSInfo)

4768 TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);

4770 SubExpr);

4771}

4772

4777

4778

4779 if (!CurMethod)

4781

4782

4783

4784

4785

4786

4787

4788

4789

4790

4791 bool IsClassMethod = CurMethod->isClassMethod();

4792

4793 bool LookForIvars;

4794 if (Lookup.empty())

4795 LookForIvars = true;

4796 else if (IsClassMethod)

4797 LookForIvars = false;

4798 else

4802 if (LookForIvars) {

4807

4808 if (IsClassMethod) {

4809 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();

4811 }

4812

4813

4817 Diag(Loc, diag::err_private_ivar_access) << IV->getDeclName();

4818

4819

4820 return IV;

4821 }

4823

4829 Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();

4830 }

4831 }

4834

4836 dyn_cast(Lookup.getFoundDecl())) {

4837 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();

4839 }

4840 }

4841

4842

4844}

4845

4848 bool AllowBuiltinCreation) {

4849

4856

4857 if (Lookup.empty() && II && AllowBuiltinCreation)

4858 SemaRef.LookupBuiltin(Lookup);

4859

4860

4862}

4863

4869 "should not reference ivar from this context");

4870

4872 assert(IFace && "should not reference ivar from this context");

4873

4874

4875

4878

4879

4880 if (SemaRef.DiagnoseUseOfDecl(IV, Loc))

4882

4883

4884

4891 SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,

4892 false,

4893 false);

4896

4897 SelfExpr = SemaRef.DefaultLvalueConversion(SelfExpr.get());

4900

4901 SemaRef.MarkAnyDeclReferenced(Loc, IV, true);

4902

4906 Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName();

4907

4911

4913 if (SemaRef.isUnevaluatedContext() &&

4914 getDiagnostics().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))

4915 SemaRef.getCurFunction()->recordUseOfWeak(Result);

4916 }

4917 if (getLangOpts().ObjCAutoRefCount && SemaRef.isUnevaluatedContext())

4918 if (const BlockDecl *BD = SemaRef.CurContext->getInnermostBlockDecl())

4919 SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});

4920

4922}

4923

4930

4931

4932

4933

4935 (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {

4936 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,

4937 CK_CPointerToObjCPointerCast);

4938 return LHSTy;

4939 }

4941 (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {

4942 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,

4943 CK_CPointerToObjCPointerCast);

4944 return RHSTy;

4945 }

4946

4948 (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {

4949 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,

4950 CK_CPointerToObjCPointerCast);

4951 return LHSTy;

4952 }

4954 (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {

4955 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,

4956 CK_CPointerToObjCPointerCast);

4957 return RHSTy;

4958 }

4959

4960 if (Context.isObjCSelType(LHSTy) &&

4961 (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {

4962 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast);

4963 return LHSTy;

4964 }

4965 if (Context.isObjCSelType(RHSTy) &&

4966 (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {

4967 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast);

4968 return RHSTy;

4969 }

4970

4972

4973 if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {

4974

4975 return LHSTy;

4976 }

4981 QualType compositeType = LHSTy;

4982

4983

4984

4985

4986

4987

4988

4989

4990

4991

4992

4993

4994

4995

4996 if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))

4997 .isNull()) {

4998

4999 } else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {

5000 compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;

5001 } else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {

5004 RHSOPT->isObjCQualifiedIdType()) &&

5005 Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,

5006 true)) {

5007

5008

5009

5010

5011 compositeType = Context.getObjCIdType();

5013 compositeType = Context.getObjCIdType();

5014 } else {

5015 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)

5018 QualType incompatTy = Context.getObjCIdType();

5019 LHS = SemaRef.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);

5020 RHS = SemaRef.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);

5021 return incompatTy;

5022 }

5023

5024 LHS = SemaRef.ImpCastExprToType(LHS.get(), compositeType, CK_BitCast);

5025 RHS = SemaRef.ImpCastExprToType(RHS.get(), compositeType, CK_BitCast);

5026 return compositeType;

5027 }

5028

5031

5032

5033 Diag(QuestionLoc, diag::err_cond_voidptr_arc)

5036 LHS = RHS = true;

5038 }

5042 Context.getQualifiedType(lhptee, rhptee.getQualifiers());

5043 QualType destType = Context.getPointerType(destPointee);

5044

5045 LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_NoOp);

5046

5047 RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_BitCast);

5048 return destType;

5049 }

5052

5053

5054 Diag(QuestionLoc, diag::err_cond_voidptr_arc)

5057 LHS = RHS = true;

5059 }

5063 Context.getQualifiedType(rhptee, lhptee.getQualifiers());

5064 QualType destType = Context.getPointerType(destPointee);

5065

5066 RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_NoOp);

5067

5068 LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_BitCast);

5069 return destType;

5070 }

5072}

5073

5075 bool Diagnose) {

5077 return false;

5078

5080 if (!PT)

5081 return false;

5083

5084

5085

5086

5088 if (OpaqueValueExpr *OV = dyn_cast(SrcExpr))

5089 if (OV->getSourceExpr())

5091

5092 if (auto *SL = dyn_cast(SrcExpr)) {

5093 if (!PT->isObjCIdType() && !(ID && ID->getIdentifier()->isStr("NSString")))

5094 return false;

5095 if (!SL->isOrdinary())

5096 return false;

5097

5098 if (Diagnose) {

5099 Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)

5102 }

5103 return true;

5104 }

5105

5111 if (!ID || !ID->getIdentifier()->isStr("NSNumber"))

5112 return false;

5113 if (Diagnose) {

5114 Diag(SrcExpr->getBeginLoc(), diag::err_missing_atsign_prefix)

5115 << 1

5117 Expr *NumLit =

5119 if (NumLit)

5120 Exp = NumLit;

5121 }

5122 return true;

5123 }

5124

5125 return false;

5126}

5127

5128

5131 assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&

5132 "Unknown Objective-C Boolean value!");

5134 QualType BoolT = Context.ObjCBuiltinBoolTy;

5135 if (!Context.getBOOLDecl()) {

5139 Result.isSingleResult()) {

5141 if (TypedefDecl *TD = dyn_cast(ND))

5142 Context.setBOOLDecl(TD);

5143 }

5144 }

5145 if (Context.getBOOLDecl())

5146 BoolT = Context.getBOOLType();

5147 return new (Context)

5149}

5150

5155 auto FindSpecVersion =

5156 [&](StringRef Platform,

5157 const llvm::Triple::OSType &OS) -> std::optional {

5158 auto Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {

5160 });

5161

5162

5163 if (Spec == AvailSpecs.end() && Platform == "maccatalyst") {

5164 Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {

5166 });

5167 }

5168 if (Spec == AvailSpecs.end())

5169 return std::nullopt;

5170

5171 return llvm::Triple::getCanonicalVersionForOS(

5173 llvm::Triple::isValidVersionForOS(OS, Spec->getVersion()));

5174 };

5175

5176 VersionTuple Version;

5177 if (auto MaybeVersion =

5178 FindSpecVersion(Context.getTargetInfo().getPlatformName(),

5179 Context.getTargetInfo().getTriple().getOS()))

5180 Version = *MaybeVersion;

5181

5182

5183

5185 Context->HasPotentialAvailabilityViolations = true;

5186

5187 return new (Context)

5189}

5190

5191

5192

5195 if (type->isObjCObjectPointerType()) {

5196 return CK_BitCast;

5197 } else if (type->isBlockPointerType()) {

5198 SemaRef.maybeExtendBlockObject(E);

5199 return CK_BlockPointerToObjCPointerCast;

5200 } else {

5201 assert(type->isPointerType());

5202 return CK_CPointerToObjCPointerCast;

5203 }

5204}

5205

5209 default:

5210 break;

5211 case Stmt::ObjCStringLiteralClass:

5212

5214 case Stmt::ObjCArrayLiteralClass:

5215

5217 case Stmt::ObjCDictionaryLiteralClass:

5218

5220 case Stmt::BlockExprClass:

5222 case Stmt::ObjCBoxedExprClass: {

5225 case Stmt::IntegerLiteralClass:

5226 case Stmt::FloatingLiteralClass:

5227 case Stmt::CharacterLiteralClass:

5228 case Stmt::ObjCBoolLiteralExprClass:

5229 case Stmt::CXXBoolLiteralExprClass:

5230

5232 case Stmt::ImplicitCastExprClass: {

5234

5235 if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast)

5237 break;

5238 }

5239 default:

5240 break;

5241 }

5243 }

5244 }

5246}

Defines the clang::ASTContext interface.

static StringRef bytes(const std::vector< T, Allocator > &v)

Defines enum values for all the target-independent builtin functions.

llvm::MachO::Target Target

Defines the clang::Preprocessor interface.

static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)

Definition SemaExprObjC.cpp:4003

static ObjCMethodDecl * getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc, QualType NumberType, bool isLiteral=false, SourceRange R=SourceRange())

Retrieve the NSNumber factory method that should be used to create an Objective-C literal for the giv...

Definition SemaExprObjC.cpp:247

static QualType stripObjCInstanceType(ASTContext &Context, QualType T)

Definition SemaExprObjC.cpp:1436

static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, QualType castType, ARCConversionTypeClass castACTC, Expr *castExpr, Expr *realCast, ARCConversionTypeClass exprACTC, CheckedConversionKind CCK)

Definition SemaExprObjC.cpp:3870

static ObjCInterfaceDecl * LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)

Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.

Definition SemaExprObjC.cpp:224

static ObjCMethodDecl * findMethodInCurrentClass(Sema &S, Selector Sel)

Definition SemaExprObjC.cpp:1274

static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg)

Definition SemaExprObjC.cpp:2488

static ObjCMethodDecl * LookupDirectMethodInGlobalPool(Sema &S, Selector Sel, bool &onlyDirect, bool &anyDirect)

Definition SemaExprObjC.cpp:1259

static Expr * maybeUndoReclaimObject(Expr *e)

Look for an ObjCReclaimReturnedObject cast and destroy it.

Definition SemaExprObjC.cpp:4608

static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)

Definition SemaExprObjC.cpp:4066

static void CheckObjCDictionaryLiteralDuplicateKeys(Sema &S, ObjCDictionaryLiteral *Literal)

Check for duplicate keys in an ObjC dictionary literal.

Definition SemaExprObjC.cpp:901

static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)

Validates ObjCInterfaceDecl availability.

Definition SemaExprObjC.cpp:201

static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind)

Maps ObjCLiteralKind to NSClassIdKindKind.

Definition SemaExprObjC.cpp:175

static bool isAnyCLike(ARCConversionTypeClass ACTC)

Definition SemaExprObjC.cpp:3465

static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc, ObjCMethodDecl *Method, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)

Definition SemaExprObjC.cpp:1207

static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S, SourceLocation AtLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, ObjCMethodDecl *Method, ObjCMethodList &MethList)

Definition SemaExprObjC.cpp:1176

static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg, unsigned DiagID, bool(*refactor)(const ObjCMessageExpr *, const NSAPI &, edit::Commit &))

Definition SemaExprObjC.cpp:2449

static ObjCMethodDecl * LookupDirectMethodInMethodList(Sema &S, Selector Sel, ObjCMethodList &MethList, bool &onlyDirect, bool &anyDirect)

Definition SemaExprObjC.cpp:1233

static ObjCBridgeRelatedAttr * ObjCBridgeRelatedAttrFromType(QualType T, TypedefNameDecl *&TDNDecl)

Definition SemaExprObjC.cpp:3858

static T * getObjCBridgeAttr(const TypedefType *TD)

Definition SemaExprObjC.cpp:3843

static ARCConversionTypeClass classifyTypeForARCConversion(QualType type)

Definition SemaExprObjC.cpp:3471

static bool isAnyRetainable(ARCConversionTypeClass ACTC)

Definition SemaExprObjC.cpp:3459

static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg)

Definition SemaExprObjC.cpp:3398

ARCConversionTypeClass

Definition SemaExprObjC.cpp:3442

@ ACTC_voidPtr

void* might be a normal C type, or it might a CF type.

Definition SemaExprObjC.cpp:3453

@ ACTC_retainable

id, void (^)()

Definition SemaExprObjC.cpp:3447

@ ACTC_coreFoundation

struct A*

Definition SemaExprObjC.cpp:3456

@ ACTC_indirectRetainable

id*, id***, void (^*)(),

Definition SemaExprObjC.cpp:3450

@ ACTC_none

int, void, struct A

Definition SemaExprObjC.cpp:3444

static QualType getBaseMessageSendResultType(Sema &S, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)

Determine the result type of a message send based on the receiver type, method, and the kind of messa...

Definition SemaExprObjC.cpp:1458

static const ObjCMethodDecl * findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD, QualType instancetype)

Look for an ObjC method whose result type exactly matches the given type.

Definition SemaExprObjC.cpp:1621

static void DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, ObjCMethodDecl *Method, Selector Sel, Expr **Args, unsigned NumArgs)

Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...

Definition SemaExprObjC.cpp:2542

static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M)

Definition SemaExprObjC.cpp:2784

static bool validateBoxingMethod(Sema &S, SourceLocation Loc, const ObjCInterfaceDecl *Class, Selector Sel, const ObjCMethodDecl *Method)

Emits an error if the given method does not exist, or if the return type is not an Objective-C object...

Definition SemaExprObjC.cpp:151

static void checkFoundationAPI(Sema &S, SourceLocation Loc, const ObjCMethodDecl *Method, ArrayRef< Expr * > Args, QualType ReceiverType, bool IsClassObjectCall)

Definition SemaExprObjC.cpp:2493

static void addFixitForObjCARCConversion(Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK, SourceLocation afterLParen, QualType castType, Expr *castExpr, Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName)

Definition SemaExprObjC.cpp:3748

static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, QualType T, bool ArrayLiteral=false)

Check that the given expression is a valid element of an Objective-C collection literal.

Definition SemaExprObjC.cpp:391

This file declares semantic analysis for Objective-C.

static QualType getPointeeType(const MemRegion *R)

Defines the clang::TypeLoc interface and its subclasses.

__device__ __2f16 float __ockl_bool s

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

SourceManager & getSourceManager()

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

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

bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT, ObjCInterfaceDecl *IDecl)

QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in QT's qualified-id protocol list adopt...

QualType getObjCObjectPointerType(QualType OIT) const

Return a ObjCObjectPointerType type for the given ObjCObjectType.

bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl)

ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's protocol list adopt all protocols in Q...

Represents an array type, per C99 6.7.5.2 - Array Declarators.

ArraySizeModifier getSizeModifier() const

QualType getElementType() const

unsigned getIndexTypeCVRQualifiers() const

One specifier in an @available expression.

StringRef getPlatform() const

VersionTuple getVersion() const

Represents a block literal declaration, which is like an unnamed FunctionDecl.

CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....

Abstract class common to all of the C++ "named"/"keyword" casts.

Represents a C++ nested-name-specifier or a global scope specifier.

FunctionDecl * getDirectCallee()

If the callee is a FunctionDecl, return it. Otherwise return null.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

CastKind getCastKind() const

Expr * getFalseExpr() const

getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...

Expr * getTrueExpr() const

getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...

Represents the canonical version of C arrays with a specified constant size.

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

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

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

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

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

bool isImplicit() const

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

bool isInvalidDecl() const

SourceLocation getLocation() const

bool isDefinedOutsideFunctionOrMethod() const

isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...

DeclContext * getDeclContext()

SourceLocation getBeginLoc() const LLVM_READONLY

TranslationUnitDecl * getTranslationUnitDecl()

The name of a declaration.

IdentifierInfo * getAsIdentifierInfo() const

Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...

bool isIdentifier() const

Predicate functions for querying what type of name this is.

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

ExplicitCastExpr - An explicit cast written in the source code.

This represents one expression.

bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...

Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY

Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...

@ SE_AllowSideEffects

Allow any unmodeled side effect.

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

ExprValueKind getValueKind() const

getValueKind - The value kind that this expression produces.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

Expr * IgnoreParenLValueCasts() LLVM_READONLY

Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...

Expr * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

bool isObjCSelfExpr() const

Check if this expression is the ObjC 'self' implicit parameter.

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

@ NPC_ValueDependentIsNull

Specifies that a value-dependent expression of integral or dependent type should be considered a null...

@ NPC_NeverValueDependent

Specifies that the expression should never be value-dependent.

@ NPC_ValueDependentIsNotNull

Specifies that a value-dependent expression should be considered to never be a null pointer constant.

ExprObjectKind getObjectKind() const

getObjectKind - The object kind that this expression produces.

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const

isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

bool hasPlaceholderType() const

Returns whether this expression has a placeholder type.

static ExprValueKind getValueKindForType(QualType T)

getValueKindForType - Given a formal return or parameter type, give its value kind.

Represents difference between two FPOptions values.

static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)

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

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

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

static FixItHint CreateRemoval(CharSourceRange RemoveRange)

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

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

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

unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const

Returns a value indicating whether this function corresponds to a builtin function.

QualType getReturnType() const

Represents a C11 generic selection.

AssociationTy< false > Association

static GenericSelectionExpr * Create(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > AssocTypes, ArrayRef< Expr * > AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex)

Create a non-result-dependent generic selection expression accepting an expression predicate.

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

bool isStr(const char(&Str)[StrLen]) const

Return true if this is the identifier for the specified string.

StringRef getName() const

Return the actual identifier string.

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)

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

static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)

Create a copy initialization.

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

Describes an entity that is being initialized.

static InitializedEntity InitializeTemporary(QualType Type)

Create the initialization entity for a temporary.

static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)

Create the initialization entity for a parameter.

static bool isAsciiIdentifierContinueChar(char c, const LangOptions &LangOpts)

Returns true if the given character could appear in an identifier.

Represents the results of name lookup.

bool empty() const

Return true if no decls were found.

SourceLocation getNameLoc() const

Gets the location of the identifier.

NamedDecl * getFoundDecl() const

Fetch the unique decl found by this lookup.

bool isSingleResult() const

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

@ NSDict_dictionaryWithObjectsForKeysCount

@ NSArr_arrayWithObjectsCount

This represents a decl that may have a name.

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.

std::string getNameAsString() const

Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...

static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr * > Elements, QualType T, ObjCMethodDecl *Method, SourceRange SR)

A runtime availability query.

ObjCBoolLiteralExpr - Objective-C Boolean Literal.

ObjCBoxedExpr - used for generalized expression boxing.

An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...

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

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

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

ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...

static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, SourceRange SR)

ObjCEncodeExpr, used for @encode in Objective-C.

Represents an ObjC class declaration.

ObjCMethodDecl * lookupClassMethod(Selector Sel) const

Lookup a class method for a given selector.

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

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

ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const

Lookup an instance method for a given selector.

ObjCMethodDecl * lookupPrivateClassMethod(const Selector &Sel)

ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const

ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const

Lookup a method in the classes implementation hierarchy.

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

ObjCInterfaceDecl * getSuperClass() const

bool isSuperClassOf(const ObjCInterfaceDecl *I) const

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

Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...

ObjCInterfaceDecl * getDecl() const

Get the declaration of this interface.

ObjCIvarDecl - Represents an ObjC instance variable.

AccessControl getAccessControl() const

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.

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

static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr * > Args, SourceLocation RBracLoc, bool isImplicit)

Create a message send to super.

Selector getSelector() const

const ObjCMethodDecl * getMethodDecl() const

ObjCMethodDecl - Represents an instance or class method declaration.

ImplicitParamDecl * getSelfDecl() const

ArrayRef< ParmVarDecl * > parameters() const

bool isPropertyAccessor() const

void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const

Return overridden methods for the given Method.

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

const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const

Returns the property associated with this method's selector.

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

Sets the method's parameters and selector source locations.

bool hasRelatedResultType() const

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

SourceLocation getBeginLoc() const LLVM_READONLY

bool isDirectMethod() const

True if the method is tagged as objc_direct.

Selector getSelector() const

bool isInstanceMethod() const

ObjCMethodFamily getMethodFamily() const

Determines the family of this method.

QualType getReturnType() const

bool isClassMethod() const

ObjCInterfaceDecl * getClassInterface()

Represents a pointer to an Objective C object.

bool isObjCQualifiedIdType() const

True if this is equivalent to 'id.

bool isObjCIdType() const

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

QualType getPointeeType() const

Gets the type pointed to by this ObjC pointer.

ObjCInterfaceDecl * getInterfaceDecl() const

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

const ObjCInterfaceType * getInterfaceType() const

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

Represents one property declaration in an Objective-C interface.

ObjCMethodDecl * getGetterMethodDecl() const

ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.

ObjCPropertyDecl * getExplicitProperty() const

ObjCMethodDecl * getImplicitPropertyGetter() const

bool isExplicitProperty() const

Represents an Objective-C protocol declaration.

bool hasDefinition() const

Determine whether this protocol has a definition.

ObjCProtocolDecl * getDefinition()

Retrieve the definition of this protocol, if any.

bool isNonRuntimeProtocol() const

This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.

ObjCProtocolExpr used for protocol expression in Objective-C.

ObjCSelectorExpr used for @selector in Objective-C.

ObjCStringLiteral, used for Objective-C string literals i.e.

ObjCSubscriptRefExpr - used for array and dictionary subscripting.

OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.

ParenExpr - This represents a parenthesized expression, e.g.

Sugar for parentheses used when specifying types.

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)

PointerType - C99 6.7.5.1 - Pointer Declarators.

QualType getPointeeType() const

Expr * getResultExpr()

Return the result-bearing expression, or null if there is none.

A (possibly-)qualified type.

QualType getDesugaredType(const ASTContext &Context) const

Return the specified type with any "sugar" removed from the type.

QualType withConst() const

bool isNull() const

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

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this 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.

QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const

Substitute type arguments for the Objective-C type parameters used in the subject type.

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

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

Base for LValueReferenceType and RValueReferenceType.

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

bool isInObjcMethodScope() const

isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body.

static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)

Return the default setter selector for the given identifier.

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

std::string getAsString() const

Derive the full selector name (e.g.

ObjCMethodFamily getMethodFamily() const

Derive the conventional family of this method.

bool isUnarySelector() const

ObjCStringFormatFamily getStringFormatFamily() const

unsigned getNumArgs() const

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

ASTContext & getASTContext() const

const LangOptions & getLangOpts() const

DiagnosticsEngine & getDiagnostics() const

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Emit a diagnostic.

ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)

Definition SemaExprObjC.cpp:2284

ObjCMethodDecl * ValueWithBytesObjCTypeMethod

The declaration of the valueWithBytes:objCType: method.

ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)

Definition SemaExprObjC.cpp:954

ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super)

HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an objective C interface.

Definition SemaExprObjC.cpp:1975

ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)

Build an Objective-C instance message expression.

Definition SemaExprObjC.cpp:2831

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

ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)

ParseObjCSelectorExpression - Build selector expression for @selector.

Definition SemaExprObjC.cpp:1295

ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)

Build an Objective-C class message expression.

Definition SemaExprObjC.cpp:2606

ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)

BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.

Definition SemaExprObjC.cpp:320

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

ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)

LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.

ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr)

Definition SemaExprObjC.cpp:4756

ObjCLiteralKind CheckLiteralKind(Expr *FromE)

Definition SemaExprObjC.cpp:5206

ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)

Definition SemaExprObjC.cpp:1129

bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose=true)

Definition SemaExprObjC.cpp:4292

ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)

Definition SemaExprObjC.cpp:794

ObjCInterfaceDecl * NSArrayDecl

The declaration of the Objective-C NSArray class.

ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)

Definition SemaExprObjC.cpp:2158

void CheckObjCCircularContainer(ObjCMessageExpr *Message)

Check whether receiver is mutable ObjC container which attempts to add itself into the container.

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

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

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

LookupMethodInType - Look up a method in an ObjCObjectType.

Definition SemaExprObjC.cpp:1938

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

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

ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)

Definition SemaExprObjC.cpp:2430

ObjCInterfaceDecl * NSNumberDecl

The declaration of the Objective-C NSNumber class.

void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)

Definition SemaExprObjC.cpp:4182

ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)

BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.

Definition SemaExprObjC.cpp:507

ObjCInterfaceDecl * NSValueDecl

The declaration of the Objective-C NSValue class.

Selector RespondsToSelectorSel

will hold 'respondsToSelector:'

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

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

bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, MultiExprArg Args, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType, ExprValueKind &VK)

CheckMessageArgumentTypes - Check types in an Obj-C message send.

Definition SemaExprObjC.cpp:1711

ObjCInterfaceDecl * NSStringDecl

The declaration of the Objective-C NSString class.

llvm::MapVector< Selector, SourceLocation > ReferencedSelectors

Method selectors used in a @selector expression.

ObjCMethodDecl * LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)

LookupFactoryMethodInGlobalPool - Returns the method and warns if there are multiple signatures.

ObjCMethodDecl * StringWithUTF8StringMethod

The declaration of the stringWithUTF8String: method.

bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall)

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

QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)

FindCompositeObjCPointerType - Helper method to find composite type of two objective-c pointer types ...

Definition SemaExprObjC.cpp:4924

ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)

Definition SemaExprObjC.cpp:83

ObjCInterfaceDecl * NSDictionaryDecl

The declaration of the Objective-C NSDictionary class.

ObjCMethodDecl * ArrayWithObjectsMethod

The declaration of the arrayWithObjects:count: method.

ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)

Definition SemaExprObjC.cpp:1160

QualType QIDNSCopying

id type.

bool CheckObjCString(Expr *Arg)

CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...

ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)

Definition SemaExprObjC.cpp:2754

void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)

Definition SemaExprObjC.cpp:4134

bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, bool Diagnose=true)

Definition SemaExprObjC.cpp:5074

ObjCMethodDecl * tryCaptureObjCSelf(SourceLocation Loc)

Try to capture an implicit reference to 'self'.

Definition SemaExprObjC.cpp:1421

ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)

Definition SemaExprObjC.cpp:37

ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)

Definition SemaExprObjC.cpp:371

ObjCMethodDecl * DictionaryWithObjectsMethod

The declaration of the dictionaryWithObjects:forKeys:count: method.

QualType NSStringPointer

Pointer to NSString type (NSString *).

ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *SubExpr)

Definition SemaExprObjC.cpp:4644

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

Find the protocol with the given name, if any.

QualType NSNumberPointer

Pointer to NSNumber type (NSNumber *).

DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo *II)

The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.

Definition SemaExprObjC.cpp:4773

ObjCMethodDecl * NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]

The Objective-C NSNumber methods used to create NSNumber literals.

GlobalMethodPool MethodPool

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

QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)

Determine the result of a message send expression based on the type of the receiver,...

Definition SemaExprObjC.cpp:1520

ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)

ParseObjCProtocolExpression - Build protocol expression for @protocol.

Definition SemaExprObjC.cpp:1391

ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)

Definition SemaExprObjC.cpp:2775

void checkRetainCycles(ObjCMessageExpr *msg)

checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.

ObjCMessageKind

Describes the kind of message expression indicated by a message send that starts with an identifier.

@ ObjCClassMessage

The message is a class message, and the identifier is a type name.

@ ObjCInstanceMessage

The message is an instance message.

@ ObjCSuperMessage

The message is sent to 'super'.

ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, IdentifierInfo *II, bool AllowBuiltinCreation=false)

The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.

Definition SemaExprObjC.cpp:4846

QualType NSValuePointer

Pointer to NSValue type (NSValue *).

void EmitRelatedResultTypeNote(const Expr *E)

If the given expression involves a message send to a method with a related result type,...

Definition SemaExprObjC.cpp:1684

ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)

Definition SemaExprObjC.cpp:3412

bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)

ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV)

Definition SemaExprObjC.cpp:4864

ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)

Definition SemaExprObjC.cpp:2380

CastKind PrepareCastToObjCObjectPointer(ExprResult &E)

Prepare a conversion of the given expression to an ObjC object pointer type.

Definition SemaExprObjC.cpp:5193

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

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

bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, QualType SrcType, ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod, ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs, bool Diagnose=true)

Definition SemaExprObjC.cpp:4220

void EmitRelatedResultTypeNoteForReturn(QualType destType)

Given that we had incompatible pointer types in a return statement, check whether we're in a method w...

Definition SemaExprObjC.cpp:1654

void diagnoseARCUnbridgedCast(Expr *e)

Given that we saw an expression with the ARCUnbridgedCastTy placeholder type, complain bitterly.

Definition SemaExprObjC.cpp:4515

ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)

LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...

Definition SemaExprObjC.cpp:1962

ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD, bool IsReinterpretCast=false)

Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...

Definition SemaExprObjC.cpp:4388

bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)

Definition SemaExprObjC.cpp:4203

bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)

Definition SemaExprObjC.cpp:4589

bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)

Expr * stripARCUnbridgedCast(Expr *e)

stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast type, remove the placeholder cast.

Definition SemaExprObjC.cpp:4548

ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)

Build an ObjC subscript pseudo-object expression, given that that's supported by the runtime.

Definition SemaExprObjC.cpp:764

bool isSelfExpr(Expr *RExpr)

Private Helper predicate to check for 'self'.

Definition SemaExprObjC.cpp:1920

ExprResult ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef< AvailabilitySpec > AvailSpecs, SourceLocation AtLoc, SourceLocation RParen)

Definition SemaExprObjC.cpp:5151

bool isKnownName(StringRef name)

Definition SemaExprObjC.cpp:3738

std::unique_ptr< NSAPI > NSAPIObj

Caches identifiers/selectors for NSFoundation APIs.

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

@ LookupOrdinaryName

Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....

bool FormatStringHasSArg(const StringLiteral *FExpr)

NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)

Look up a name, looking for a single declaration.

ASTContext & getASTContext() const

ObjCMethodDecl * getCurMethodDecl()

getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

Calls Lexer::getLocForEndOfToken()

const LangOptions & getLangOpts() const

const LangOptions & LangOpts

ExprResult DefaultLvalueConversion(Expr *E)

static bool isCast(CheckedConversionKind CCK)

ExprResult CheckPlaceholderExpr(Expr *E)

Check for operands with placeholder types and complain if found.

SourceManager & getSourceManager() const

bool makeUnavailableInSystemHeader(SourceLocation loc, UnavailableAttr::ImplicitReason reason)

makeUnavailableInSystemHeader - There is an error in the current context.

Scope * TUScope

Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...

SourceManager & SourceMgr

DiagnosticsEngine & Diags

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

bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)

Perform unqualified name lookup starting from a given scope.

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.

bool isInSystemHeader(SourceLocation Loc) const

Returns if a SourceLocation is in a system header.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

CompoundStmt * getSubStmt()

StmtVisitor - This class implements a simple visitor for Stmt subclasses.

SourceLocation getEndLoc() const LLVM_READONLY

StmtClass getStmtClass() const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

StringLiteral - This represents a string literal expression, e.g.

SourceLocation getBeginLoc() const LLVM_READONLY

tokloc_iterator tokloc_begin() const

tokloc_iterator tokloc_end() const

static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)

This is the "fully general" constructor that allows representation of strings formed from one or more...

StringRef getString() const

The top declaration context.

Represents a declaration of a type.

SourceLocation getBeginLoc() const LLVM_READONLY

SourceRange getSourceRange() const LLVM_READONLY

Get the full source range.

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

The base class of the type hierarchy.

bool isBlockPointerType() const

const ObjCObjectPointerType * getAsObjCQualifiedClassType() const

const ObjCObjectPointerType * getAsObjCQualifiedIdType() const

bool isObjCBuiltinType() const

bool isVoidPointerType() const

bool isObjCARCBridgableType() const

Determine whether the given type T is a "bridgable" Objective-C type, which is either an Objective-C ...

bool isPointerType() const

bool isIntegerType() const

isIntegerType() does not include complex integers (a GCC extension).

const T * castAs() const

Member-template castAs.

const ObjCObjectPointerType * getAsObjCInterfacePointerType() const

bool isIntegralType(const ASTContext &Ctx) const

Determine whether this type is an integral type.

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool canHaveNullability(bool ResultIfUnknown=true) const

Determine whether the given type can have a nullability specifier applied to it, i....

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

bool isCARCBridgableType() const

Determine whether the given type T is a "bridgeable" C type.

bool isObjCIdType() const

bool isObjCClassOrClassKindOfType() const

Whether the type is Objective-C 'Class' or a __kindof type of an Class type, e.g.,...

const ArrayType * getAsArrayTypeUnsafe() const

A variant of getAs<> for array types which silently discards qualifiers from the outermost type.

bool isObjCObjectPointerType() const

bool isObjCQualifiedClassType() const

bool isObjCClassType() const

std::optional< ArrayRef< QualType > > getObjCSubstitutions(const DeclContext *dc) const

Retrieve the set of substitutions required when accessing a member of the Objective-C receiver type t...

const T * getAsCanonical() const

If this type is canonically the specified type, return its canonical type cast to that specified type...

const ObjCObjectType * getAsObjCInterfaceType() const

bool isAnyPointerType() const

bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, const ObjCObjectType *&bound) const

Whether the type is Objective-C 'id' or a __kindof type of an object type, e.g., __kindof NSView * or...

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

bool isObjCRetainableType() const

std::optional< NullabilityKind > getNullability() const

Determine the nullability of the given type.

Represents the declaration of a typedef-name via the 'typedef' type specifier.

Base class for declarations which introduce a typedef-name.

QualType getUnderlyingType() const

TypedefNameDecl * getDecl() const

Simple class containing the result of Sema::CorrectTypo.

DeclClass * getCorrectionDeclAs() const

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

Expr * getSubExpr() const

static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)

Represents a C++ unqualified-id that has been parsed.

void setImplicitSelfParam(const IdentifierInfo *Id)

Specify that this unqualified-id is an implicit 'self' parameter.

void setType(QualType newType)

bool isCommitable() const

edit_iterator edit_begin() const

SmallVectorImpl< Edit >::const_iterator edit_iterator

edit_iterator edit_end() const

Retains information about a function, method, or block that is currently being parsed.

bool ObjCIsDesignatedInit

True when this is a method marked as a designated initializer.

bool ObjCWarnForNoInitDelegation

This starts true for a secondary initializer method and will be set to false if there is an invocatio...

bool ObjCIsSecondaryInit

True when this is an initializer method not marked as a designated initializer within a class that ha...

bool ObjCWarnForNoDesignatedInitChain

This starts true for a method marked as designated initializer and will be set to false if there is a...

Defines the clang::TargetInfo interface.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr

Matches any cast nodes of Clang's AST.

constexpr Variable var(Literal L)

Returns the variable of L.

bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)

bool followsCreateRule(const FunctionDecl *FD)

TokenKind

Provides a simple uniform namespace for tokens from all C languages.

RangeSelector merge(RangeSelector First, RangeSelector Second)

Selects the merge of the two ranges, i.e.

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

bool isa(CodeGen::Address addr)

@ Ambiguous

Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...

@ NotFound

No entity found met the criteria.

@ FoundOverloaded

Name lookup found a set of overloaded functions that met the criteria.

@ Found

Name lookup found a single declaration that met the criteria.

@ FoundUnresolvedValue

Name lookup found an unresolvable value declaration and cannot yet complete.

@ NotFoundInCurrentInstantiation

No entity found met the criteria within the current instantiation,, but there were dependent base cla...

NullabilityKind

Describes the nullability of a particular type.

@ Nullable

Values of this type can be null.

@ NonNull

Values of this type can never be null.

@ OK_ObjCProperty

An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...

@ OK_ObjCSubscript

An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...

@ Seq

'seq' clause, allowed on 'loop' and 'routine' directives.

ActionResult< Decl * > DeclResult

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

ObjCMethodFamily

A family of Objective-C methods.

@ OMF_None

No particular method family.

MutableArrayRef< Expr * > MultiExprArg

@ Parameter

The parameter type of a method or function.

@ Result

The result type of a method or function.

const FunctionProtoType * T

ObjCBridgeCastKind

The kind of bridging performed by the Objective-C bridge cast.

@ OBC_Bridge

Bridging via __bridge, which does nothing but reinterpret the bits.

@ OBC_BridgeTransfer

Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.

@ OBC_BridgeRetained

Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.

CastKind

CastKind - The kind of operation required for a conversion.

ExprValueKind

The categorization of expression values, currently following the C++11 scheme.

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

@ None

The alignment was not explicit in code.

OpaquePtr< QualType > ParsedType

An opaque type for threading parsed type information through the parser.

@ None

No keyword precedes the qualified type name.

@ Class

The "class" keyword introduces the elaborated-type-specifier.

ActionResult< Expr * > ExprResult

CheckedConversionKind

The kind of conversion being performed.

@ Implicit

An implicit conversion.

@ CStyleCast

A C-style cast.

@ ForBuiltinOverloadedOp

A conversion for an operand of a builtin overloaded operator.

@ OtherCast

A cast other than a C-style cast.

@ FunctionalCast

A functional-style cast.

DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...

EvalResult is a struct with detailed info about an evaluated expression.

An element in an Objective-C dictionary literal.

a linked list of methods with the same selector name but different signatures.

ObjCMethodDecl * getMethod() const

ObjCMethodList * getNext() const

CharSourceRange getFileRange(SourceManager &SM) const

CharSourceRange getInsertFromRange(SourceManager &SM) const