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

44 StringLiteral *S = cast(Strings[0]);

45

46

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

48

51

52 for (Expr *E : Strings) {

53 S = cast(E);

54

55

56 if (!S->isOrdinary()) {

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

58 << S->getSourceRange();

59 return true;

60 }

61

62

63 StrBuf += S->getString();

64

65

66 StrLocs.append(S->tokloc_begin(), S->tokloc_end());

67 }

68

69

70

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

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

77 false, StrTy, &StrLocs[0],

78 StrLocs.size());

79 }

80

82}

83

87

89 return true;

90

91

92

93

94

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

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

101

102 if (StringClass.empty())

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

104 else

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

106

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

113 } else {

114

115

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

117 << NSIdent << S->getSourceRange();

119 }

120 } else {

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

128 } else {

129

130

131

132

142 }

144 }

145 }

146

148}

149

150

151

155 if (!Method) {

156

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

158 return false;

159 }

160

161

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

165 << Sel;

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

167 << ReturnType;

168 return false;

169 }

170

171 return true;

172}

173

174

177 switch (LiteralKind) {

188

189

190

193 break;

194 }

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

196}

197

198

199

200

201static bool

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

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

210 return false;

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

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

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

215 return false;

216 }

217

218 return true;

219}

220

221

222

223

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

237 }

238

240 ID = nullptr;

241 }

242

243 return ID;

244}

245

246

247

250 bool isLiteral = false,

252 std::optionalNSAPI::NSNumberLiteralMethodKind Kind =

253 S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);

254

255 if (!Kind) {

256 if (isLiteral) {

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

258 << NumberType << R;

259 }

260 return nullptr;

261 }

262

263

264 if (S.NSNumberLiteralMethods[*Kind])

265 return S.NSNumberLiteralMethods[*Kind];

266

267 Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,

268 false);

269

271

272

273

274 if (!S.NSNumberDecl) {

275 S.NSNumberDecl =

277 if (!S.NSNumberDecl) {

278 return nullptr;

279 }

280 }

281

282 if (S.NSNumberPointer.isNull()) {

283

286 }

287

288

289 ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);

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

291

295 ReturnTInfo, S.NSNumberDecl,

296 false, false,

297 false,

298 false,

299 true,

301 false);

305 NumberType, nullptr, SC_None, nullptr);

307 }

308

310 return nullptr;

311

312

313

314

315 S.NSNumberLiteralMethods[*Kind] = Method;

316 return Method;

317}

318

319

320

322 Expr *Number) {

324

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

327

328

329 switch (Char->getKind()) {

332 NumberType = Context.CharTy;

333 break;

334

337 break;

338

340 NumberType = Context.Char16Ty;

341 break;

342

344 NumberType = Context.Char32Ty;

345 break;

346 }

347 }

348

349

350

353 true, NR);

354 if (!Method)

356

357

360 ParamDecl);

365 Number = ConvertedNumber.get();

366

367

370}

371

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

379 } else {

380

381

384 CK_IntegralToBoolean);

385 }

386

388}

389

390

391

394 bool ArrayLiteral = false) {

395

396 if (Element->isTypeDependent())

397 return Element;

398

400 if (Result.isInvalid())

402 Element = Result.get();

403

404

405

406 if (S.getLangOpts().CPlusPlus && Element->getType()->isRecordType()) {

409 false);

413 if (Seq.Failed())

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

415 }

416

417 Expr *OrigElement = Element;

418

419

421 if (Result.isInvalid())

423 Element = Result.get();

424

425

426 if (!Element->getType()->isObjCObjectPointerType() &&

427 !Element->getType()->isBlockPointerType()) {

428 bool Recovered = false;

429

430

431 if (isa(OrigElement) ||

432 isa(OrigElement) ||

433 isa(OrigElement) ||

434 isa(OrigElement) ||

435 isa(OrigElement)) {

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

437 OrigElement->getType())) {

438 int Which = isa(OrigElement) ? 1

439 : (isa(OrigElement) ||

440 isa(OrigElement)) ? 2

441 : 3;

442

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

446

448 OrigElement);

449 if (Result.isInvalid())

451

452 Element = Result.get();

453 Recovered = true;

454 }

455 }

456

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

458 if (String->isOrdinary()) {

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

462

465 if (Result.isInvalid())

467

468 Element = Result.get();

469 Recovered = true;

470 }

471 }

472

473 if (!Recovered) {

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

475 << Element->getType();

477 }

478 }

479 if (ArrayLiteral)

481 dyn_cast(OrigElement)) {

483 unsigned numConcat = SL->getNumConcatenated();

484 if (numConcat > 1) {

485

486 bool hasMacro = false;

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

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

489 hasMacro = true;

490 break;

491 }

492 if (!hasMacro)

493 S.Diag(Element->getBeginLoc(),

494 diag::warn_concatenated_nsarray_literal)

495 << Element->getType();

496 }

497 }

498 }

499

500

501

504 false),

505 Element->getBeginLoc(), Element);

506}

507

513 return BoxedExpr;

514 }

517

521 }

523 ValueExpr = RValue.get();

528

534 }

537 }

538

539

540

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

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

543 if (auto *SL =

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

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

546 "unexpected character encoding");

547 StringRef Str = SL->getString();

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

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

550

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

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

555 }

556

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

559 }

560

564

565

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

568

573 false, false,

574 false,

575 false,

576 true,

578 false);

585 nullptr,

588 BoxingMethod = M;

589 }

590

592 stringWithUTF8String, BoxingMethod))

594

596 }

597

600

601 std::optional Nullability =

603 if (Nullability)

604 BoxedType =

606 }

608

609

610

611

612

613

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

616

617

618 switch (Char->getKind()) {

621 ValueType = Context.CharTy;

622 break;

623

626 break;

627

629 ValueType = Context.Char16Ty;

630 break;

631

633 ValueType = Context.Char32Ty;

634 break;

635 }

636 }

637

638

639

643 if (!ET->getDecl()->isComplete()) {

644 Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)

647 }

648

650 ET->getDecl()->getIntegerType());

653

654

655

656

657

662 }

663

664

667 }

668

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

673

674

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

677

682 false,

683 false,

684 false,

685 false,

686 true,

688 false);

689

691

697 nullptr,

699 Params.push_back(bytes);

700

707 nullptr,

709 Params.push_back(type);

710

712 BoxingMethod = M;

713 }

714

716 ValueWithBytesObjCType, BoxingMethod))

718

720 }

721

723 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)

726 }

727

730 }

731

732 if (!BoxingMethod) {

733 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)

736 }

737

739

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

745 } else {

746

749 ParamDecl);

750 ConvertedValueExpr =

752 }

753

754 if (ConvertedValueExpr.isInvalid())

756 ValueExpr = ConvertedValueExpr.get();

757

759 new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,

760 BoxingMethod, SR);

762}

763

764

765

769 assert(getLangOpts().isSubscriptPointerArithmetic());

771

772

773

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

776

777

778

780 if (Result.isInvalid())

782 IndexExpr = Result.get();

783

784

786 if (Result.isInvalid())

788 BaseExpr = Result.get();

789

790

793 getterMethod, setterMethod, RB);

794}

795

800

806 }

807 }

808

809

815 if (!Method && getLangOpts().DebuggerObjCLiteral) {

820 false ,

821 false, false,

822 true, false,

830 nullptr,

832 Params.push_back(objects);

838 nullptr, SC_None,

839 nullptr);

840 Params.push_back(cnt);

842 }

843

846

847

850 if (!PtrT ||

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

853 << Sel;

855 diag::note_objc_literal_method_param)

856 << 0 << T

859 }

860

861

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

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

864 << Sel;

866 diag::note_objc_literal_method_param)

867 << 1

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

869 << "integral";

871 }

872

873

875 }

876

879

880

881

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

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

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

888

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

890 }

891

895

898}

899

900

901

902static void

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

906 return;

907

908

909

910

911 struct APSIntCompare {

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

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

914 }

915 };

916

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

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

919

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

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

922 if (!Pair.second) {

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

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

925 }

926 };

927

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

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

930

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

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

934 checkOneKey(StringKeys, Bytes, Loc);

935 }

936

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

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

940

941

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

944 continue;

945 }

946

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

951 }

952 }

953 }

954}

955

960

966 }

967 }

968

969

970

976 if (!Method && getLangOpts().DebuggerObjCLiteral) {

980 false , false ,

981 false,

982 false,

983 true, false,

991 nullptr, SC_None,

992 nullptr);

993 Params.push_back(objects);

999 nullptr, SC_None,

1000 nullptr);

1001 Params.push_back(keys);

1007 nullptr, SC_None,

1008 nullptr);

1009 Params.push_back(cnt);

1011 }

1012

1014 Method))

1016

1017

1020 if (!PtrValue ||

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

1023 << Sel;

1025 diag::note_objc_literal_method_param)

1026 << 0 << ValueT

1029 }

1030

1031

1034 if (!PtrKey ||

1036 IdT)) {

1037 bool err = true;

1038 if (PtrKey) {

1040

1048 }

1049 }

1053 }

1054

1055 if (err) {

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

1057 << Sel;

1059 diag::note_objc_literal_method_param)

1060 << 1 << KeyT

1063 }

1064 }

1065

1066

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

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

1070 << Sel;

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

1072 diag::note_objc_literal_method_param)

1073 << 2 << CountType

1074 << "integral";

1076 }

1077

1078

1080 }

1081

1082 QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();

1084 QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();

1086

1087

1088

1089 bool HasPackExpansions = false;

1091

1096

1097

1100 if (Value.isInvalid())

1102

1103 Element.Key = Key.get();

1104 Element.Value = Value.get();

1105

1106 if (Element.EllipsisLoc.isInvalid())

1107 continue;

1108

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

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

1111 Diag(Element.EllipsisLoc,

1112 diag::err_pack_expansion_without_parameter_packs)

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

1114 Element.Value->getEndLoc());

1116 }

1117

1118 HasPackExpansions = true;

1119 }

1120

1123

1126 DictionaryWithObjectsMethod, SR);

1128 return SemaRef.MaybeBindToTemporary(Literal);

1129}

1130

1139 else {

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

1141 !EncodedType->isVoidType())

1143 diag::err_incomplete_type_objc_at_encode,

1146

1147 std::string Str;

1150 if (!NotEncodedT.isNull())

1151 Diag(AtLoc, diag::warn_incomplete_encoded_type)

1152 << EncodedType << NotEncodedT;

1153

1154

1155

1157 }

1158

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

1160}

1161

1168

1171 if (!TInfo)

1174

1176}

1177

1185 bool Warned = false;

1188 if (MatchingMethodDecl == Method ||

1189 isa(MatchingMethodDecl->getDeclContext()) ||

1191 continue;

1194 if (!Warned) {

1195 Warned = true;

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

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

1201 }

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

1204 }

1205 }

1206 return Warned;

1207}

1208

1213 bool WarnMultipleSelectors) {

1214 if (!WarnMultipleSelectors ||

1216 return;

1217 bool Warned = false;

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

1220 b != e; b++) {

1221

1224 Method, InstMethList))

1225 Warned = true;

1226

1227

1230 Method, ClsMethList) || Warned)

1231 return;

1232 }

1233}

1234

1237 bool &onlyDirect,

1238 bool &anyDirect) {

1239 (void)Sel;

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

1244 if (!Method)

1245 continue;

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

1248 anyDirect = true;

1249 DirectMethod = Method;

1250 } else

1251 onlyDirect = false;

1252 }

1253

1254 return DirectMethod;

1255}

1256

1257

1258

1259

1260

1262 bool &onlyDirect,

1263 bool &anyDirect) {

1266 return nullptr;

1267

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

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

1272

1273 return DirectInstance ? DirectInstance : DirectClass;

1274}

1275

1278 if (!CurMD)

1279 return nullptr;

1281

1282

1283

1284

1286 return MD;

1288 return MD;

1290 return MD;

1292 return MD;

1293

1294 return nullptr;

1295}

1296

1302 bool WarnMultipleSelectors) {

1306 if (!Method)

1309 if (!Method) {

1311 Selector MatchedSel = OM->getSelector();

1314 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)

1315 << Sel << MatchedSel

1317

1318 } else

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

1320 } else {

1322 WarnMultipleSelectors);

1323

1324 bool onlyDirect = true;

1325 bool anyDirect = false;

1328

1329 if (onlyDirect) {

1330 Diag(AtLoc, diag::err_direct_selector_expression)

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

1334 } else if (anyDirect) {

1335

1336

1337

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

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

1343 diag::note_direct_method_declared_at)

1345 } else if (!LikelyTargetMethod) {

1346

1347

1348 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)

1349 << Sel;

1351 diag::note_direct_method_declared_at)

1353 }

1354 }

1355 }

1356

1357 if (Method &&

1362

1363

1364

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

1373 Sel << SourceRange(LParenLoc, RParenLoc);

1374 break;

1375

1386 break;

1387 }

1388 }

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

1391}

1392

1401 if (!PDecl) {

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

1403 return true;

1404 }

1406 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)

1407 << PDecl;

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

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

1411 } else {

1413 }

1414

1417 return true;

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

1420}

1421

1422

1425

1426

1427

1428

1429 ObjCMethodDecl *method = dyn_cast(DC);

1430 if (!method)

1431 return nullptr;

1432

1434

1435 return method;

1436}

1437

1444 }

1445

1446 return origType;

1447 }

1448

1451

1452 return origType;

1453}

1454

1455

1456

1457

1458

1459

1463 bool isClassMessage,

1464 bool isSuperMessage) {

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

1468

1470

1471

1472

1474

1475 if (auto nullability =

1477

1479

1480

1482 }

1483

1484 return type;

1485 };

1486

1487

1488

1489

1490

1494

1495

1496

1497 if (isSuperMessage) {

1500 return transferNullability(

1503 }

1504 }

1505

1506

1509

1510

1515

1516

1517

1518

1519 return transferNullability(ReceiverType);

1520}

1521

1525 bool isClassMessage,

1526 bool isSuperMessage) {

1528

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

1531

1532

1533 if (isClassMessage) {

1534

1535

1536

1537

1538

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

1545 cast(

1547 ->getDeclContext());

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

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

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

1553 NewResultType);

1554 return NewResultType;

1555 }

1556 }

1557 return resultType;

1558 }

1559

1560

1561

1563 return resultType;

1564

1565

1566 unsigned receiverNullabilityIdx = 0;

1567 if (std::optional nullability =

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

1572 }

1573

1574 unsigned resultNullabilityIdx = 0;

1575 if (std::optional nullability =

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

1580 }

1581

1582

1583

1584 static const uint8_t None = 0;

1585 static const uint8_t NonNull = 1;

1586 static const uint8_t Nullable = 2;

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

1589

1594 };

1595

1596 unsigned newResultNullabilityIdx

1597 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];

1598 if (newResultNullabilityIdx == resultNullabilityIdx)

1599 return resultType;

1600

1601

1602

1603 do {

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

1605 resultType = attributed->getModifiedType();

1606 } else {

1608 }

1610

1611

1612 if (newResultNullabilityIdx > 0) {

1613 auto newNullability

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

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

1616 }

1617

1618 return resultType;

1619}

1620

1621

1626 return MD;

1627

1628

1629

1634 dyn_cast(impl)) {

1635 iface = catImpl->getCategoryDecl();

1636 } else {

1637 iface = impl->getClassInterface();

1638 }

1639

1643 }

1644

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

1650 return result;

1651 }

1652

1653 return nullptr;

1654}

1655

1658

1659

1663 return;

1664

1665

1666

1669 SourceRange range = overridden->getReturnTypeSourceRange();

1672 loc = overridden->getLocation();

1673 Diag(loc, diag::note_related_result_type_explicit)

1674 << 1 << range;

1675 return;

1676 }

1677

1678

1679

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

1682 << 1

1683 << family;

1684}

1685

1689 const ObjCMessageExpr *MsgSend = dyn_cast(E);

1690 if (!MsgSend)

1691 return;

1692

1694 if (!Method)

1695 return;

1696

1698 return;

1699

1702 return;

1703

1706 return;

1707

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

1711}

1712

1716 bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,

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

1722 SelLoc = SelectorLocs.front();

1723 else

1724 SelLoc = lbrac;

1725

1726 if (!Method) {

1727

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

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

1730 continue;

1731

1734 QualType paramTy;

1736 } else {

1738 }

1740 return true;

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

1742 }

1743

1744 unsigned DiagID;

1746 DiagID = diag::err_arc_method_not_found;

1747 else

1748 DiagID = isClassMessage ? diag::warn_class_method_not_found

1749 : diag::warn_inst_method_not_found;

1754 DiagID = diag::err_method_not_found_with_typo;

1755 else

1756 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo

1757 : diag::warn_instance_method_not_found_with_typo;

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

1761 Diag(SelLoc, DiagID)

1762 << Sel<< isClassMessage << MatchedSel

1764 else

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

1766 }

1767 else

1768 Diag(SelLoc, DiagID)

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

1770 SelectorLocs.back());

1771

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

1776 if (ThisClass->lookupClassMethod(Sel))

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

1779 ThisClass->getNameAsString());

1780 }

1781 }

1782 }

1783

1784

1785

1788 } else {

1790 }

1792 return false;

1793 }

1794

1796 isClassMessage, isSuperMessage);

1798

1799 unsigned NumNamedArgs = Sel.getNumArgs();

1800

1801

1803 NumNamedArgs = Method->param_size();

1804

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

1806 Diag(SelLoc, diag::err_typecheck_call_too_few_args)

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

1808 << 0;

1809 return false;

1810 }

1811

1812

1813

1814 std::optional<ArrayRef> typeArgs =

1816 bool IsError = false;

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

1818

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

1820 continue;

1821

1822 Expr *argExpr = Args[i];

1823

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

1826

1827 if (param->hasAttr() &&

1829 if (auto *BE = dyn_cast(

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

1832

1833

1834

1836 !param->hasAttr())

1838

1839

1840

1845 IsError = true;

1846 } else {

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

1848

1849

1850 param->setType(paramType);

1851 }

1852 continue;

1853 }

1854

1857 if (typeArgs)

1859 Context,

1860 *typeArgs,

1862

1865 diag::err_call_incomplete_argument, argExpr))

1866 return true;

1867

1873 IsError = true;

1874 else {

1876

1877

1878

1879

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

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

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

1886 }

1887 }

1888 }

1889

1890

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

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

1894 continue;

1895

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

1900 }

1901 } else {

1902

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

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

1905 diag::err_typecheck_call_too_many_args)

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

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

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

1910 }

1911 }

1912

1914

1915

1916 IsError |=

1918

1919 return IsError;

1920}

1921

1923

1924 ObjCMethodDecl *Method = dyn_cast_or_null(

1927}

1928

1930 if (!method) return false;

1931

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

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

1935 return true;

1936 return false;

1937}

1938

1939

1941 bool isInstance) {

1944

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

1946 return method;

1947

1948

1949

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

1951 return method;

1952 }

1953

1954

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

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

1957 return method;

1958

1959 return nullptr;

1960}

1961

1962

1963

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

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

1969 return MD;

1970 }

1971 }

1972 return nullptr;

1973}

1974

1975

1976

1984

1986 Diag(MemberLoc, diag::err_invalid_property_name)

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

1989 }

1990

1992

1996 diag::err_property_not_found_forward_class,

1997 MemberName, BaseRange))

1999

2002

2005 if (Super)

2006 return new (Context)

2009 else

2010 return new (Context)

2013 }

2014

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

2018

2021

2022 if (Super)

2025 SuperLoc, SuperType);

2026 else

2027 return new (Context)

2030 }

2031

2032

2033

2034

2035

2036

2039

2040

2041 if (!Getter)

2043

2044

2045 if (!Getter)

2047

2048 if (Getter) {

2049

2052 }

2053

2054

2058

2059

2060 if (!Setter)

2062

2063 if (!Setter) {

2064

2065

2067 }

2068

2071

2072

2073

2074

2079

2080

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

2083 Diag(MemberLoc,

2084 diag::warn_property_access_suggest)

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

2087 }

2088 }

2089

2090 if (Getter || Setter) {

2091 if (Super)

2092 return new (Context)

2095 else

2096 return new (Context)

2099

2100 }

2101

2102

2110

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

2113 if (ChosenDecl && isa(ChosenDecl))

2114 if (cast(ChosenDecl)->isClassProperty()) {

2115

2116

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

2122 }

2123 } else {

2125 PDiag(diag::err_property_not_found_suggest)

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

2128 TypoResult, MemberLoc,

2129 SuperLoc, SuperType, Super);

2130 }

2131 }

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 }

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 {

2215 &propertyName);

2216 }

2217

2218

2220

2221

2222 if (!Getter)

2224

2225 if (Getter) {

2226

2227

2230 }

2231

2232

2234 if (!Setter) {

2235

2236

2238 }

2239

2240 if (!Setter)

2242

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)

2259}

2260

2261namespace {

2262

2264 public:

2266

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

2293 if (IsSuper && S->isInObjcMethodScope())

2295

2298

2299 switch (Result.getResultKind()) {

2301

2302

2303

2304

2307

2309 }

2310

2313 ClassDeclared))

2315 }

2316

2317

2318 break;

2319

2324 Result.suppressDiagnostics();

2326

2328

2329

2330 if (HasTrailingDot)

2332

2333

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

2341 }

2342 else

2344

2345

2346

2350 }

2351 }

2352

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

2357 if (Corrected.isKeyword()) {

2358

2359

2361 << Name);

2365

2366

2368 << Name);

2373 }

2374 }

2375

2376

2378}

2379

2386

2388 if (!Method) {

2389 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);

2391 }

2392

2395 Diag(SuperLoc, diag::err_no_super_class_message)

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

2412

2414

2415

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

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

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

2491}

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)

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)

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

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

2650

2651 if (!Method) {

2657 ? diag::err_arc_receiver_forward_class

2658 : diag::warn_receiver_forward_class),

2659 TypeRange)) {

2660

2663 if (Method && getLangOpts().ObjCAutoRefCount)

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

2666 }

2667 if (!Method)

2668 Method = Class->lookupClassMethod(Sel);

2669

2670

2671 if (!Method)

2672 Method = Class->lookupPrivateClassMethod(Sel);

2673

2675 false, false, Class))

2677 }

2678

2679

2682

2683 unsigned NumArgs = ArgsIn.size();

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

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

2687 Method, true, SuperLoc.isValid(), LBracLoc,

2688 RBracLoc, SourceRange(), ReturnType, VK))

2690

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"

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

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)

2716 }

2718

2720 Diag(Loc, diag::warn_direct_super_initialize_call);

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

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 }

2745 if (Method)

2747 ReceiverType, true);

2749}

2750

2751

2752

2753

2763 if (ReceiverType.isNull())

2765

2766 if (!ReceiverTypeInfo)

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

2866 else

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

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

2901

2902

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

2907 CK_CPointerToObjCPointerCast)

2909 } else {

2910

2913 CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;

2914 Receiver =

2917 }

2918 ReceiverType = Receiver->getType();

2920

2922 diag::err_incomplete_receiver_type))

2924

2928 Receiver = result.get();

2929 ReceiverType = Receiver->getType();

2930 }

2931 }

2932 }

2933

2934

2935

2936

2937

2938 if (!Method) {

2939

2940

2943 typeBound);

2947

2949 true, typeBound);

2950 if (!Methods.empty()) {

2951

2952

2953 Method = Methods[0];

2954

2957 Method = BestMethod;

2958

2961 receiverIsIdLike, Methods))

2963 }

2966

2967

2968

2969

2973

2975 if (!Method) {

2977

2979 Diag(SelLoc, diag::warn_instance_method_on_class_found)

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

2983 }

2984 }

2985 } else {

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

2988

2989

2990

2991

2992 Method = ClassDecl->lookupClassMethod(Sel);

2993

2994 if (!Method)

2995 Method = ClassDecl->lookupPrivateClassMethod(Sel);

2996

2999 }

3000 }

3001 if (!Method) {

3002

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

3004

3005

3008 false,

3009 true);

3010 if (!Methods.empty()) {

3011

3012

3013 Method = Methods[0];

3014

3015

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

3027 Method = BestMethod;

3028 }

3029 }

3030 }

3031 }

3032 } else {

3034

3035

3036

3037

3040

3042 if (!Method)

3048

3049 ClassDecl = OCIType->getInterfaceDecl();

3050

3051

3052

3053

3054

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

3068 Method = nullptr;

3069 } else {

3071 }

3072

3073 if (!Method)

3074

3076

3077 if (!Method) {

3078

3080

3081 if (!Method && getLangOpts().ObjCAutoRefCount) {

3082 Diag(SelLoc, diag::err_arc_may_not_respond)

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

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

3086 }

3087

3088 if (!Method && (!Receiver || isSelfExpr(Receiver))) {

3089

3090

3091

3092 if (OCIType->qual_empty()) {

3095 true,

3096 false);

3097 if (!Methods.empty()) {

3098

3099

3100 Method = Methods[0];

3101

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 }

3118 if (Method &&

3121 } else {

3122

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

3125 }

3126 }

3127 }

3128

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)

3140 }

3141

3142

3143

3144

3147 {

3149 diag::err_messaging_class_with_direct_method);

3153 }

3154 }

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

3157 }

3158

3159 if (SuperLoc.isValid()) {

3160 {

3161 auto Builder =

3162 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);

3166 } else {

3168 }

3169 }

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

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

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,

3230 Method, ClassMessage, SuperLoc.isValid(),

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

3233

3237 diag::err_illegal_message_expr_incomplete_type))

3239

3240

3241

3245 switch (family) {

3247 if (Method)

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 }

3337 if (Method) {

3338 bool IsClassObjectCall = ClassMessage;

3339

3340

3341

3342

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

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

3347 IsClassObjectCall = true;

3348 ReceiverType =

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 =

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

3387 LBracLoc))

3389 }

3390 }

3391 }

3392

3394

3396}

3397

3401 Selector Sel = OSE->getSelector();

3403 auto Pos = S.ReferencedSelectors.find(Sel);

3404 if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc)

3405 S.ReferencedSelectors.erase(Pos);

3406 }

3407}

3408

3409

3410

3411

3418 if (!Receiver)

3420

3421

3422 if (isa(Receiver)) {

3426 Receiver = Result.get();

3427 }

3428

3432 }

3435

3438 nullptr, LBracLoc, SelectorLocs,

3439 RBracLoc, Args);

3440}

3441

3443

3445

3446

3448

3449

3451

3452

3454

3455

3458

3463}

3464

3469}

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

3536

3540 bool Diagnose;

3541

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

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

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

3605 }

3606

3607

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

3610 if (left == ACC_invalid) return ACC_invalid;

3611 return merge(left, Visit(e->getFalseExpr()));

3612 }

3613

3614

3616

3618 }

3619

3620

3621 ACCResult VisitStmtExpr(StmtExpr *e) {

3623 }

3624

3625

3626 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {

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

3694 }

3695

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;

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

3795 if (isa(castedE)) {

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 += ")";

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

3820 }

3821 } else {

3822 std::string castCode = "(";

3823 castCode += bridgeKeyword;

3825 castCode += ")";

3828 if (isa(castedE)) {

3830 castCode));

3831 } else {

3832 castCode += "(";

3834 castCode));

3837 ")"));

3838 }

3839 }

3840}

3841

3842template

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

3861 TDNDecl = TD->getDecl();

3862 if (ObjCBridgeRelatedAttr *ObjCBAttr =

3863 getObjCBridgeAttr(TD))

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;

4009 if (TB *ObjCBAttr = getObjCBridgeAttr(TD)) {

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

4011 HadTheAttribute = true;

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

4013 return true;

4014

4015

4020 if (Target && isa(Target)) {

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;

4072 if (TB *ObjCBAttr = getObjCBridgeAttr(TD)) {

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

4074 HadTheAttribute = true;

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

4076 return true;

4077

4079

4084 if (Target && isa(Target)) {

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;

4142 bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeNSCast(

4144 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)

4145 return;

4146 bool HasObjCBridgeMutableAttr;

4147 bool ObjCBridgeMutableAttrWillNotWarn =

4148 CheckObjCBridgeNSCast(

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

4150 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)

4151 return;

4152

4153 if (HasObjCBridgeAttr)

4154 CheckObjCBridgeNSCast(SemaRef, castType, castExpr,

4155 HasObjCBridgeAttr, true);

4156 else if (HasObjCBridgeMutableAttr)

4157 CheckObjCBridgeNSCast(

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

4159 }

4161 bool HasObjCBridgeAttr;

4162 bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeCFCast(

4164 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)

4165 return;

4166 bool HasObjCBridgeMutableAttr;

4167 bool ObjCBridgeMutableAttrWillNotWarn =

4168 CheckObjCBridgeCFCast(

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

4170 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)

4171 return;

4172

4173 if (HasObjCBridgeAttr)

4174 CheckObjCBridgeCFCast(SemaRef, castType, castExpr,

4175 HasObjCBridgeAttr, true);

4176 else if (HasObjCBridgeMutableAttr)

4177 CheckObjCBridgeCFCast(

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 }

4249 if (Target && isa(Target))

4250 RelatedClass = cast(Target);

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

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

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

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

4459

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

4461

4462 case ACC_invalid:

4463 break;

4464

4465

4466 case ACC_bottom:

4467 case ACC_plusZero:

4469

4470

4471 case ACC_plusOne:

4473 CK_ARCConsumeObject, castExpr, nullptr,

4477 }

4478

4479

4480

4481

4485

4486

4487

4488

4492

4493

4494

4495

4496

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

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

4501 if (Diagnose)

4505 }

4507}

4508

4509

4510

4512

4515

4519

4522 castType = cast->getTypeAsWritten();

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

4526 castType = cast->getTypeAsWritten();

4528 } else {

4529 llvm_unreachable("Unexpected ImplicitCastExpr");

4530 }

4531

4534

4537

4540}

4541

4542

4543

4547

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

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

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

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

4556 uo->getOperatorLoc(), false,

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

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

4561

4562 unsigned n = gse->getNumAssocs();

4565 subExprs.reserve(n);

4566 subTypes.reserve(n);

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

4569 Expr *sub = assoc.getAssociationExpr();

4570 if (assoc.isSelected())

4572 subExprs.push_back(sub);

4573 }

4574

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

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

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

4579 } else {

4580 assert(isa(e) && "bad form of unbridged cast!");

4581 return cast(e)->getSubExpr();

4582 }

4583}

4584

4592 if (isa(canCastType) &&

4598 return !ObjI->isArcWeakrefUnavailable();

4599 }

4600 return true;

4601}

4602

4603

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

4606

4607

4608

4609 while (true) {

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

4611 prevExpr = curExpr;

4612 curExpr = pe->getSubExpr();

4613 continue;

4614 }

4615

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

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

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

4619 if (!prevExpr)

4620 return ice->getSubExpr();

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

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

4623 else

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

4625 return e;

4626 }

4627

4628 prevExpr = curExpr;

4629 curExpr = ce->getSubExpr();

4630 continue;

4631 }

4632

4633

4634 break;

4635 }

4636

4637 return e;

4638}

4639

4644 Expr *SubExpr) {

4648 SubExpr = SubResult.get();

4649

4652

4654

4655 bool MustConsume = false;

4657

4658 CK = CK_Dependent;

4660

4662 : CK_CPointerToObjCPointerCast);

4663 switch (Kind) {

4665 break;

4666

4668 bool br = isKnownName("CFBridgingRelease");

4669 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)

4670 << 2

4671 << FromType

4673 << T

4675 << Kind;

4676 Diag(BridgeKeywordLoc, diag::note_arc_bridge)

4678 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)

4679 << FromType << br

4681 br ? "CFBridgingRelease "

4682 : "__bridge_transfer ");

4683

4685 break;

4686 }

4687

4689

4690 MustConsume = true;

4691 break;

4692 }

4694

4695 CK = CK_BitCast;

4696 switch (Kind) {

4698

4699

4701 break;

4702

4704

4708 break;

4709

4711 bool br = isKnownName("CFBridgingRetain");

4712 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)

4714 << FromType

4715 << 2

4716 << T

4718 << Kind;

4719

4720 Diag(BridgeKeywordLoc, diag::note_arc_bridge)

4722 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)

4723 << T << br

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

4726

4728 break;

4729 }

4730 }

4731 } else {

4732 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)

4733 << FromType << T << Kind

4737 }

4738

4740 BridgeKeywordLoc,

4741 TSInfo, SubExpr);

4742

4743 if (MustConsume) {

4747 }

4748

4750}

4751

4757 Expr *SubExpr) {

4763 if (!TSInfo)

4766 SubExpr);

4767}

4768

4773

4774

4775 if (!CurMethod)

4777

4778

4779

4780

4781

4782

4783

4784

4785

4786

4787 bool IsClassMethod = CurMethod->isClassMethod();

4788

4789 bool LookForIvars;

4790 if (Lookup.empty())

4791 LookForIvars = true;

4792 else if (IsClassMethod)

4793 LookForIvars = false;

4794 else

4798 if (LookForIvars) {

4803

4804 if (IsClassMethod) {

4807 }

4808

4809

4814

4815

4816 return IV;

4817 }

4819

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

4826 }

4827 }

4830

4832 dyn_cast(Lookup.getFoundDecl())) {

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

4835 }

4836 }

4837

4838

4840}

4841

4844 bool AllowBuiltinCreation) {

4845

4851 cast(Ivar.get()));

4852

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

4855

4856

4858}

4859

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

4866

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

4869

4870

4871

4874

4875

4878

4879

4880

4888 false,

4889 false);

4892

4896

4898

4903

4907

4912 }

4916

4918}

4919

4926

4927

4928

4929

4933 CK_CPointerToObjCPointerCast);

4934 return LHSTy;

4935 }

4939 CK_CPointerToObjCPointerCast);

4940 return RHSTy;

4941 }

4942

4946 CK_CPointerToObjCPointerCast);

4947 return LHSTy;

4948 }

4952 CK_CPointerToObjCPointerCast);

4953 return RHSTy;

4954 }

4955

4959 return LHSTy;

4960 }

4964 return RHSTy;

4965 }

4966

4968

4970

4971 return LHSTy;

4972 }

4977 QualType compositeType = LHSTy;

4978

4979

4980

4981

4982

4983

4984

4985

4986

4987

4988

4989

4990

4991

4993 .isNull()) {

4994

5000 RHSOPT->isObjCQualifiedIdType()) &&

5002 true)) {

5003

5004

5005

5006

5010 } else {

5011 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)

5017 return incompatTy;

5018 }

5019

5022 return compositeType;

5023 }

5024

5027

5028

5029 Diag(QuestionLoc, diag::err_cond_voidptr_arc)

5032 LHS = RHS = true;

5034 }

5040

5042

5044 return destType;

5045 }

5048

5049

5050 Diag(QuestionLoc, diag::err_cond_voidptr_arc)

5053 LHS = RHS = true;

5055 }

5061

5063

5065 return destType;

5066 }

5068}

5069

5071 bool Diagnose) {

5073 return false;

5074

5076 if (!PT)

5077 return false;

5079

5080

5081

5082

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

5085 if (OV->getSourceExpr())

5087

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

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

5090 return false;

5091 if (!SL->isOrdinary())

5092 return false;

5093

5094 if (Diagnose) {

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

5098 }

5099 return true;

5100 }

5101

5102 if ((isa(SrcExpr) || isa(SrcExpr) ||

5103 isa(SrcExpr) || isa(SrcExpr) ||

5104 isa(SrcExpr)) &&

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

5108 return false;

5109 if (Diagnose) {

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

5111 << 1

5113 Expr *NumLit =

5115 if (NumLit)

5116 Exp = NumLit;

5117 }

5118 return true;

5119 }

5120

5121 return false;

5122}

5123

5124

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

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

5135 Result.isSingleResult()) {

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

5139 }

5140 }

5143 return new (Context)

5145}

5146

5151 auto FindSpecVersion =

5152 [&](StringRef Platform) -> std::optional {

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

5155 });

5156

5157

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

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

5161 });

5162 }

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

5164 return std::nullopt;

5166 };

5167

5168 VersionTuple Version;

5169 if (auto MaybeVersion =

5171 Version = *MaybeVersion;

5172

5173

5174

5176 Context->HasPotentialAvailabilityViolations = true;

5177

5178 return new (Context)

5180}

5181

5182

5183

5186 if (type->isObjCObjectPointerType()) {

5187 return CK_BitCast;

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

5190 return CK_BlockPointerToObjCPointerCast;

5191 } else {

5192 assert(type->isPointerType());

5193 return CK_CPointerToObjCPointerCast;

5194 }

5195}

5196

5200 default:

5201 break;

5202 case Stmt::ObjCStringLiteralClass:

5203

5205 case Stmt::ObjCArrayLiteralClass:

5206

5208 case Stmt::ObjCDictionaryLiteralClass:

5209

5211 case Stmt::BlockExprClass:

5213 case Stmt::ObjCBoxedExprClass: {

5214 Expr *Inner = cast(FromE)->getSubExpr()->IgnoreParens();

5215 switch (Inner->getStmtClass()) {

5216 case Stmt::IntegerLiteralClass:

5217 case Stmt::FloatingLiteralClass:

5218 case Stmt::CharacterLiteralClass:

5219 case Stmt::ObjCBoolLiteralExprClass:

5220 case Stmt::CXXBoolLiteralExprClass:

5221

5223 case Stmt::ImplicitCastExprClass: {

5224 CastKind CK = cast(Inner)->getCastKind();

5225

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

5228 break;

5229 }

5230 default:

5231 break;

5232 }

5234 }

5235 }

5237}

Defines the clang::ASTContext interface.

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

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

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

Produce a diagnostic highlighting some portion of a literal.

llvm::MachO::Target Target

Defines the clang::Preprocessor interface.

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

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

static QualType stripObjCInstanceType(ASTContext &Context, QualType T)

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

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

Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.

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

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

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

static Expr * maybeUndoReclaimObject(Expr *e)

Look for an ObjCReclaimReturnedObject cast and destroy it.

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

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

Check for duplicate keys in an ObjC dictionary literal.

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

Validates ObjCInterfaceDecl availability.

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

Maps ObjCLiteralKind to NSClassIdKindKind.

static bool isAnyCLike(ARCConversionTypeClass ACTC)

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

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

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

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

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

static T * getObjCBridgeAttr(const TypedefType *TD)

static ARCConversionTypeClass classifyTypeForARCConversion(QualType type)

static bool isAnyRetainable(ARCConversionTypeClass ACTC)

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

@ ACTC_voidPtr

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

@ ACTC_retainable

id, void (^)()

@ ACTC_coreFoundation

struct A*

@ ACTC_indirectRetainable

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

@ ACTC_none

int, void, struct A

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

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

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

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

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

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

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

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

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.

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

TranslationUnitDecl * getTranslationUnitDecl() const

const ConstantArrayType * getAsConstantArrayType(QualType T) const

void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl)

QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)

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

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

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

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

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

void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const

Emit the Objective-CC type encoding for the given type T into S.

CanQualType getCanonicalType(QualType T) const

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

void setObjCNSStringType(QualType T)

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

QualType getObjCSelRedefinitionType() const

Retrieve the type that 'SEL' has been defined to, which may be different from the built-in 'SEL' if '...

QualType getPointerType(QualType T) const

Return the uniqued reference to the type for a pointer to the specified type.

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

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

bool isObjCSelType(QualType T) const

bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT, ObjCInterfaceDecl *IDecl)

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

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

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

QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const

Return the unique reference to the type for a constant array of the specified element type.

SelectorTable & Selectors

TypedefDecl * getBOOLDecl() const

Retrieve declaration of 'BOOL' typedef.

QualType getObjCInstanceType()

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

QualType getObjCProtoType() const

Retrieve the type of the Objective-C Protocol class.

CanQualType ObjCBuiltinIdTy

void setBOOLDecl(TypedefDecl *TD)

Save declaration of 'BOOL' typedef.

QualType getObjCSelType() const

Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.

CanQualType UnsignedLongTy

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

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

QualType getStringLiteralArrayType(QualType EltTy, unsigned Length) const

Return a type for a constant array for a string literal of the specified element type and length.

QualType getBOOLType() const

type of 'BOOL' type.

CanQualType PseudoObjectTy

QualType getQualifiedType(SplitQualType split) const

Un-split a SplitQualType.

QualType getObjCObjectPointerType(QualType OIT) const

Return a ObjCObjectPointerType type for the given ObjCObjectType.

CanQualType ObjCBuiltinBoolTy

QualType getObjCObjectType(QualType Base, ObjCProtocolDecl *const *Protocols, unsigned NumProtocols) const

Legacy interface: cannot provide type arguments or __kindof.

static bool isObjCNSObjectType(QualType Ty)

Return true if this is an NSObject object with its NSObject attribute set.

QualType getObjCIdType() const

Represents the Objective-CC id type.

bool hasSameUnqualifiedType(QualType T1, QualType T2) const

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

QualType getObjCClassRedefinitionType() const

Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...

bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl)

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

QualType getObjCConstantStringInterface() const

QualType getObjCIdRedefinitionType() const

Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...

const TargetInfo & getTargetInfo() const

QualType getObjCNSStringType() const

QualType getWideCharType() const

Return the type of wide characters.

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

ArraySizeModifier getSizeModifier() const

QualType getElementType() const

unsigned getIndexTypeCVRQualifiers() const

An attributed type is a type to which a type attribute has been applied.

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

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

One specifier in an @available expression.

StringRef getPlatform() const

VersionTuple getVersion() const

A builtin binary operation expression such as "x + y" or "x <= y".

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.

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

FunctionDecl * getDirectCallee()

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

QualType withConst() const

Retrieves a version of this type with const applied.

CanQual< T > getUnqualifiedType() const

Retrieve the unqualified form of this type.

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

CastKind getCastKind() const

void setExprNeedsCleanups(bool SideEffects)

ConditionalOperator - The ?: ternary operator.

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

Decl * getNonClosureAncestor()

Find the nearest non-closure ancestor of this context, i.e.

const BlockDecl * getInnermostBlockDecl() const

Return this DeclContext if it is a BlockDecl.

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

llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() 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

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.

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

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.

Represents a function declaration or definition.

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.

@ FoundOverloaded

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

@ FoundUnresolvedValue

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

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

@ NotFoundInCurrentInstantiation

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

@ Found

Name lookup found a single declaration that met the criteria.

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

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

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

unsigned param_size() 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.

QualType getSendResultType() const

Determine the type of an expression that sends a message to this function.

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

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

bool isInstanceMethod() const

ObjCMethodFamily getMethodFamily() const

Determines the family of this method.

QualType getReturnType() const

ObjCImplementationControl getImplementationControl() 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 a class type in Objective C.

ObjCInterfaceDecl * getInterface() const

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

Represents one property declaration in an Objective-C interface.

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

IdentifierTable & getIdentifierTable()

SelectorTable & getSelectorTable()

PseudoObjectExpr - An expression which accesses a pseudo-object l-value.

Expr * getResultExpr()

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

A (possibly-)qualified type.

bool isTriviallyCopyableType(const ASTContext &Context) const

Return true if this is a trivially copyable type (C++0x [basic.types]p9)

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

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

Base for LValueReferenceType and RValueReferenceType.

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

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

Return the default setter selector for the given identifier.

Selector getNullarySelector(const IdentifierInfo *ID)

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

Can create any sort of selector.

Selector getUnarySelector(const IdentifierInfo *ID)

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

bool isNull() const

Determine whether this is the empty selector.

ObjCStringFormatFamily getStringFormatFamily() const

unsigned getNumArgs() const

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

Emit a diagnostic.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

ASTContext & getASTContext() const

const LangOptions & getLangOpts() const

DiagnosticsEngine & getDiagnostics() const

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

ObjCMethodDecl * ValueWithBytesObjCTypeMethod

The declaration of the valueWithBytes:objCType: method.

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

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.

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.

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.

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

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

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.

ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)

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

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)

ObjCLiteralKind CheckLiteralKind(Expr *FromE)

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

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

ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)

ObjCInterfaceDecl * NSArrayDecl

The declaration of the Objective-C NSArray class.

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

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.

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)

void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)

ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)

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

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.

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

ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)

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)

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)

void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)

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

ObjCMethodDecl * tryCaptureObjCSelf(SourceLocation Loc)

Try to capture an implicit reference to 'self'.

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

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

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)

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.

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

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

ParseObjCProtocolExpression - Build protocol expression for @protocol.

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

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.

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

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

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

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

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

CastKind PrepareCastToObjCObjectPointer(ExprResult &E)

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

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)

void EmitRelatedResultTypeNoteForReturn(QualType destType)

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

void diagnoseARCUnbridgedCast(Expr *e)

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

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

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

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

bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)

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.

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.

bool isSelfExpr(Expr *RExpr)

Private Helper predicate to check for 'self'.

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

bool isKnownName(StringRef name)

std::unique_ptr< NSAPI > NSAPIObj

Caches identifiers/selectors for NSFoundation APIs.

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

ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)

Package the given type and TSI into a ParsedType.

ExprResult PerformContextuallyConvertToObjCPointer(Expr *From)

PerformContextuallyConvertToObjCPointer - Perform a contextual conversion of the expression From to a...

Scope * getCurScope() const

Retrieve the parser's current scope.

@ LookupOrdinaryName

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

void DiagnoseSentinelCalls(const NamedDecl *D, SourceLocation Loc, ArrayRef< Expr * > Args)

DiagnoseSentinelCalls - This routine checks whether a call or message-send is to a declaration with t...

bool FormatStringHasSArg(const StringLiteral *FExpr)

ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, CorrectionCandidateCallback *CCC=nullptr, bool IsInlineAsmIdentifier=false, Token *KeywordReplacement=nullptr)

ExprResult MaybeBindToTemporary(Expr *E)

MaybeBindToTemporary - If the passed in expression has a record type with a non-trivial destructor,...

FPOptionsOverride CurFPFeatureOverrides()

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

Look up a name, looking for a single declaration.

ExprResult UsualUnaryConversions(Expr *E)

UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....

ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)

ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME)

This is not an AltiVec-style cast or or C++ direct-initialization, so turn the ParenListExpr into a s...

bool LookupBuiltin(LookupResult &R)

Lookup a builtin function, when name lookup would otherwise fail.

ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)

ASTContext & getASTContext() const

bool tryCaptureVariable(ValueDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt)

Try to capture the given variable.

ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)

ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.

ExprResult DefaultArgumentPromotion(Expr *E)

DefaultArgumentPromotion (C99 6.5.2.2p6).

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

TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)

Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...

ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)

ActOnCXXBoolLiteral - Parse {true,false} literals.

const LangOptions & LangOpts

void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)

Perform marking for a reference to an arbitrary declaration.

CleanupInfo Cleanup

Used to control the generation of ExprWithCleanups.

sema::FunctionScopeInfo * getCurFunction() const

ExprResult DefaultLvalueConversion(Expr *E)

void maybeExtendBlockObject(ExprResult &E)

Do an explicit extend of the given block pointer if we're in ARC.

static bool isCast(CheckedConversionKind CCK)

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

bool isUnevaluatedContext() const

Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.

ObjCMethodDecl * SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, SmallVectorImpl< ObjCMethodDecl * > &Methods)

DeclContext * getFunctionLevelDeclContext(bool AllowLambda=false) const

If AllowLambda is true, treat lambda as function.

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.

sema::FunctionScopeInfo * getCurFunctionAvailabilityContext()

Retrieve the current function, if any, that should be analyzed for potential availability violations.

bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)

Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.

void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)

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

Ensure that the type T is a complete type.

Scope * TUScope

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

ExprResult forceUnknownAnyToType(Expr *E, QualType ToType)

Force an expression with unknown-type to an expression of the given type.

SourceManager & SourceMgr

DiagnosticsEngine & Diags

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

ExprResult ActOnIntegerConstant(SourceLocation Loc, int64_t Val)

sema::FunctionScopeInfo * getEnclosingFunction() const

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

Perform unqualified name lookup starting from a given scope.

static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)

ExprResult checkUnknownAnyArg(SourceLocation callLoc, Expr *result, QualType &paramType)

Type-check an expression that's being passed to an __unknown_anytype parameter.

llvm::SmallVector< std::pair< SourceLocation, const BlockDecl * >, 1 > ImplicitlyRetainedSelfLocs

List of SourceLocations where 'self' is implicitly retained inside a block.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

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

StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).

CompoundStmt * getSubStmt()

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

Stmt - This represents one statement.

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.

static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)

This is the "fully general" constructor that allows representation of strings formed from multiple co...

StringRef getString() const

StringRef getPlatformName() const

Retrieve the name of the platform as it is used in the availability attribute.

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.

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

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

Helper methods to distinguish type categories.

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

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 ObjCObjectType * getAsObjCInterfaceType() 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 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)

Represents a variable declaration or definition.

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.

void recordUseOfWeak(const ExprT *E, bool IsRead=true)

Record that a weak object was accessed.

bool ObjCIsDesignatedInit

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

bool ObjCShouldCallSuper

A flag that is set when parsing a method that must call super's implementation, such as -dealloc,...

bool ObjCWarnForNoInitDelegation

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

bool ObjCIsSecondaryInit

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

bool ObjCWarnForNoDesignatedInitChain

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

Defines the clang::TargetInfo interface.

const internal::VariadicAllOfMatcher< Attr > attr

Matches attributes.

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.

uint32_t Literal

Literals are represented as positive integers.

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.

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

NullabilityKind

Describes the nullability of a particular type.

@ Nullable

Values of this type can be null.

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

ObjCMethodFamily

A family of Objective-C methods.

@ OMF_None

No particular method family.

@ Parameter

The parameter type of a method or function.

@ Result

The result type of a method or function.

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.

ActionResult< Expr * > ExprResult

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.

const FunctionProtoType * T

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

Determine whether two declarations declare the same entity.

ActionResult< Decl * > DeclResult

U cast(CodeGen::Address addr)

@ None

The alignment was not explicit in code.

@ Class

The "class" keyword introduces the elaborated-type-specifier.

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.

MutableArrayRef< Expr * > MultiExprArg

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