clang: lib/CodeGen/CGObjC.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

27#include "llvm/Analysis/ObjCARCUtil.h"

28#include "llvm/BinaryFormat/MachO.h"

29#include "llvm/IR/Constants.h"

30#include "llvm/IR/DataLayout.h"

31#include "llvm/IR/InlineAsm.h"

32#include

33using namespace clang;

35

36typedef llvm::PointerIntPairllvm::Value\*,1,bool TryEmitResult;

42

43

44

49

50

52{

53 llvm::Constant *C =

54 CGM.getObjCRuntime().GenerateConstantString(E->getString()).getPointer();

55 return C;

56}

57

58

59

60

61

62

63llvm::Value *

65

66

69

73 }

74

75 assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method");

77

78

79

80

83 llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl);

84

88

89

90

92 if (ValueType->isObjCBoxableRecordType()) {

93

94

97 llvm::Value *BitCast = Builder.CreateBitCast(

100

101

102 std::string Str;

104 llvm::Constant *GV = CGM.GetAddrOfConstantCString(Str).getPointer();

105

106

109 llvm::Value *Cast = Builder.CreateBitCast(GV, ConvertType(EncodingQT));

110

112 } else {

114 }

115

118 Args, ClassDecl, BoxingMethod);

121}

122

128 if (!ALE)

130

131

132 uint64_t NumElements =

134 if (NumElements == 0 && CGM.getLangOpts().ObjCRuntime.hasEmptyCollections()) {

135 StringRef ConstantName = ALE ? "__NSArray0__" : "__NSDictionary0__";

136 QualType IdTy(CGM.getContext().getObjCIdType());

137 llvm::Constant *Constant =

138 CGM.CreateRuntimeVariable(ConvertType(IdTy), ConstantName);

142 llvm::LLVMContext::MD_invariant_load,

145 }

146

147

148 llvm::APInt APNumElements(Context.getTypeSize(Context.getSizeType()),

149 NumElements);

151 QualType ElementArrayType = Context.getConstantArrayType(

153 0);

154

155

158 if (DLE)

160

161

162

164 bool TrackNeededObjects =

166 CGM.getCodeGenOpts().OptimizationLevel != 0);

167

168

169 for (uint64_t i = 0; i < NumElements; i++) {

170 if (ALE) {

171

175

178 if (TrackNeededObjects) {

179 NeededObjects.push_back(value);

180 }

181 } else {

182

188

189

195 if (TrackNeededObjects) {

196 NeededObjects.push_back(keyValue);

197 NeededObjects.push_back(valueValue);

198 }

199 }

200 }

201

202

208 if (DLE) {

209 argDecl = *PI++;

212 }

213 argDecl = *PI;

215 llvm::Value *Count =

216 llvm::ConstantInt::get(CGM.getTypes().ConvertType(ArgQT), NumElements);

218

219

224 assert(InterfacePointerType && "Unexpected InterfacePointerType - null");

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

228 llvm::Value *Receiver = Runtime.GetClass(*this, Class);

229

230

233 Receiver, Args, Class, MethodWithObjects);

234

235

236

237

238

239 if (TrackNeededObjects) {

241 }

242

245}

246

250

255

256

258

259

260

261

262 return CGM.getObjCRuntime().GetSelector(*this, E->getSelector());

263}

264

266

267 return CGM.getObjCRuntime().GenerateProtocolRef(*this, E->getProtocol());

268}

269

270

271

272

276 return Result;

277

278

279 llvm::Type *ExpLLVMTy = CGF.ConvertType(ExpT);

280 if (ExpLLVMTy == Result.getScalarVal()->getType())

281 return Result;

282

283

285 ExpLLVMTy));

286}

287

288

289

290static bool

293

294

295

298

299

300 if (auto opaque = dyn_cast(receiver)) {

301 if (opaque->getSourceExpr())

302 receiver = opaque->getSourceExpr()->IgnoreParens();

303 }

304

305 const ImplicitCastExpr *ice = dyn_cast(receiver);

306 if (!ice || ice->getCastKind() != CK_LValueToRValue) return true;

308

309

310 if (auto opaque = dyn_cast(receiver)) {

311 if (opaque->getSourceExpr())

312 receiver = opaque->getSourceExpr()->IgnoreParens();

313 }

314

315

317 return true;

318

319

321 return false;

322

323

325 if (!declRef) return true;

326 const VarDecl *var = dyn_cast(declRef->getDecl());

327 if (!var) return true;

328

329

330

331 return (var->hasLocalStorage() &&

332 !var->hasAttr());

333 }

334

337

338 return false;

339

341

342 return false;

343 }

344

345 llvm_unreachable("invalid receiver kind");

346}

347

348

349

353 if (auto CE = dyn_cast(E)) {

354 if (CE->getCastKind() == CK_LValueToRValue) {

356 return CE->getSubExpr();

357 }

358 }

359

360 return nullptr;

361}

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

380 bool isClassMessage) {

381 auto &CGM = CGF.CGM;

382 if (!CGM.getCodeGenOpts().ObjCConvertMessagesToRuntimeCalls)

383 return std::nullopt;

384

388 if (isClassMessage &&

389 Runtime.shouldUseRuntimeFunctionsForAlloc() &&

391

392

395

396

398 Args.size() == 1 && Args.front().getType()->isPointerType() &&

400 const llvm::Value* arg = Args.front().getKnownRValue().getScalarVal();

404 return std::nullopt;

405 }

406 }

407 break;

408

412 Runtime.shouldUseARCFunctionsForRetainRelease())

414 break;

415

419 Runtime.shouldUseARCFunctionsForRetainRelease())

421 break;

422

426 Runtime.shouldUseARCFunctionsForRetainRelease()) {

428 return nullptr;

429 }

430 break;

431

432 default:

433 break;

434 }

435 return std::nullopt;

436}

437

442 bool isClassMessage) {

443 if (std::optional<llvm::Value *> SpecializedResult =

445 Sel, Method, isClassMessage)) {

447 }

448 return GenerateMessageSend(CGF, Return, ResultType, Sel, Receiver, Args, OID,

450}

451

454 llvm::UniqueVector<const ObjCProtocolDecl *> &PDs) {

457 PDs.insert(Can);

458 return;

459 }

460

461 for (const auto *ParentPD : PD->protocols())

463}

464

465std::vector<const ObjCProtocolDecl *>

468 std::vector<const ObjCProtocolDecl *> RuntimePds;

469 llvm::DenseSet<const ObjCProtocolDecl *> NonRuntimePDs;

470

471 for (; begin != end; ++begin) {

472 const auto *It = *begin;

473 const auto *Can = It->getCanonicalDecl();

474 if (Can->isNonRuntimeProtocol())

475 NonRuntimePDs.insert(Can);

476 else

477 RuntimePds.push_back(Can);

478 }

479

480

481 if (NonRuntimePDs.empty())

482 return RuntimePds;

483

484

485

486

487

488 llvm::UniqueVector<const ObjCProtocolDecl *> FirstImpliedProtos;

489 for (const auto *PD : NonRuntimePDs)

491

492

493

494 llvm::DenseSet<const ObjCProtocolDecl *> AllImpliedProtocols;

495 for (const auto *PD : RuntimePds) {

496 const auto *Can = PD->getCanonicalDecl();

497 AllImpliedProtocols.insert(Can);

498 Can->getImpliedProtocols(AllImpliedProtocols);

499 }

500

501

502

503

504 for (const auto *PD : FirstImpliedProtos) {

505 PD->getImpliedProtocols(AllImpliedProtocols);

506 }

507

508

509

510

511

512 for (const auto *PD : FirstImpliedProtos) {

513 if (!AllImpliedProtocols.contains(PD)) {

514 RuntimePds.push_back(PD);

515 }

516 }

517

518 return RuntimePds;

519}

520

521

522

523

524static std::optional<llvm::Value *>

527 if (!Runtime.shouldUseRuntimeFunctionForCombinedAllocInit())

528 return std::nullopt;

529

530

535 return std::nullopt;

536

537

538

539 auto *SubOME =

541 if (!SubOME)

542 return std::nullopt;

543 Selector SubSel = SubOME->getSelector();

544

545 if (!SubOME->getType()->isObjCObjectPointerType() ||

547 return std::nullopt;

548

549 llvm::Value *Receiver = nullptr;

550 switch (SubOME->getReceiverKind()) {

552 if (!SubOME->getInstanceReceiver()->getType()->isObjCClassType())

553 return std::nullopt;

554 Receiver = CGF.EmitScalarExpr(SubOME->getInstanceReceiver());

555 break;

556

558 QualType ReceiverType = SubOME->getClassReceiver();

561 assert(ID && "null interface should be impossible here");

563 break;

564 }

567 return std::nullopt;

568 }

569

571}

572

575

576

577

578

580

582

583

584

591 }

592 }

593

596

597

598

599

600

601 bool retainSelf =

602 (!isDelegateInit &&

603 CGM.getLangOpts().ObjCAutoRefCount &&

604 method &&

605 method->hasAttr());

606

608 bool isSuperMessage = false;

609 bool isClassMessage = false;

611

613 llvm::Value *Receiver = nullptr;

618 if (retainSelf) {

621 Receiver = ter.getPointer();

622 if (ter.getInt()) retainSelf = false;

623 } else

625 break;

626

630 assert(OID && "Invalid Objective-C class message send");

631 Receiver = Runtime.GetClass(*this, OID);

632 isClassMessage = true;

633 break;

634 }

635

639 isSuperMessage = true;

640 break;

641

645 isSuperMessage = true;

646 isClassMessage = true;

647 break;

648 }

649

650 if (retainSelf)

652

653

654

655

656 if (getLangOpts().ObjCAutoRefCount && method &&

657 method->hasAttr() &&

660

662

665

666

667

668

669

670

671

672

673 if (isDelegateInit) {

675 "delegate init calls should only be marked in ARC");

676

677

681 }

682

684 if (isSuperMessage) {

685

691 isCategoryImpl,

692 Receiver,

693 isClassMessage,

694 Args,

695 method);

696 } else {

697

699 *this, Return, ResultType, E->getSelector(), Receiver, Args, OID,

700 method, isClassMessage);

701 }

702

703

704

705 if (isDelegateInit) {

708 llvm::Value *newSelf = result.getScalarVal();

709

710

711

713 newSelf = Builder.CreateBitCast(newSelf, selfTy);

714

715 Builder.CreateStore(newSelf, selfAddr);

716 }

717

719}

720

721namespace {

722struct FinishARCDealloc final : EHScopeStack::Cleanup {

725

729

731

732

734

739 iface,

740 isCategory,

741 self,

742 false,

743 args,

744 method);

745 }

746};

747}

748

749

750

751

756

757 if (OMD->hasAttr())

758 DebugInfo = nullptr;

759

760 llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);

761

762 const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD);

764 Fn->setVisibility(llvm::Function::HiddenVisibility);

765 CGM.SetLLVMFunctionAttributes(OMD, FI, Fn, false);

766 CGM.SetLLVMFunctionAttributesForDefinition(OMD, Fn);

767 } else {

768 CGM.SetInternalFunctionAttributes(OMD, Fn, FI);

769 }

770

774

776

778 CurEHLocation = OMD->getEndLoc();

779

782

784

785

786

787

788 CGM.getObjCRuntime().GenerateDirectMethodPrologue(*this, Fn, OMD, CD);

789 }

790

791

792 if (CGM.getLangOpts().ObjCAutoRefCount &&

797 if (ident->isStr("dealloc"))

799 }

800}

801

804

805

806

815

816

817

819 bool isAtomic, bool hasStrong) {

821

822 llvm::Value *src =

825

826

827

829

833

838

843}

844

845

846

847

849

850

851 return false;

852}

853

854

855

857 llvm::Triple::ArchType arch) {

858

859

860

861

862

864}

865

866namespace {

867 class PropertyImplStrategy {

868 public:

869 enum StrategyKind {

870

871

873

874

875 GetSetProperty,

876

877

878

879 SetPropertyAndExpressionGet,

880

881

882 CopyStruct,

883

884

885

887 };

888

889 StrategyKind getKind() const { return StrategyKind(Kind); }

890

891 bool hasStrongMember() const { return HasStrong; }

892 bool isAtomic() const { return IsAtomic; }

893 bool isCopy() const { return IsCopy; }

894

895 CharUnits getIvarSize() const { return IvarSize; }

896 CharUnits getIvarAlignment() const { return IvarAlignment; }

897

898 PropertyImplStrategy(CodeGenModule &CGM,

899 const ObjCPropertyImplDecl *propImpl);

900

901 private:

902 LLVM_PREFERRED_TYPE(StrategyKind)

903 unsigned Kind : 8;

904 LLVM_PREFERRED_TYPE(bool)

905 unsigned IsAtomic : 1;

906 LLVM_PREFERRED_TYPE(bool)

907 unsigned IsCopy : 1;

908 LLVM_PREFERRED_TYPE(bool)

909 unsigned HasStrong : 1;

910

911 CharUnits IvarSize;

912 CharUnits IvarAlignment;

913 };

914}

915

916

917PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,

918 const ObjCPropertyImplDecl *propImpl) {

919 const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();

921

924 HasStrong = false;

925

926

928 QualType ivarType = ivar->getType();

930 IvarSize = TInfo.Width;

931 IvarAlignment = TInfo.Align;

932

933

934

935

936 if (IsCopy) {

937 Kind = IsAtomic ? GetSetProperty : SetPropertyAndExpressionGet;

938 return;

939 }

940

941

943

945

946

947

948

949

950 } else if (CGM.getLangOpts().ObjCAutoRefCount && !IsAtomic) {

951

952

953

954

955

956

959 else

960 Kind = SetPropertyAndExpressionGet;

961 return;

962

963

964

965

966 } else if (!IsAtomic) {

967 Kind = SetPropertyAndExpressionGet;

968 return;

969

970

971 } else {

972 Kind = GetSetProperty;

973 return;

974 }

975 }

976

977

978 if (!IsAtomic) {

980 return;

981 }

982

983

984

987 return;

988 }

989

990

991

992

997 return;

998 }

999

1000

1003 HasStrong = RD->hasObjectMember();

1004

1005

1006

1007

1008 if (HasStrong) {

1009 Kind = CopyStruct;

1010 return;

1011 }

1012

1013

1014

1015

1016

1017

1018 if (!IvarSize.isPowerOfTwo()) {

1019 Kind = CopyStruct;

1020 return;

1021 }

1022

1023 llvm::Triple::ArchType arch =

1025

1026

1027

1028

1030 Kind = CopyStruct;

1031 return;

1032 }

1033

1034

1035

1037 Kind = CopyStruct;

1038 return;

1039 }

1040

1041

1043}

1044

1045

1046

1047

1048

1051 llvm::Constant *AtomicHelperFn =

1052 CodeGenFunction(CGM).GenerateObjCAtomicGetterCopyHelperFunction(PID);

1054 assert(OMD && "Invalid call to generate getter (empty method)");

1056

1058

1060}

1061

1064 if (!getter) return true;

1065

1066

1067

1068

1069

1070

1071

1073 return false;

1074

1075

1076 if (const CXXConstructExpr *construct = dyn_cast(getter))

1077 return (construct->getConstructor()->isTrivial());

1078

1079

1080

1082 return false;

1083}

1084

1085

1086

1088 llvm::Value *returnAddr,

1090 llvm::Constant *AtomicHelperFn) {

1091

1092

1094

1095

1097

1098

1099 llvm::Value *ivarAddr =

1103

1104

1106

1107 llvm::FunctionCallee copyCppAtomicObjectFn =

1113}

1114

1115

1116

1117

1118

1119

1120

1124

1125

1126

1128 return llvm::PoisonValue::get(selType);

1129 }

1130

1132}

1133

1134void

1138 llvm::Constant *AtomicHelperFn) {

1139

1141

1143 if (!AtomicHelperFn) {

1148 } else {

1151 ivar, AtomicHelperFn);

1152 }

1153 return;

1154 }

1155

1156

1158 if (!AtomicHelperFn) {

1161 nullptr);

1163 }

1164 else {

1167 ivar, AtomicHelperFn);

1168 }

1169 return;

1170 }

1171

1175

1176

1177 PropertyImplStrategy strategy(CGM, propImpl);

1178 switch (strategy.getKind()) {

1179 case PropertyImplStrategy::Native: {

1180

1181 if (strategy.getIvarSize().isZero())

1182 return;

1183

1185

1186

1187

1188 uint64_t ivarSize = getContext().toBits(strategy.getIvarSize());

1189 llvm::Type *bitcastType = llvm::Type::getIntNTy(getLLVMContext(), ivarSize);

1190

1191

1194 llvm::LoadInst *load = Builder.CreateLoad(ivarAddr, "load");

1195 load->setAtomic(llvm::AtomicOrdering::Unordered);

1196 llvm::Value *ivarVal = load;

1200 CGM.getPointerAuthInfoForType(getterMethod->getReturnType());

1202 TargetInfo, false);

1203 }

1204

1205

1206

1207

1209 uint64_t retTySize = CGM.getDataLayout().getTypeSizeInBits(retTy);

1210 if (ivarSize > retTySize) {

1211 bitcastType = llvm::Type::getIntNTy(getLLVMContext(), retTySize);

1212 ivarVal = Builder.CreateTrunc(ivarVal, bitcastType);

1213 }

1214 Builder.CreateStore(ivarVal, ReturnValue.withElementType(bitcastType));

1215

1216

1218 return;

1219 }

1220

1221 case PropertyImplStrategy::GetSetProperty: {

1222 llvm::FunctionCallee getPropertyFn =

1223 CGM.getObjCRuntime().GetPropertyGetFunction();

1224

1226

1227

1228

1229 CGM.ErrorUnsupported(propImpl,

1230 "Obj-C getter requiring pointer authentication");

1231 return;

1232 }

1233

1234 if (!getPropertyFn) {

1235 CGM.ErrorUnsupported(propImpl, "Obj-C getter requiring atomic copy");

1236 return;

1237 }

1239

1240

1241

1242

1245 llvm::Value *ivarOffset =

1247

1254

1255

1256

1257 llvm::CallBase *CallInstruction;

1259 getContext().getObjCIdType(), args),

1261 if (llvm::CallInst *call = dyn_castllvm::CallInst(CallInstruction))

1262 call->setTailCall();

1263

1264

1265

1266

1270

1271 EmitReturnOfRValue(RV, propType);

1272

1273

1275

1276 return;

1277 }

1278

1279 case PropertyImplStrategy::CopyStruct:

1281 strategy.hasStrongMember());

1282 return;

1283

1284 case PropertyImplStrategy::Expression:

1285 case PropertyImplStrategy::SetPropertyAndExpressionGet: {

1287

1291 switch (EvaluationKind) {

1295 true);

1296 return;

1297 }

1299

1300

1301

1304 return;

1305 }

1307 llvm::Value *value;

1310 CGM.ErrorUnsupported(propImpl,

1311 "Obj-C getter for authenticated reference type");

1312 return;

1313 }

1315 } else {

1316

1320 } else {

1322 }

1323

1324

1325

1326 } else {

1329 llvm::LoadInst *LoadInst = Builder.CreateLoad(ivarAddr, "load");

1330 llvm::Value *Load = LoadInst;

1333 CGM.getPointerAuthInfoForType(getterMethod->getReturnType());

1335 false);

1336 value = Load;

1337 } else

1339

1341 }

1342

1343 value = Builder.CreateBitCast(

1345 }

1346

1347 EmitReturnOfRValue(RValue::get(value), propType);

1348 return;

1349 }

1350 }

1351 llvm_unreachable("bad evaluation kind");

1352 }

1353

1354 }

1355 llvm_unreachable("bad @property implementation strategy!");

1356}

1357

1358

1359

1362

1363

1365

1366

1367 llvm::Value *ivarAddr =

1370 ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);

1372

1373

1380

1381

1382 llvm::Value *size =

1385

1386

1388

1389

1390

1392

1398}

1399

1400

1401

1402

1406 llvm::Constant *AtomicHelperFn) {

1407

1408

1410

1411

1412 llvm::Value *ivarAddr =

1416

1417

1424

1425

1427

1428 llvm::FunctionCallee fn =

1434}

1435

1436

1439 if (!setter) return true;

1440

1441

1442

1443

1444

1445

1446

1447

1448

1449 if (CallExpr *call = dyn_cast(setter)) {

1451 = dyn_cast_or_null(call->getCalleeDecl()))

1452 if (callee->isTrivial())

1453 return true;

1454 return false;

1455 }

1456

1458 return false;

1459}

1460

1466

1467void

1470 llvm::Constant *AtomicHelperFn) {

1473

1476 if (!AtomicHelperFn) {

1477

1478

1480 0);

1483 } else {

1484

1486 }

1487

1489 return;

1490 }

1491

1492

1493

1495 if (!AtomicHelperFn)

1496

1498 else

1499

1501 AtomicHelperFn);

1502 return;

1503 }

1504

1505 PropertyImplStrategy strategy(CGM, propImpl);

1506 switch (strategy.getKind()) {

1507 case PropertyImplStrategy::Native: {

1508

1509 if (strategy.getIvarSize().isZero())

1510 return;

1511

1513

1517

1518

1519

1520 llvm::Type *castType = llvm::Type::getIntNTy(

1522

1523

1526

1527 llvm::Value *load = Builder.CreateLoad(argAddr);

1528

1534 false);

1535 }

1536

1537

1538 llvm::StoreInst *store = Builder.CreateStore(load, ivarAddr);

1539 store->setAtomic(llvm::AtomicOrdering::Unordered);

1540 return;

1541 }

1542

1543 case PropertyImplStrategy::GetSetProperty:

1544 case PropertyImplStrategy::SetPropertyAndExpressionGet: {

1545

1546 llvm::FunctionCallee setOptimizedPropertyFn = nullptr;

1547 llvm::FunctionCallee setPropertyFn = nullptr;

1549

1550 setOptimizedPropertyFn =

1551 CGM.getObjCRuntime().GetOptimizedPropertySetFunction(

1552 strategy.isAtomic(), strategy.isCopy());

1553 if (!setOptimizedPropertyFn) {

1554 CGM.ErrorUnsupported(propImpl, "Obj-C optimized setter - NYI");

1555 return;

1556 }

1557 }

1558 else {

1559 setPropertyFn = CGM.getObjCRuntime().GetPropertySetFunction();

1560 if (!setPropertyFn) {

1561 CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy");

1562 return;

1563 }

1564 }

1565

1566

1567

1569 llvm::Value *self =

1571 llvm::Value *ivarOffset =

1574 llvm::Value *arg = Builder.CreateLoad(argAddr, "arg");

1576

1580 if (setOptimizedPropertyFn) {

1586 } else {

1593

1594

1598 }

1599

1600 return;

1601 }

1602

1603 case PropertyImplStrategy::CopyStruct:

1605 return;

1606

1607 case PropertyImplStrategy::Expression:

1608 break;

1609 }

1610

1611

1616 CK_LValueToRValue, &self, VK_PRValue,

1620 &selfLoad, true, true);

1621

1629

1630

1631

1632

1636 argCK = CK_BitCast;

1638 argCK = CK_BlockPointerToObjCPointerCast;

1639 else

1640 argCK = CK_CPointerToObjCPointerCast;

1643 argCK = CK_BitCast;

1644 else

1645 argCK = CK_AnyPointerToBlockPointerCast;

1647 argCK = CK_BitCast;

1650 argCK = CK_AtomicToNonAtomic;

1653 argCK = CK_NonAtomicToAtomic;

1654 }

1657 Expr *finalArg = &argLoad;

1660 finalArg = &argCast;

1661

1666}

1667

1668

1669

1670

1671

1674 llvm::Constant *AtomicHelperFn =

1675 CodeGenFunction(CGM).GenerateObjCAtomicSetterCopyHelperFunction(PID);

1677 assert(OMD && "Invalid call to generate setter (empty method)");

1679

1681

1683}

1684

1685namespace {

1686 struct DestroyIvar final : EHScopeStack::Cleanup {

1687 private:

1688 llvm::Value *addr;

1691 bool useEHCleanupForArray;

1692 public:

1693 DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,

1695 bool useEHCleanupForArray)

1696 : addr(addr), ivar(ivar), destroyer(destroyer),

1697 useEHCleanupForArray(useEHCleanupForArray) {}

1698

1703 flags.isForNormalCleanup() && useEHCleanupForArray);

1704 }

1705 };

1706}

1707

1708

1715

1719

1721

1726

1727

1729 if (!dtorKind) continue;

1730

1732

1733

1734

1737

1738

1739 } else {

1741 }

1742

1744

1745 CGF.EHStack.pushCleanup(cleanupKind, self, ivar, destroyer,

1747 }

1748

1749 assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");

1750}

1751

1754 bool ctor) {

1757

1758

1759 if (ctor) {

1760

1762

1763 for (const auto *IvarInit : IMP->inits()) {

1764 FieldDecl *Field = IvarInit->getAnyMember();

1773 }

1774

1776 QualType IdTy(CGM.getContext().getObjCIdType());

1777 llvm::Value *SelfAsId =

1779 EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);

1780

1781

1782 } else {

1784 }

1786}

1787

1795

1803

1805 llvm::FunctionCallee EnumerationMutationFnPtr =

1806 CGM.getObjCRuntime().EnumerationMutationFunction();

1807 if (!EnumerationMutationFnPtr) {

1808 CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");

1809 return;

1810 }

1811 CGCallee EnumerationMutationFn =

1813

1815 if (DI)

1817

1819

1820

1824

1826

1827

1828 QualType StateTy = CGM.getObjCFastEnumerationStateType();

1831

1832

1833 static const unsigned NumItems = 16;

1834

1835

1837 &CGM.getContext().Idents.get("countByEnumeratingWithState"),

1838 &CGM.getContext().Idents.get("objects"),

1839 &CGM.getContext().Idents.get("count")};

1841 CGM.getContext().Selectors.getSelector(std::size(II), &II[0]);

1842

1844 getContext().getObjCIdType(), llvm::APInt(32, NumItems), nullptr,

1847

1848

1849 llvm::Value *Collection;

1852

1853

1855 } else {

1857 }

1858

1859

1860

1862

1863

1865

1866

1868

1869

1870

1871

1872

1873

1875

1876

1878 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumItems);

1880

1881

1885 FastEnumSel, Collection, Args);

1886

1887

1888 llvm::Value *initialBufferLimit = CountRV.getScalarVal();

1889

1890 llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");

1891 llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");

1892

1893 llvm::Value *zero = llvm::Constant::getNullValue(NSUIntegerTy);

1894

1895

1896

1897

1900 Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"), EmptyBB,

1901 LoopInitBB,

1903

1904

1906

1907

1908

1909

1910 Address StateMutationsPtrPtr =

1911 Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");

1912 llvm::Value *StateMutationsPtr

1913 = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");

1914

1916 llvm::Value *initialMutations =

1917 Builder.CreateAlignedLoad(UnsignedLongTy, StateMutationsPtr,

1919

1920

1921

1922 llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");

1924

1925

1926 llvm::PHINode *index = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.index");

1927 index->addIncoming(zero, LoopInitBB);

1928

1929

1930 llvm::PHINode *count = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.count");

1931 count->addIncoming(initialBufferLimit, LoopInitBB);

1932

1934

1935

1936

1937

1938 StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");

1939 llvm::Value *currentMutations

1940 = Builder.CreateAlignedLoad(UnsignedLongTy, StateMutationsPtr,

1942

1943 llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");

1944 llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");

1945

1946 Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),

1947 WasNotMutatedBB, WasMutatedBB);

1948

1949

1952 llvm::Value *V =

1953 Builder.CreateBitCast(Collection, ObjCIdType);

1956

1957

1961

1962

1964

1965

1967 bool elementIsVariable;

1968 LValue elementLValue;

1971

1973

1977 elementLValue = EmitLValue(&tempDRE);

1978 elementType = D->getType();

1979 elementIsVariable = true;

1980

1983 } else {

1984 elementLValue = LValue();

1986 elementIsVariable = false;

1987 }

1988 llvm::Type *convertedElementType = ConvertType(elementType);

1989

1990

1991

1992

1994 Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");

1995 llvm::Value *EnumStateItems =

1996 Builder.CreateLoad(StateItemsPtr, "stateitems");

1997

1998

1999 llvm::Value *CurrentItemPtr = Builder.CreateInBoundsGEP(

2000 ObjCIdType, EnumStateItems, index, "currentitem.ptr");

2001 llvm::Value *CurrentItem =

2003

2004 if (SanOpts.has(SanitizerKind::ObjCCast)) {

2005

2006

2007

2008

2009

2014 if (InterfaceTy) {

2015 auto CheckOrdinal = SanitizerKind::SO_ObjCCast;

2016 auto CheckHandler = SanitizerHandler::InvalidObjCCast;

2018 auto &C = CGM.getContext();

2019 assert(InterfaceTy->getDecl() && "No decl for ObjC interface type");

2022 llvm::Value *Cls =

2023 CGM.getObjCRuntime().GetClass(*this, InterfaceTy->getDecl());

2024 IsKindOfClassArgs.add(RValue::get(Cls), C.getObjCClassType());

2025 llvm::Value *IsClass =

2026 CGM.getObjCRuntime()

2028 IsKindOfClassSel, CurrentItem,

2029 IsKindOfClassArgs)

2030 .getScalarVal();

2031 llvm::Constant *StaticData[] = {

2034 EmitCheck({{IsClass, CheckOrdinal}}, CheckHandler,

2036 }

2037 }

2038

2039

2040 CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,

2041 "currentitem");

2042

2043

2044

2045 if (!elementIsVariable) {

2048 } else {

2050 true);

2051 }

2052

2053

2054

2055 if (elementIsVariable)

2057

2058

2059 BreakContinueStack.push_back(BreakContinue(S, LoopEnd, AfterBody));

2060 {

2063 }

2064 BreakContinueStack.pop_back();

2065

2066

2068

2069

2071

2072 llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");

2073

2074

2075 llvm::Value *indexPlusOne =

2076 Builder.CreateNUWAdd(index, llvm::ConstantInt::get(NSUIntegerTy, 1));

2077

2078

2079

2080

2081

2083 Builder.CreateICmpULT(indexPlusOne, count), LoopBodyBB, FetchMoreBB,

2085

2086 index->addIncoming(indexPlusOne, AfterBody.getBlock());

2087 count->addIncoming(count, AfterBody.getBlock());

2088

2089

2091

2092 CountRV =

2095 FastEnumSel, Collection, Args);

2096

2097

2098 llvm::Value *refetchCount = CountRV.getScalarVal();

2099

2100

2101 index->addIncoming(zero, Builder.GetInsertBlock());

2102 count->addIncoming(refetchCount, Builder.GetInsertBlock());

2103

2104 Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),

2105 EmptyBB, LoopBodyBB);

2106

2107

2109

2110 if (!elementIsVariable) {

2111

2112

2113 llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);

2116 }

2117

2118 if (DI)

2120

2123}

2124

2126 CGM.getObjCRuntime().EmitTryStmt(*this, S);

2127}

2128

2130 CGM.getObjCRuntime().EmitThrowStmt(*this, S);

2131}

2132

2135 CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);

2136}

2137

2138namespace {

2139 struct CallObjCRelease final : EHScopeStack::Cleanup {

2140 CallObjCRelease(llvm::Value *object) : object(object) {}

2141 llvm::Value *object;

2142

2144

2146 }

2147 };

2148}

2149

2150

2151

2153 llvm::Value *object) {

2154

2155

2157 return object;

2158}

2159

2161 llvm::Value *value) {

2163}

2164

2165

2166

2168 llvm::Function *&fn = CGM.getObjCEntrypoints().clang_arc_use;

2169 if (!fn)

2170 fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_use);

2171

2172

2173

2175}

2176

2177

2178

2180 llvm::Function *&fn = CGM.getObjCEntrypoints().clang_arc_noop_use;

2181 if (!fn)

2182 fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_noop_use);

2184}

2185

2187 if (auto *F = dyn_castllvm::Function(RTF)) {

2188

2189

2190

2192 !CGM.getTriple().isOSBinFormatCOFF()) {

2193 F->setLinkage(llvm::Function::ExternalWeakLinkage);

2194 }

2195 }

2196}

2197

2199 llvm::FunctionCallee RTF) {

2201}

2202

2205 llvm::Function *fn = CGM.getIntrinsic(IntID);

2207 return fn;

2208}

2209

2210

2211

2212

2214 CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType,

2215 llvm::Function *&fn, llvm::Intrinsic::ID IntID,

2216 llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {

2218 return value;

2219

2220 if (!fn)

2222

2223

2224 llvm::Type *origType = returnType ? returnType : value->getType();

2226

2227

2229 call->setTailCallKind(tailKind);

2230

2231

2232 return CGF.Builder.CreateBitCast(call, origType);

2233}

2234

2235

2236

2238 llvm::Function *&fn,

2239 llvm::Intrinsic::ID IntID) {

2240 if (!fn)

2242

2244}

2245

2246

2247

2249 llvm::Value *value,

2250 llvm::Function *&fn,

2251 llvm::Intrinsic::ID IntID,

2252 bool ignored) {

2254

2255 if (!fn)

2257

2258 llvm::Type *origType = value->getType();

2259

2260 llvm::Value *args[] = {

2264

2265 if (ignored) return nullptr;

2266

2267 return CGF.Builder.CreateBitCast(result, origType);

2268}

2269

2270

2271

2273 llvm::Function *&fn,

2274 llvm::Intrinsic::ID IntID) {

2275 assert(dst.getType() == src.getType());

2276

2277 if (!fn)

2279

2280 llvm::Value *args[] = {

2284}

2285

2286

2287

2288

2290 llvm::Value *value,

2291 llvm::Type *returnType,

2292 llvm::FunctionCallee &fn,

2293 StringRef fnName) {

2295 return value;

2296

2297 if (!fn) {

2298 llvm::FunctionType *fnType =

2301

2302

2303 if (llvm::Function *f = dyn_castllvm::Function(fn.getCallee()))

2304 if (fnName == "objc_retain")

2305 f->addFnAttr(llvm::Attribute::NonLazyBind);

2306 }

2307

2308

2309 llvm::Type *origType = returnType ? returnType : value->getType();

2311

2312

2314

2315

2316

2317 if (fnName == "objc_autorelease")

2318 if (auto *Call = dyn_castllvm::CallInst(Inst))

2319 Call->setTailCall();

2320

2321

2322 return CGF.Builder.CreateBitCast(Inst, origType);

2323}

2324

2325

2326

2327

2329 if (type->isBlockPointerType())

2331 else

2333}

2334

2335

2336

2339 CGM.getObjCEntrypoints().objc_retain,

2340 llvm::Intrinsic::objc_retain);

2341}

2342

2343

2344

2345

2346

2347

2348

2350 bool mandatory) {

2351 llvm::Value *result

2353 CGM.getObjCEntrypoints().objc_retainBlock,

2354 llvm::Intrinsic::objc_retainBlock);

2355

2356

2357

2358

2359

2361 llvm::CallInst *call

2363 assert(call->getCalledOperand() ==

2364 CGM.getObjCEntrypoints().objc_retainBlock);

2365

2366 call->setMetadata("clang.arc.copy_on_escape",

2367 llvm::MDNode::get(Builder.getContext(), {}));

2368 }

2369

2370 return result;

2371}

2372

2374

2375

2376 llvm::InlineAsm *&marker

2378 if (!marker) {

2379 StringRef assembly

2382

2383

2384 if (assembly.empty()) {

2385

2386

2387

2389 llvm::FunctionType *type =

2390 llvm::FunctionType::get(CGF.VoidTy, false);

2391

2392 marker = llvm::InlineAsm::get(type, assembly, "", true);

2393

2394

2395

2396

2397 } else {

2398 const char *retainRVMarkerKey = llvm::objcarc::getRVMarkerModuleFlagStr();

2399 if (!CGF.CGM.getModule().getModuleFlag(retainRVMarkerKey)) {

2400 auto *str = llvm::MDString::get(CGF.getLLVMContext(), assembly);

2401 CGF.CGM.getModule().addModuleFlag(llvm::Module::Error,

2402 retainRVMarkerKey, str);

2403 }

2404 }

2405 }

2406

2407

2408 if (marker)

2410}

2411

2413 bool IsRetainRV,

2416

2417

2418

2419

2420

2422 llvm::Function *&EP = IsRetainRV

2425 llvm::Intrinsic::ID IID =

2426 IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue

2427 : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;

2429

2430 llvm::Triple::ArchType Arch = CGF.CGM.getTriple().getArch();

2431

2432

2433

2435 (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32 ||

2436 Arch == llvm::Triple::x86_64)) {

2437 llvm::Value *bundleArgs[] = {EP};

2438 llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs);

2440 llvm::CallBase *newCall = llvm::CallBase::addOperandBundle(

2441 oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB,

2442 oldCall->getIterator());

2443 newCall->copyMetadata(*oldCall);

2444 oldCall->replaceAllUsesWith(newCall);

2445 oldCall->eraseFromParent();

2447 return newCall;

2448 }

2449

2450 bool isNoTail =

2452 llvm::CallInst::TailCallKind tailKind =

2453 isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None;

2455}

2456

2457

2458

2459

2460

2461

2462llvm::Value *

2466

2467

2468

2469

2470

2471

2472

2473

2474llvm::Value *

2478

2479

2480

2484

2485 llvm::Function *&fn = CGM.getObjCEntrypoints().objc_release;

2486 if (!fn)

2488

2489

2491

2492

2494

2496 call->setMetadata("clang.imprecise_release",

2497 llvm::MDNode::get(Builder.getContext(), {}));

2498 }

2499}

2500

2501

2502

2503

2504

2505

2506

2507

2508

2509

2512 if (CGM.getCodeGenOpts().OptimizationLevel == 0) {

2515 return;

2516 }

2517

2518 llvm::Value *value = Builder.CreateLoad(addr);

2520}

2521

2522

2523

2525 llvm::Value *value,

2526 bool ignored) {

2528

2529 llvm::Function *&fn = CGM.getObjCEntrypoints().objc_storeStrong;

2530 if (!fn)

2532

2533 llvm::Value *args[] = {

2537

2538 if (ignored) return nullptr;

2539 return value;

2540}

2541

2542

2543

2544

2546 llvm::Value *newValue,

2547 bool ignored) {

2549 bool isBlock = type->isBlockPointerType();

2550

2551

2552

2554 !isBlock &&

2555 (dst.getAlignment().isZero() ||

2558 }

2559

2560

2561

2562

2564

2565

2567

2568

2569

2571

2572

2573 EmitARCRelease(oldValue, dst.isARCPreciseLifetime());

2574

2575 return newValue;

2576}

2577

2578

2579

2582 CGM.getObjCEntrypoints().objc_autorelease,

2583 llvm::Intrinsic::objc_autorelease);

2584}

2585

2586

2587

2588llvm::Value *

2591 CGM.getObjCEntrypoints().objc_autoreleaseReturnValue,

2592 llvm::Intrinsic::objc_autoreleaseReturnValue,

2593 llvm::CallInst::TCK_Tail);

2594}

2595

2596

2597

2598llvm::Value *

2601 CGM.getObjCEntrypoints().objc_retainAutoreleaseReturnValue,

2602 llvm::Intrinsic::objc_retainAutoreleaseReturnValue,

2603 llvm::CallInst::TCK_Tail);

2604}

2605

2606

2607

2608

2609

2610

2612 llvm::Value *value) {

2613 if (type->isBlockPointerType())

2615

2617

2618 llvm::Type *origType = value->getType();

2622 return Builder.CreateBitCast(value, origType);

2623}

2624

2625

2626

2627llvm::Value *

2630 CGM.getObjCEntrypoints().objc_retainAutorelease,

2631 llvm::Intrinsic::objc_retainAutorelease);

2632}

2633

2634

2635

2638 CGM.getObjCEntrypoints().objc_loadWeak,

2639 llvm::Intrinsic::objc_loadWeak);

2640}

2641

2642

2645 CGM.getObjCEntrypoints().objc_loadWeakRetained,

2646 llvm::Intrinsic::objc_loadWeakRetained);

2647}

2648

2649

2650

2652 llvm::Value *value,

2653 bool ignored) {

2655 CGM.getObjCEntrypoints().objc_storeWeak,

2656 llvm::Intrinsic::objc_storeWeak, ignored);

2657}

2658

2659

2660

2661

2662

2664

2665

2666

2667

2669 CGM.getCodeGenOpts().OptimizationLevel == 0) {

2670 Builder.CreateStore(value, addr);

2671 return;

2672 }

2673

2675 CGM.getObjCEntrypoints().objc_initWeak,

2676 llvm::Intrinsic::objc_initWeak, true);

2677}

2678

2679

2680

2682 llvm::Function *&fn = CGM.getObjCEntrypoints().objc_destroyWeak;

2683 if (!fn)

2685

2687}

2688

2689

2690

2691

2694 CGM.getObjCEntrypoints().objc_moveWeak,

2695 llvm::Intrinsic::objc_moveWeak);

2696}

2697

2698

2699

2700

2703 CGM.getObjCEntrypoints().objc_copyWeak,

2704 llvm::Intrinsic::objc_copyWeak);

2705}

2706

2713

2721

2722

2723

2725 llvm::Function *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush;

2726 if (!fn)

2727 fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush, CGM);

2728

2730}

2731

2732

2733

2735 assert(value->getType() == Int8PtrTy);

2736

2738

2739 llvm::FunctionCallee &fn =

2740 CGM.getObjCEntrypoints().objc_autoreleasePoolPopInvoke;

2741 if (!fn) {

2742 llvm::FunctionType *fnType =

2743 llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);

2744 fn = CGM.CreateRuntimeFunction(fnType, "objc_autoreleasePoolPop");

2746 }

2747

2748

2750 } else {

2751 llvm::FunctionCallee &fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop;

2752 if (!fn)

2753 fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop, CGM);

2754

2756 }

2757}

2758

2759

2760

2761

2762

2763

2767

2768 const IdentifierInfo *II = &CGM.getContext().Idents.get("alloc");

2774 AllocSel, Receiver, Args);

2775

2776

2778 II = &CGM.getContext().Idents.get("init");

2783 InitSel, Receiver, Args);

2785}

2786

2787

2788

2790 llvm::Type *resultType) {

2792 CGM.getObjCEntrypoints().objc_alloc,

2793 "objc_alloc");

2794}

2795

2796

2797

2799 llvm::Type *resultType) {

2801 CGM.getObjCEntrypoints().objc_allocWithZone,

2802 "objc_allocWithZone");

2803}

2804

2806 llvm::Type *resultType) {

2808 CGM.getObjCEntrypoints().objc_alloc_init,

2809 "objc_alloc_init");

2810}

2811

2812

2813

2821

2826}

2827

2832}

2833

2838}

2839

2841 QualType type) {

2844}

2845

2846

2847

2849 llvm::Type *returnType) {

2851 *this, value, returnType,

2852 CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction,

2853 "objc_autorelease");

2854}

2855

2856

2857

2859 llvm::Type *returnType) {

2861 *this, value, returnType,

2862 CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain");

2863}

2864

2865

2866

2870

2871 llvm::FunctionCallee &fn =

2872 CGM.getObjCEntrypoints().objc_releaseRuntimeFunction;

2873 if (!fn) {

2874 llvm::FunctionType *fnType =

2875 llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);

2876 fn = CGM.CreateRuntimeFunction(fnType, "objc_release");

2878

2879 if (llvm::Function *f = dyn_castllvm::Function(fn.getCallee()))

2880 f->addFnAttr(llvm::Attribute::NonLazyBind);

2881 }

2882

2883

2885

2886

2888

2890 call->setMetadata("clang.imprecise_release",

2891 llvm::MDNode::get(Builder.getContext(), {}));

2892 }

2893}

2894

2895namespace {

2896 struct CallObjCAutoreleasePoolObject final : EHScopeStack::Cleanup {

2897 llvm::Value *Token;

2898

2899 CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}

2900

2903 }

2904 };

2905 struct CallObjCMRRAutoreleasePoolObject final : EHScopeStack::Cleanup {

2906 llvm::Value *Token;

2907

2908 CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}

2909

2910 void Emit(CodeGenFunction &CGF, Flags flags) override {

2912 }

2913 };

2914}

2915

2917 if (CGM.getLangOpts().ObjCAutoRefCount)

2919 else

2921}

2922

2924 switch (lifetime) {

2929 return true;

2930

2932 return false;

2933 }

2934

2935 llvm_unreachable("impossible lifetime!");

2936}

2937

2939 LValue lvalue,

2941 llvm::Value *result;

2943 if (shouldRetain) {

2945 } else {

2948 }

2950}

2951

2953 const Expr *e) {

2956

2957

2958

2959

2961 type.isConstQualified() &&

2963

2965

2966

2969

2970

2972

2974 }

2975

2976

2977

2978

2980 type.isVolatileQualified() &&

2985

2986

2987

2988

2989 if (const auto *decl_expr = dyn_cast(e)) {

2990 auto *DRE = const_cast<DeclRefExpr *>(decl_expr);

2994 }

2995

2997}

2998

2999typedef llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,

3000 llvm::Value *value)>

3002

3003

3004

3005

3006

3008 llvm::Value *value,

3011 CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();

3012 auto *callBase = dyn_castllvm::CallBase(value);

3013

3014 if (callBase && llvm::objcarc::hasAttachedCallOpBundle(callBase)) {

3015

3016 value = doFallback(CGF, value);

3017 } else if (llvm::CallInst *call = dyn_castllvm::CallInst(value)) {

3018

3019 CGF.Builder.SetInsertPoint(call->getParent(),

3020 ++llvm::BasicBlock::iterator(call));

3021 value = doAfterCall(CGF, value);

3022 } else if (llvm::InvokeInst *invoke = dyn_castllvm::InvokeInst(value)) {

3023

3024 llvm::BasicBlock *BB = invoke->getNormalDest();

3025 CGF.Builder.SetInsertPoint(BB, BB->begin());

3026 value = doAfterCall(CGF, value);

3027

3028

3029

3030 } else if (llvm::BitCastInst *bitcast = dyn_castllvm::BitCastInst(value)) {

3031

3032

3033 CGF.Builder.SetInsertPoint(bitcast->getParent(), bitcast->getIterator());

3034 llvm::Value *operand = bitcast->getOperand(0);

3036 bitcast->setOperand(0, operand);

3037 value = bitcast;

3038 } else {

3039 auto *phi = dyn_castllvm::PHINode(value);

3040 if (phi && phi->getNumIncomingValues() == 2 &&

3043

3044

3045 llvm::Value *inVal = phi->getIncomingValue(0);

3047 phi->setIncomingValue(0, inVal);

3048 value = phi;

3049 } else {

3050

3051

3052

3053 value = doFallback(CGF, value);

3054 }

3055 }

3056

3057 CGF.Builder.restoreIP(ip);

3058 return value;

3059}

3060

3061

3062

3064 const Expr *e) {

3069 },

3072 });

3073}

3074

3075

3076

3078 const Expr *e) {

3083 },

3085 return value;

3086 });

3087}

3088

3090 bool allowUnsafeClaim) {

3091 if (allowUnsafeClaim &&

3092 CGM.getLangOpts().ObjCRuntime.hasARCUnsafeClaimAutoreleasedReturnValue()) {

3094 } else {

3097 }

3098}

3099

3100

3101

3102

3106

3107

3108

3110 return false;

3111

3112 if (const CastExpr *cast = dyn_cast(e)) {

3113 switch (cast->getCastKind()) {

3114

3115 case CK_LValueToRValue:

3116 case CK_ARCReclaimReturnedObject:

3117 case CK_ARCConsumeObject:

3118 case CK_ARCProduceObject:

3119 return false;

3120

3121

3122 case CK_NoOp:

3123 case CK_BitCast:

3125

3126

3127 case CK_AnyPointerToBlockPointerCast:

3128 default:

3129 return true;

3130 }

3131 }

3132

3133 return true;

3134}

3135

3136namespace {

3137

3138

3139template <typename Impl, typename Result> class ARCExprEmitter {

3140protected:

3141 CodeGenFunction &CGF;

3142 Impl &asImpl() { return *static_cast<Impl*>(this); }

3143

3144 ARCExprEmitter(CodeGenFunction &CGF) : CGF(CGF) {}

3145

3146public:

3147 Result visit(const Expr *e);

3149 Result visitPseudoObjectExpr(const PseudoObjectExpr *e);

3150 Result visitBlockExpr(const BlockExpr *e);

3151 Result visitBinaryOperator(const BinaryOperator *e);

3152 Result visitBinAssign(const BinaryOperator *e);

3153 Result visitBinAssignUnsafeUnretained(const BinaryOperator *e);

3154 Result visitBinAssignAutoreleasing(const BinaryOperator *e);

3155 Result visitBinAssignWeak(const BinaryOperator *e);

3156 Result visitBinAssignStrong(const BinaryOperator *e);

3157

3158

3159

3160

3161

3162

3163

3164

3165

3166

3167

3168};

3169}

3170

3171

3172

3173

3174template <typename Impl, typename Result>

3176ARCExprEmitter<Impl,Result>::visitPseudoObjectExpr(const PseudoObjectExpr *E) {

3177 SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques;

3178

3179

3181 assert(resultExpr);

3183

3186 const Expr *semantic = *i;

3187

3188

3189

3190 if (const OpaqueValueExpr *ov = dyn_cast(semantic)) {

3192 OVMA opaqueData;

3193

3194

3195

3196 if (ov == resultExpr) {

3197 assert(!OVMA::shouldBindAsLValue(ov));

3198 result = asImpl().visit(ov->getSourceExpr());

3199 opaqueData = OVMA::bind(CGF, ov,

3200 RValue::get(asImpl().getValueOfResult(result)));

3201

3202

3203 } else {

3204 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());

3205 }

3206 opaques.push_back(opaqueData);

3207

3208

3209

3210 } else if (semantic == resultExpr) {

3211 result = asImpl().visit(semantic);

3212

3213

3214 } else {

3215 CGF.EmitIgnoredExpr(semantic);

3216 }

3217 }

3218

3219

3221 opaque.unbind(CGF);

3222

3223 return result;

3224}

3225

3226template <typename Impl, typename Result>

3227Result ARCExprEmitter<Impl, Result>::visitBlockExpr(const BlockExpr *e) {

3228

3229 return asImpl().visitExpr(e);

3230}

3231

3232template <typename Impl, typename Result>

3233Result ARCExprEmitter<Impl,Result>::visitCastExpr(const CastExpr *e) {

3235

3236

3237 case CK_NoOp:

3238 return asImpl().visit(e->getSubExpr());

3239

3240

3241 case CK_CPointerToObjCPointerCast:

3242 case CK_BlockPointerToObjCPointerCast:

3243 case CK_AnyPointerToBlockPointerCast:

3244 case CK_BitCast: {

3245 llvm::Type *resultType = CGF.ConvertType(e->getType());

3248 return asImpl().emitBitCast(result, resultType);

3249 }

3250

3251

3252 case CK_LValueToRValue:

3253 return asImpl().visitLValueToRValue(e->getSubExpr());

3254 case CK_ARCConsumeObject:

3255 return asImpl().visitConsumeObject(e->getSubExpr());

3256 case CK_ARCExtendBlockObject:

3257 return asImpl().visitExtendBlockObject(e->getSubExpr());

3258 case CK_ARCReclaimReturnedObject:

3259 return asImpl().visitReclaimReturnedObject(e->getSubExpr());

3260

3261

3262 default:

3263 return asImpl().visitExpr(e);

3264 }

3265}

3266

3267template <typename Impl, typename Result>

3269ARCExprEmitter<Impl,Result>::visitBinaryOperator(const BinaryOperator *e) {

3271 case BO_Comma:

3272 CGF.EmitIgnoredExpr(e->getLHS());

3273 CGF.EnsureInsertPoint();

3274 return asImpl().visit(e->getRHS());

3275

3276 case BO_Assign:

3277 return asImpl().visitBinAssign(e);

3278

3279 default:

3280 return asImpl().visitExpr(e);

3281 }

3282}

3283

3284template <typename Impl, typename Result>

3285Result ARCExprEmitter<Impl,Result>::visitBinAssign(const BinaryOperator *e) {

3288 return asImpl().visitBinAssignUnsafeUnretained(e);

3289

3291 return asImpl().visitBinAssignWeak(e);

3292

3294 return asImpl().visitBinAssignAutoreleasing(e);

3295

3297 return asImpl().visitBinAssignStrong(e);

3298

3300 return asImpl().visitExpr(e);

3301 }

3302 llvm_unreachable("bad ObjC ownership qualifier");

3303}

3304

3305

3306

3307template <typename Impl, typename Result>

3308Result ARCExprEmitter<Impl,Result>::

3309 visitBinAssignUnsafeUnretained(const BinaryOperator *e) {

3310

3311

3312 Result result = asImpl().visit(e->getRHS());

3313

3314

3317 CGF.EmitStoreThroughLValue(RValue::get(asImpl().getValueOfResult(result)),

3318 lvalue);

3319

3320 return result;

3321}

3322

3323template <typename Impl, typename Result>

3325ARCExprEmitter<Impl,Result>::visitBinAssignAutoreleasing(const BinaryOperator *e) {

3326 return asImpl().visitExpr(e);

3327}

3328

3329template <typename Impl, typename Result>

3331ARCExprEmitter<Impl,Result>::visitBinAssignWeak(const BinaryOperator *e) {

3332 return asImpl().visitExpr(e);

3333}

3334

3335template <typename Impl, typename Result>

3337ARCExprEmitter<Impl,Result>::visitBinAssignStrong(const BinaryOperator *e) {

3338 return asImpl().visitExpr(e);

3339}

3340

3341

3342template <typename Impl, typename Result>

3343Result ARCExprEmitter<Impl,Result>::visit(const Expr *e) {

3344

3345

3346

3347

3349

3350

3352

3353

3354 if (const CastExpr *ce = dyn_cast(e)) {

3355 return asImpl().visitCastExpr(ce);

3356

3357

3358 } else if (auto op = dyn_cast(e)) {

3359 return asImpl().visitBinaryOperator(op);

3360

3361

3362

3363

3364

3365

3366

3370 return asImpl().visitCall(e);

3371

3372

3373 } else if (const PseudoObjectExpr *pseudo = dyn_cast(e)) {

3374 return asImpl().visitPseudoObjectExpr(pseudo);

3375 } else if (auto *be = dyn_cast(e))

3376 return asImpl().visitBlockExpr(be);

3377

3378 return asImpl().visitExpr(e);

3379}

3380

3381namespace {

3382

3383

3384struct ARCRetainExprEmitter :

3385 public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> {

3386

3387 ARCRetainExprEmitter(CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}

3388

3389 llvm::Value *getValueOfResult(TryEmitResult result) {

3390 return result.getPointer();

3391 }

3392

3394 llvm::Value *value = result.getPointer();

3395 value = CGF.Builder.CreateBitCast(value, resultType);

3396 result.setPointer(value);

3397 return result;

3398 }

3399

3400 TryEmitResult visitLValueToRValue(const Expr *e) {

3402 }

3403

3404

3405

3406 TryEmitResult visitConsumeObject(const Expr *e) {

3407 llvm::Value *result = CGF.EmitScalarExpr(e);

3409 }

3410

3411 TryEmitResult visitBlockExpr(const BlockExpr *e) {

3413

3414

3415 if (CGF.CGM.getCodeGenOpts().ObjCAvoidHeapifyLocalBlocks &&

3417 result.setInt(true);

3418 return result;

3419 }

3420

3421

3422

3423

3424 TryEmitResult visitExtendBlockObject(const Expr *e) {

3425 llvm::Value *result;

3426

3427

3428

3430 result = CGF.EmitScalarExpr(e);

3431

3432

3433 } else {

3435

3436

3437 if (subresult.getInt()) {

3438 return subresult;

3439 }

3440

3441

3442 result = subresult.getPointer();

3443 }

3444

3445

3446 result = CGF.EmitARCRetainBlock(result, true);

3448 }

3449

3450

3451

3452 TryEmitResult visitReclaimReturnedObject(const Expr *e) {

3455 }

3456

3457

3461 }

3462

3463

3464

3466

3467

3468 llvm::Value *result = CGF.EmitScalarExpr(e);

3470 }

3471};

3472}

3473

3476 return ARCRetainExprEmitter(CGF).visit(e);

3477}

3478

3480 LValue lvalue,

3483 llvm::Value *value = result.getPointer();

3484 if (!result.getInt())

3486 return value;

3487}

3488

3489

3490

3491

3492

3494

3495 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {

3498 }

3499

3501 llvm::Value *value = result.getPointer();

3502 if (!result.getInt())

3504 return value;

3505}

3506

3507llvm::Value *

3509

3510 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {

3513 }

3514

3516 llvm::Value *value = result.getPointer();

3517 if (result.getInt())

3519 else

3521 return value;

3522}

3523

3525 llvm::Value *result;

3526 bool doRetain;

3527

3530 doRetain = true;

3531 } else {

3533 result = subresult.getPointer();

3534 doRetain = !subresult.getInt();

3535 }

3536

3537 if (doRetain)

3540}

3541

3543

3545

3546

3548 }

3549

3550

3551

3552

3553

3554

3556}

3557

3558namespace {

3559

3560

3561struct ARCUnsafeUnretainedExprEmitter :

3562 public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> {

3563

3564 ARCUnsafeUnretainedExprEmitter(CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}

3565

3566 llvm::Value *getValueOfResult(llvm::Value *value) {

3567 return value;

3568 }

3569

3570 llvm::Value *emitBitCast(llvm::Value *value, llvm::Type *resultType) {

3571 return CGF.Builder.CreateBitCast(value, resultType);

3572 }

3573

3574 llvm::Value *visitLValueToRValue(const Expr *e) {

3575 return CGF.EmitScalarExpr(e);

3576 }

3577

3578

3579

3580 llvm::Value *visitConsumeObject(const Expr *e) {

3581 llvm::Value *value = CGF.EmitScalarExpr(e);

3582 return CGF.EmitObjCConsumeObject(e->getType(), value);

3583 }

3584

3585

3586

3587 llvm::Value *visitExtendBlockObject(const Expr *e) {

3588 return CGF.EmitARCExtendBlockObject(e);

3589 }

3590

3591

3592 llvm::Value *visitReclaimReturnedObject(const Expr *e) {

3593 return CGF.EmitARCReclaimReturnedObject(e, true);

3594 }

3595

3596

3597

3598 llvm::Value *visitCall(const Expr *e) {

3599 return CGF.EmitScalarExpr(e);

3600 }

3601

3602

3603 llvm::Value *visitExpr(const Expr *e) {

3604 return CGF.EmitScalarExpr(e);

3605 }

3606};

3607}

3608

3610 const Expr *e) {

3611 return ARCUnsafeUnretainedExprEmitter(CGF).visit(e);

3612}

3613

3614

3615

3616

3617

3619

3620 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {

3623 }

3624

3626}

3627

3628std::pair<LValue,llvm::Value*>

3630 bool ignored) {

3631

3632

3633 llvm::Value *value;

3634 if (ignored) {

3636 } else {

3638 }

3639

3640

3643

3644 return std::pair<LValue,llvm::Value*>(std::move(lvalue), value);

3645}

3646

3647std::pair<LValue,llvm::Value*>

3649 bool ignored) {

3650

3652 llvm::Value *value = result.getPointer();

3653

3654 bool hasImmediateRetain = result.getInt();

3655

3656

3657

3658

3661 hasImmediateRetain = true;

3662 }

3663

3665

3666

3667 if (hasImmediateRetain) {

3671 } else {

3673 }

3674

3675 return std::pair<LValue,llvm::Value*>(lvalue, value);

3676}

3677

3678std::pair<LValue,llvm::Value*>

3682

3684

3685 return std::pair<LValue,llvm::Value*>(lvalue, value);

3686}

3687

3692

3694 if (DI)

3696

3697

3699 if (CGM.getLangOpts().ObjCRuntime.hasNativeARC()) {

3702 } else {

3704 EHStack.pushCleanup(NormalCleanup, token);

3705 }

3706

3707 for (const auto *I : S.body())

3709

3710 if (DI)

3712}

3713

3714

3715

3717

3718 llvm::FunctionType *extenderType

3720 llvm::InlineAsm *extender = llvm::InlineAsm::get(extenderType,

3721 "",

3722 "r",

3723 true);

3724

3726}

3727

3728

3729

3730

3731

3732llvm::Constant *

3737 return nullptr;

3738

3741

3743

3744

3745 CharUnits Alignment = C.getTypeAlignInChars(Ty);

3748 return Fn;

3749 }

3750

3753 return nullptr;

3755 return nullptr;

3756 llvm::Constant *HelperFn = nullptr;

3758 return nullptr;

3760 if ((HelperFn = CGM.getAtomicSetterHelperFnMap(Ty)))

3761 return HelperFn;

3762

3764 &CGM.getContext().Idents.get("__assign_helper_atomic_property_");

3765

3767 QualType DestTy = C.getPointerType(Ty);

3770 SrcTy = C.getPointerType(SrcTy);

3771

3773 ArgTys.push_back(DestTy);

3774 ArgTys.push_back(SrcTy);

3775 QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});

3776

3779 FunctionTy, nullptr, SC_Static, false, false, false);

3780

3786 nullptr);

3787 args.push_back(Params[0] = DstDecl);

3791 nullptr);

3792 args.push_back(Params[1] = SrcDecl);

3793 FD->setParams(Params);

3794

3796 CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);

3797

3798 llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);

3799

3800 llvm::Function *Fn =

3801 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,

3802 "__assign_helper_atomic_property_",

3803 &CGM.getModule());

3804

3805 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);

3806

3808

3813

3818

3819 Expr *Args[2] = {DST, SRC};

3824

3826

3828 HelperFn = Fn;

3829 CGM.setAtomicSetterHelperFnMap(Ty, HelperFn);

3830 return HelperFn;

3831}

3832

3837 return nullptr;

3838

3841

3843 CharUnits Alignment = C.getTypeAlignInChars(Ty);

3846 return Fn;

3847 }

3848

3851 return nullptr;

3853 return nullptr;

3854 llvm::Constant *HelperFn = nullptr;

3856 return nullptr;

3858 if ((HelperFn = CGM.getAtomicGetterHelperFnMap(Ty)))

3859 return HelperFn;

3860

3862 &CGM.getContext().Idents.get("__copy_helper_atomic_property_");

3863

3865 QualType DestTy = C.getPointerType(Ty);

3868 SrcTy = C.getPointerType(SrcTy);

3869

3871 ArgTys.push_back(DestTy);

3872 ArgTys.push_back(SrcTy);

3873 QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});

3874

3877 FunctionTy, nullptr, SC_Static, false, false, false);

3878

3884 nullptr);

3885 args.push_back(Params[0] = DstDecl);

3889 nullptr);

3890 args.push_back(Params[1] = SrcDecl);

3891 FD->setParams(Params);

3892

3894 CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);

3895

3896 llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);

3897

3898 llvm::Function *Fn = llvm::Function::Create(

3899 LTy, llvm::GlobalValue::InternalLinkage, "__copy_helper_atomic_property_",

3900 &CGM.getModule());

3901

3902 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);

3903

3905

3908

3912

3915

3917 ConstructorArgs.push_back(SRC);

3918 ConstructorArgs.append(std::next(CXXConstExpr->arg_begin()),

3919 CXXConstExpr->arg_end());

3920

3925 ConstructorArgs,

3932

3935

3945

3947 HelperFn = Fn;

3948 CGM.setAtomicGetterHelperFnMap(Ty, HelperFn);

3949 return HelperFn;

3950}

3951

3952llvm::Value *

3954

3959 Selector AutoreleaseSelector =

3961

3962

3964 llvm::Value *Val = Block;

3967 Ty, CopySelector,

3969 Val = Result.getScalarVal();

3971 Ty, AutoreleaseSelector,

3973 Val = Result.getScalarVal();

3974 return Val;

3975}

3976

3978 switch (TT.getOS()) {

3979 case llvm::Triple::Darwin:

3980 case llvm::Triple::MacOSX:

3981 return llvm::MachO::PLATFORM_MACOS;

3982 case llvm::Triple::IOS:

3983 return llvm::MachO::PLATFORM_IOS;

3984 case llvm::Triple::TvOS:

3985 return llvm::MachO::PLATFORM_TVOS;

3986 case llvm::Triple::WatchOS:

3987 return llvm::MachO::PLATFORM_WATCHOS;

3988 case llvm::Triple::XROS:

3989 return llvm::MachO::PLATFORM_XROS;

3990 case llvm::Triple::DriverKit:

3991 return llvm::MachO::PLATFORM_DRIVERKIT;

3992 default:

3993 return llvm::MachO::PLATFORM_UNKNOWN;

3994 }

3995}

3996

3998 const VersionTuple &Version) {

4000

4001

4002

4004

4005 auto EmitArgs = [&](const VersionTuple &Version, const llvm::Triple &TT) {

4006 std::optional Min = Version.getMinor(),

4007 SMin = Version.getSubminor();

4008 Args.push_back(

4010 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, Version.getMajor()));

4011 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, Min.value_or(0)));

4012 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, SMin.value_or(0)));

4013 };

4014

4015 assert(!Version.empty() && "unexpected empty version");

4017

4019 llvm::FunctionType *FTy = llvm::FunctionType::get(

4020 CGM.Int32Ty, {CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty},

4021 false);

4024 }

4025

4026 llvm::Value *Check =

4028 return CGF.Builder.CreateICmpNE(Check,

4029 llvm::Constant::getNullValue(CGM.Int32Ty));

4030}

4031

4032llvm::Value *

4034

4035 if (CGM.getTarget().getTriple().isOSDarwin())

4037

4038 if (CGM.IsOSVersionAtLeastFn) {

4039 llvm::FunctionType *FTy =

4041 CGM.IsOSVersionAtLeastFn =

4042 CGM.CreateRuntimeFunction(FTy, "__isOSVersionAtLeast");

4043 }

4044

4045 std::optional Min = Version.getMinor(),

4046 SMin = Version.getSubminor();

4047 llvm::Value *Args[] = {

4048 llvm::ConstantInt::get(CGM.Int32Ty, Version.getMajor()),

4049 llvm::ConstantInt::get(CGM.Int32Ty, Min.value_or(0)),

4050 llvm::ConstantInt::get(CGM.Int32Ty, SMin.value_or(0))};

4051

4052 llvm::Value *CallRes =

4054

4055 return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(Int32Ty));

4056}

4057

4059 const llvm::Triple &TT, const VersionTuple &TargetVersion) {

4060 VersionTuple FoundationDroppedInVersion;

4061 switch (TT.getOS()) {

4062 case llvm::Triple::IOS:

4063 case llvm::Triple::TvOS:

4064 FoundationDroppedInVersion = VersionTuple(13);

4065 break;

4066 case llvm::Triple::WatchOS:

4067 FoundationDroppedInVersion = VersionTuple(6);

4068 break;

4069 case llvm::Triple::Darwin:

4070 case llvm::Triple::MacOSX:

4071 FoundationDroppedInVersion = VersionTuple(10, 15);

4072 break;

4073 case llvm::Triple::XROS:

4074

4075 return false;

4076 case llvm::Triple::DriverKit:

4077

4078 return false;

4079 default:

4080 llvm_unreachable("Unexpected OS");

4081 }

4082 return TargetVersion < FoundationDroppedInVersion;

4083}

4084

4085void CodeGenModule::emitAtAvailableLinkGuard() {

4087 return;

4088

4089 if (!Target.getTriple().isOSDarwin())

4090 return;

4091

4092

4094 Target.getTriple(), Target.getPlatformMinVersion()))

4095 return;

4096

4097

4098

4099

4101 llvm::Metadata *Args[2] = {llvm::MDString::get(Context, "-framework"),

4102 llvm::MDString::get(Context, "CoreFoundation")};

4103 LinkerOptionsMetadata.push_back(llvm::MDNode::get(Context, Args));

4104

4105

4106 llvm::FunctionType *FTy =

4108 llvm::FunctionCallee CFFunc =

4110

4111 llvm::FunctionType *CheckFTy = llvm::FunctionType::get(VoidTy, {}, false);

4113 CheckFTy, "__clang_at_available_requires_core_foundation_framework",

4114 llvm::AttributeList(), true);

4115 llvm::Function *CFLinkCheckFunc =

4117 if (CFLinkCheckFunc->empty()) {

4118 CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);

4119 CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);

4120 CodeGenFunction CGF(*this);

4121 CGF.Builder.SetInsertPoint(CGF.createBasicBlock("", CFLinkCheckFunc));

4122 CGF.EmitNounwindRuntimeCall(CFFunc,

4123 llvm::Constant::getNullValue(VoidPtrTy));

4124 CGF.Builder.CreateUnreachable();

4126 }

4127}

4128

Defines the clang::ASTContext interface.

Defines the Diagnostic-related interfaces.

static llvm::Value * emitARCUnsafeClaimCallResult(CodeGenFunction &CGF, const Expr *e)

Given that the given expression is some sort of call (which does not return retained),...

Definition CGObjC.cpp:3077

static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl)

Definition CGObjC.cpp:1062

static bool shouldRetainObjCLifetime(Qualifiers::ObjCLifetime lifetime)

Definition CGObjC.cpp:2923

static bool shouldEmitSeparateBlockRetain(const Expr *e)

Determine whether it might be important to emit a separate objc_retain_block on the result of the giv...

Definition CGObjC.cpp:3103

static std::optional< llvm::Value * > tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME)

Instead of '[[MyClass alloc] init]', try to generate 'objc_alloc_init(MyClass)'.

Definition CGObjC.cpp:525

static llvm::Value * emitObjCValueOperation(CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, llvm::FunctionCallee &fn, StringRef fnName)

Perform an operation having the signature i8* (i8*) where a null input causes a no-op and returns nul...

Definition CGObjC.cpp:2289

llvm::function_ref< llvm::Value *(CodeGenFunction &CGF, llvm::Value *value)> ValueTransform

Definition CGObjC.cpp:3001

static llvm::Value * emitARCUnsafeUnretainedScalarExpr(CodeGenFunction &CGF, const Expr *e)

Definition CGObjC.cpp:3609

static llvm::Value * emitARCLoadOperation(CodeGenFunction &CGF, Address addr, llvm::Function *&fn, llvm::Intrinsic::ID IntID)

Perform an operation having the following signature: i8* (i8**)

Definition CGObjC.cpp:2237

static llvm::Constant * getNullForVariable(Address addr)

Given the address of a variable of pointer type, find the correct null to store into it.

Definition CGObjC.cpp:45

static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF)

Definition CGObjC.cpp:2373

static const Expr * findWeakLValue(const Expr *E)

Given an expression of ObjC pointer type, check whether it was immediately loaded from an ARC __weak ...

Definition CGObjC.cpp:350

llvm::PointerIntPair< llvm::Value *, 1, bool > TryEmitResult

Definition CGObjC.cpp:36

static bool hasUnalignedAtomics(llvm::Triple::ArchType arch)

Determine whether the given architecture supports unaligned atomic accesses.

Definition CGObjC.cpp:848

static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, llvm::Function *&fn, llvm::Intrinsic::ID IntID)

Perform an operation having the following signature: void (i8**, i8**)

Definition CGObjC.cpp:2272

static void AppendFirstImpliedRuntimeProtocols(const ObjCProtocolDecl *PD, llvm::UniqueVector< const ObjCProtocolDecl * > &PDs)

Definition CGObjC.cpp:452

static TryEmitResult tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e)

Definition CGObjC.cpp:3475

static llvm::Value * emitOptimizedARCReturnCall(llvm::Value *value, bool IsRetainRV, CodeGenFunction &CGF)

Definition CGObjC.cpp:2412

static llvm::Value * emitCmdValueForGetterSetterBody(CodeGenFunction &CGF, ObjCMethodDecl *MD)

Definition CGObjC.cpp:1121

static llvm::Function * getARCIntrinsic(llvm::Intrinsic::ID IntID, CodeGenModule &CGM)

Definition CGObjC.cpp:2203

static bool isFoundationNeededForDarwinAvailabilityCheck(const llvm::Triple &TT, const VersionTuple &TargetVersion)

Definition CGObjC.cpp:4058

static bool shouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message)

Decide whether to extend the lifetime of the receiver of a returns-inner-pointer message.

Definition CGObjC.cpp:291

static llvm::Value * emitARCStoreOperation(CodeGenFunction &CGF, Address addr, llvm::Value *value, llvm::Function *&fn, llvm::Intrinsic::ID IntID, bool ignored)

Perform an operation having the following signature: i8* (i8**, i8*)

Definition CGObjC.cpp:2248

static unsigned getBaseMachOPlatformID(const llvm::Triple &TT)

Definition CGObjC.cpp:3977

static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, LValue lvalue, QualType type)

Definition CGObjC.cpp:2938

static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF)

Definition CGObjC.cpp:2186

static std::optional< llvm::Value * > tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType, llvm::Value *Receiver, const CallArgList &Args, Selector Sel, const ObjCMethodDecl *method, bool isClassMessage)

The ObjC runtime may provide entrypoints that are likely to be faster than an ordinary message send o...

Definition CGObjC.cpp:377

static CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM, llvm::Triple::ArchType arch)

Return the maximum size that permits atomic accesses for the given architecture.

Definition CGObjC.cpp:856

static llvm::Value * emitARCRetainCallResult(CodeGenFunction &CGF, const Expr *e)

Given that the given expression is some sort of call (which does not return retained),...

Definition CGObjC.cpp:3063

static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF, llvm::Value *returnAddr, ObjCIvarDecl *ivar, llvm::Constant *AtomicHelperFn)

emitCPPObjectAtomicGetterCall - Call the runtime function to copy the ivar into the resturn slot.

Definition CGObjC.cpp:1087

static llvm::Value * emitIsPlatformVersionAtLeast(CodeGenFunction &CGF, const VersionTuple &Version)

Definition CGObjC.cpp:3997

static void destroyARCStrongWithStore(CodeGenFunction &CGF, Address addr, QualType type)

Like CodeGenFunction::destroyARCStrong, but do it with a call.

Definition CGObjC.cpp:1709

static llvm::Value * emitARCRetainLoadOfScalar(CodeGenFunction &CGF, LValue lvalue, QualType type)

Definition CGObjC.cpp:3479

static void emitCXXDestructMethod(CodeGenFunction &CGF, ObjCImplementationDecl *impl)

Definition CGObjC.cpp:1716

static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, bool isAtomic, bool hasStrong)

emitStructGetterCall - Call the runtime function to load a property into the return value slot.

Definition CGObjC.cpp:818

static llvm::Value * emitARCValueOperation(CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, llvm::Function *&fn, llvm::Intrinsic::ID IntID, llvm::CallInst::TailCallKind tailKind=llvm::CallInst::TCK_None)

Perform an operation having the signature i8* (i8*) where a null input causes a no-op and returns nul...

Definition CGObjC.cpp:2213

static llvm::Value * emitARCOperationAfterCall(CodeGenFunction &CGF, llvm::Value *value, ValueTransform doAfterCall, ValueTransform doFallback)

Insert code immediately after a call.

Definition CGObjC.cpp:3007

static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar)

emitStructSetterCall - Call the runtime function to store the value from the first formal parameter i...

Definition CGObjC.cpp:1360

static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar, llvm::Constant *AtomicHelperFn)

emitCPPObjectAtomicSetterCall - Call the runtime function to store the value from the first formal pa...

Definition CGObjC.cpp:1403

static RValue AdjustObjCObjectType(CodeGenFunction &CGF, QualType ET, RValue Result)

Adjust the type of an Objective-C object that doesn't match up due to type erasure at various points,...

Definition CGObjC.cpp:273

static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID)

Definition CGObjC.cpp:1437

static bool UseOptimizedSetter(CodeGenModule &CGM)

Definition CGObjC.cpp:1461

static Decl::Kind getKind(const Decl *D)

Defines the Objective-C statement AST node classes.

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

CharUnits getTypeAlignInChars(QualType T) const

Return the ABI-specified alignment of a (complete) type T, in characters.

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.

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

Qualifiers::GC getObjCGCAttrKind(QualType Ty) const

Return one of the GCNone, Weak or Strong Objective-C garbage collection attributes.

QualType getObjCSelType() const

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

TypeInfoChars getTypeInfoInChars(const Type *T) const

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

QualType getSizeType() const

Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.

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

static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)

bool canAvoidCopyToHeap() const

const BlockDecl * getBlockDecl() const

Represents a call to a C++ constructor.

bool isElidable() const

Whether this construction is elidable.

bool hadMultipleCandidates() const

Whether the referred constructor was resolved from an overloaded set having size greater than 1.

static CXXConstructExpr * Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor, bool Elidable, ArrayRef< Expr * > Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool ZeroInitialization, CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange)

Create a C++ construction expression.

bool isStdInitListInitialization() const

Whether this constructor call was written as list-initialization, but was interpreted as forming a st...

bool requiresZeroInitialization() const

Whether this construction first requires zero-initialization before the initializer is called.

CXXConstructorDecl * getConstructor() const

Get the constructor that this expression will (ultimately) call.

bool isListInitialization() const

Whether this constructor call was written as list-initialization.

CXXConstructionKind getConstructionKind() const

Determine whether this constructor is actually constructing a base class (rather than a complete obje...

A call to an overloaded operator written using operator syntax.

static CXXOperatorCallExpr * Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, ADLCallKind UsesADL=NotADL)

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

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

CastKind getCastKind() const

CharUnits - This is an opaque type for sizes expressed in character units.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

llvm::Value * emitRawPointer(CodeGenFunction &CGF) const

Return the pointer contained in this class after authenticating it and adding offset to it if necessa...

llvm::Type * getElementType() const

Return the type of the values stored in this address.

Address withElementType(llvm::Type *ElemTy) const

Return address with different element type, but same pointer and alignment.

llvm::PointerType * getType() const

Return the type of the pointer value.

static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)

static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)

forAddr - Make a slot for an aggregate value.

llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")

All available information about a concrete callee.

static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())

This class gathers all debug information during compilation and is responsible for emitting to llvm g...

void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)

Emit metadata to indicate the end of a new lexical block and pop the current block.

void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)

Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.

CGFunctionInfo - Class to encapsulate the information about a function definition.

Implements runtime-specific code generation functions.

virtual ~CGObjCRuntime()

Definition CGObjC.cpp:4129

virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0

API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.

virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0

API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.

virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0

Generate an Objective-C message send operation.

CodeGen::RValue GeneratePossiblySpecializedMessageSend(CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &Args, const ObjCInterfaceDecl *OID, const ObjCMethodDecl *Method, bool isClassMessage)

Generate an Objective-C message send operation.

Definition CGObjC.cpp:438

virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0

Generate an Objective-C message send operation to the super class initiated in a method for Class and...

virtual llvm::FunctionCallee GetGetStructFunction()=0

virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0

GetClass - Return a reference to the class for the given interface decl.

virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)

virtual llvm::FunctionCallee GetSetStructFunction()=0

std::vector< const ObjCProtocolDecl * > GetRuntimeProtocolList(ObjCProtocolDecl::protocol_iterator begin, ObjCProtocolDecl::protocol_iterator end)

Walk the list of protocol references from a class, category or protocol to traverse the DAG formed fr...

Definition CGObjC.cpp:466

CallArgList - Type for representing both the value and type of arguments in a call.

void add(RValue rvalue, QualType type)

An abstract representation of regular/ObjC call/message targets.

static AutoVarEmission invalid()

A non-RAII class containing all the information about a bound opaque value.

Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.

void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})

Force the emission of cleanups now, instead of waiting until this object is destroyed.

bool requiresCleanups() const

Determine whether this scope requires any cleanups.

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)

Produce the code for a CK_ARCConsumeObject.

Definition CGObjC.cpp:2152

GlobalDecl CurGD

CurGD - The GlobalDecl for the current function being compiled.

llvm::Value * EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType)

Autorelease the given object.

Definition CGObjC.cpp:2848

RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())

Definition CGObjC.cpp:573

void EmitARCMoveWeak(Address dst, Address src)

void @objc_moveWeak(i8** dest, i8** src) Disregards the current value in dest.

Definition CGObjC.cpp:2692

llvm::Value * EmitARCRetainAutoreleaseReturnValue(llvm::Value *value)

Do a fused retain/autorelease of the given object.

Definition CGObjC.cpp:2599

void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)

emitDestroy - Immediately perform the destruction of the given object.

JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)

The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...

llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)

Definition CGObjC.cpp:3089

std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)

Definition CGObjC.cpp:3679

llvm::Value * EmitARCUnsafeUnretainedScalarExpr(const Expr *expr)

EmitARCUnsafeUnretainedScalarExpr - Semantically equivalent to immediately releasing the resut of Emi...

Definition CGObjC.cpp:3618

llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)

Emit a selector.

Definition CGObjC.cpp:257

SanitizerSet SanOpts

Sanitizers enabled for this function.

void EmitNullInitialization(Address DestPtr, QualType Ty)

EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...

void EmitARCInitWeak(Address addr, llvm::Value *value)

i8* @objc_initWeak(i8** addr, i8* value) Returns value.

Definition CGObjC.cpp:2663

llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)

Definition CGObjC.cpp:251

llvm::Type * ConvertType(QualType T)

static Destroyer destroyARCWeak

llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)

Definition CGObjC.cpp:265

llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")

Emits a call or invoke instruction to the given function, depending on the current state of the EH st...

llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")

Emits a call or invoke instruction to the given runtime function.

ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)

EmitLoadOfComplex - Load a complex number from the specified l-value.

llvm::Value * EmitARCAutoreleaseReturnValue(llvm::Value *value)

Autorelease the given object.

Definition CGObjC.cpp:2589

llvm::Value * EmitARCRetain(QualType type, llvm::Value *value)

Produce the code to do a retain.

Definition CGObjC.cpp:2328

CleanupKind getARCCleanupKind()

Retrieves the default cleanup kind for an ARC cleanup.

llvm::Value * EmitARCAutorelease(llvm::Value *value)

Autorelease the given object.

Definition CGObjC.cpp:2580

llvm::Value * EmitARCRetainAutoreleaseScalarExpr(const Expr *expr)

Definition CGObjC.cpp:3508

bool shouldUseFusedARCCalls()

void EmitARCDestroyWeak(Address addr)

void @objc_destroyWeak(i8** addr) Essentially objc_storeWeak(addr, nil).

Definition CGObjC.cpp:2681

void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)

Release the given object.

Definition CGObjC.cpp:2867

llvm::Value * EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType)

Definition CGObjC.cpp:2805

void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)

Definition CGObjC.cpp:2129

llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)

Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...

void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)

Definition CGObjC.cpp:2916

void EmitAutoVarInit(const AutoVarEmission &emission)

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)

Definition CGObjC.cpp:247

const LangOptions & getLangOpts() const

llvm::Value * EmitARCRetainAutorelease(QualType type, llvm::Value *value)

Do a fused retain/autorelease of the given object.

Definition CGObjC.cpp:2611

llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)

Store into a strong object.

Definition CGObjC.cpp:2545

llvm::Value * EmitARCRetainAutoreleasedReturnValue(llvm::Value *value)

Retain the given object which is the result of a function call.

Definition CGObjC.cpp:2463

void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD)

StartObjCMethod - Begin emission of an ObjCMethod.

Definition CGObjC.cpp:752

LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)

EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.

llvm::Value * EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value)

Claim a possibly-autoreleased return value at +0.

Definition CGObjC.cpp:2475

llvm::Value * EmitObjCMRRAutoreleasePoolPush()

Produce the code to do an MRR version objc_autoreleasepool_push.

Definition CGObjC.cpp:2764

LValue EmitLValueForIvar(QualType ObjectTy, llvm::Value *Base, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)

void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, ObjCMethodDecl *MD, bool ctor)

Definition CGObjC.cpp:1752

llvm::Value * EmitObjCAllocWithZone(llvm::Value *value, llvm::Type *returnType)

Allocate the given objc object.

Definition CGObjC.cpp:2798

@ TCK_Store

Checking the destination of a store. Must be suitably sized and aligned.

llvm::Value * EmitObjCThrowOperand(const Expr *expr)

Definition CGObjC.cpp:3542

const Decl * CurCodeDecl

CurCodeDecl - This is the inner-most code context, which includes blocks.

Destroyer * getDestroyer(QualType::DestructionKind destructionKind)

llvm::AssertingVH< llvm::Instruction > AllocaInsertPt

AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...

void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)

Release the given object.

Definition CGObjC.cpp:2481

std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)

Definition CGObjC.cpp:3629

llvm::Constant * EmitCheckTypeDescriptor(QualType T)

Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.

void GenerateObjCGetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID)

GenerateObjCGetter - Synthesize an Objective-C property getter function.

Definition CGObjC.cpp:1049

llvm::Value * EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)

void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)

EmitAggregateCopy - Emit an aggregate copy.

Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())

llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)

Definition CGObjC.cpp:3953

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...

void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)

Destroy a __strong variable.

Definition CGObjC.cpp:2510

void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)

DeactivateCleanupBlock - Deactivates the given cleanup block.

void pushFullExprCleanup(CleanupKind kind, As... A)

pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.

QualType TypeOfSelfObject()

TypeOfSelfObject - Return type of object that this self represents.

Definition CGObjC.cpp:1796

static Destroyer destroyARCStrongImprecise

void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)

Definition CGObjC.cpp:3688

llvm::BasicBlock * getInvokeDest()

void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())

Emit code for the start of a function.

llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)

EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.

Definition CGObjC.cpp:64

void generateObjCSetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyImplDecl *propImpl, llvm::Constant *AtomicHelperFn)

Definition CGObjC.cpp:1468

void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)

Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...

void EmitExtendGCLifetime(llvm::Value *object)

EmitExtendGCLifetime - Given a pointer to an Objective-C object, make sure it survives garbage collec...

Definition CGObjC.cpp:3716

LValue EmitDeclRefLValue(const DeclRefExpr *E)

void callCStructCopyConstructor(LValue Dst, LValue Src)

llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)

Retain the given block, with _Block_copy semantics.

Definition CGObjC.cpp:2349

llvm::Value * EmitObjCCollectionLiteral(const Expr *E, const ObjCMethodDecl *MethodWithObjects)

Definition CGObjC.cpp:123

CGDebugInfo * getDebugInfo()

llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)

llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)

EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...

Definition CGObjC.cpp:3493

void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)

Definition CGObjC.cpp:2125

RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)

EmitCall - Generate a call of the given function, expecting the given result type,...

CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)

Emit the concrete pointer authentication informaton for the given authentication schema.

void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)

Increment the profiler's counter for the given statement by StepV.

SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)

llvm::Value * EmitObjCAlloc(llvm::Value *value, llvm::Type *returnType)

Allocate the given objc object.

Definition CGObjC.cpp:2789

llvm::Value * LoadObjCSelf()

LoadObjCSelf - Load the value of self.

Definition CGObjC.cpp:1788

void GenerateObjCMethod(const ObjCMethodDecl *OMD)

Generate an Objective-C method.

Definition CGObjC.cpp:807

void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)

llvm::Value * EmitARCLoadWeakRetained(Address addr)

i8* @objc_loadWeakRetained(i8** addr)

Definition CGObjC.cpp:2643

llvm::Value * emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull)

llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

ASTContext & getContext() const

llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)

EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...

void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)

Definition CGObjC.cpp:2714

void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)

void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)

EmitStoreOfComplex - Store a complex number into the specified l-value.

const Decl * CurFuncDecl

CurFuncDecl - Holds the Decl for the current outermost non-closure context.

void EmitAutoVarCleanups(const AutoVarEmission &emission)

void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)

EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...

llvm::Constant * GenerateObjCAtomicSetterCopyHelperFunction(const ObjCPropertyImplDecl *PID)

GenerateObjCAtomicSetterCopyHelperFunction - Given a c++ object type with non-trivial copy assignment...

Definition CGObjC.cpp:3733

void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)

Definition CGObjC.cpp:2133

void EmitARCNoopIntrinsicUse(ArrayRef< llvm::Value * > values)

Emit a call to "clang.arc.noop.use", which consumes the result of a call that has operand bundle "cla...

Definition CGObjC.cpp:2179

void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)

EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...

RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)

EmitAnyExpr - Emit code to compute the specified expression which can have any type.

void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})

EmitStmt - Emit the code for the statement.

bool AutoreleaseResult

In ARC, whether we should autorelease the return value.

CleanupKind getCleanupKind(QualType::DestructionKind kind)

llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

uint64_t getCurrentProfileCount()

Get the profiler's current count.

llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)

Retain the given object, with normal retain semantics.

Definition CGObjC.cpp:2337

llvm::Type * ConvertTypeForMem(QualType T)

void generateObjCGetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyImplDecl *propImpl, const ObjCMethodDecl *GetterMothodDecl, llvm::Constant *AtomicHelperFn)

Definition CGObjC.cpp:1135

llvm::Value * EmitARCRetainAutoreleaseNonBlock(llvm::Value *value)

Do a fused retain/autorelease of the given object.

Definition CGObjC.cpp:2628

llvm::Value * EmitObjCAutoreleasePoolPush()

Produce the code to do a objc_autoreleasepool_push.

Definition CGObjC.cpp:2724

void GenerateObjCSetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID)

GenerateObjCSetter - Synthesize an Objective-C property setter function for the given property.

Definition CGObjC.cpp:1672

llvm::Value * EmitARCLoadWeak(Address addr)

i8* @objc_loadWeak(i8** addr) Essentially objc_autorelease(objc_loadWeakRetained(addr)).

Definition CGObjC.cpp:2636

CodeGenTypes & getTypes() const

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

llvm::Constant * GenerateObjCAtomicGetterCopyHelperFunction(const ObjCPropertyImplDecl *PID)

Definition CGObjC.cpp:3833

RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)

CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...

llvm::Value * EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr)

Definition CGObjC.cpp:2160

AggValueSlot::Overlap_t getOverlapForReturnValue()

Determine whether a return value slot may overlap some other object.

void EmitAggExpr(const Expr *E, AggValueSlot AS)

EmitAggExpr - Emit the computation of the specified expression of aggregate type.

llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)

Definition CGObjC.cpp:4033

llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)

EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...

void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)

EmitCallArgs - Emit call arguments for a function.

LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)

void EmitReturnStmt(const ReturnStmt &S)

EmitReturnStmt - Note that due to GCC extensions, this can have an operand if the function returns vo...

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)

Store into a strong object.

Definition CGObjC.cpp:2524

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

Address GetAddrOfLocalVar(const VarDecl *VD)

GetAddrOfLocalVar - Return the address of a local variable.

llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)

Emits an instance of NSConstantString representing the object.

Definition CGObjC.cpp:51

std::pair< llvm::Value *, llvm::Value * > ComplexPairTy

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)

Try to emit a reference to the given value without producing it as an l-value.

void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr)

Produce the code to do a primitive release.

Definition CGObjC.cpp:2814

LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)

EmitLValue - Emit code to compute a designator that specifies the location of the expression.

llvm::Value * EmitARCExtendBlockObject(const Expr *expr)

Definition CGObjC.cpp:3524

llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)

i8* @objc_storeWeak(i8** addr, i8* value) Returns value.

Definition CGObjC.cpp:2651

llvm::LLVMContext & getLLVMContext()

static Destroyer destroyARCStrongPrecise

void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)

Definition CGObjC.cpp:1804

void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr)

Produce the code to do a primitive release.

Definition CGObjC.cpp:2734

llvm::Value * EmitObjCRetainNonBlock(llvm::Value *value, llvm::Type *returnType)

Retain the given object, with normal retain semantics.

Definition CGObjC.cpp:2858

void EmitARCCopyWeak(Address dst, Address src)

void @objc_copyWeak(i8** dest, i8** src) Disregards the current value in dest.

Definition CGObjC.cpp:2701

void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)

Definition CGObjC.cpp:2707

static Destroyer emitARCIntrinsicUse

void EmitARCIntrinsicUse(ArrayRef< llvm::Value * > values)

Given a number of pointers, inform the optimizer that they're being intrinsically used up until this ...

Definition CGObjC.cpp:2167

void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)

EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

This class organizes the cross-function state that is used while generating LLVM code.

llvm::Module & getModule() const

llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)

Create or return a runtime function declaration with the specified type and name.

void addCompilerUsedGlobal(llvm::GlobalValue *GV)

Add a global to a list to be added to the llvm.compiler.used metadata.

const LangOptions & getLangOpts() const

const TargetInfo & getTarget() const

ObjCEntrypoints & getObjCEntrypoints() const

const llvm::Triple & getTriple() const

ASTContext & getContext() const

const TargetCodeGenInfo & getTargetCodeGenInfo()

const CodeGenOptions & getCodeGenOpts() const

llvm::LLVMContext & getLLVMContext()

llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

llvm::FunctionCallee IsPlatformVersionAtLeastFn

llvm::ConstantInt * getSize(CharUnits numChars)

Emit the given number of characters as a value of type size_t.

This class organizes the cross-module state that is used while lowering AST types to LLVM types.

llvm::Type * ConvertType(QualType T)

ConvertType - Convert type T into a llvm::Type.

const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)

llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)

Try to emit the result of the given expression as an abstract constant.

FunctionArgList - Type for representing both the decl and type of parameters to a function.

LValue - This represents an lvalue references.

llvm::Value * getPointer(CodeGenFunction &CGF) const

const Qualifiers & getQuals() const

Address getAddress() const

ARCPreciseLifetime_t isARCPreciseLifetime() const

RValue - This trivial value class is used to represent the result of an expression that is evaluated.

static RValue get(llvm::Value *V)

llvm::Value * getScalarVal() const

getScalarVal() - Return the Value* of this scalar value.

ReturnValueSlot - Contains the address where the return value of a function can be stored,...

virtual StringRef getARCRetainAutoreleasedReturnValueMarker() const

Retrieve the address of a function to call immediately before calling objc_retainAutoreleasedReturnVa...

virtual bool markARCOptimizedReturnCallsAsNoTail() const

Determine whether a call to objc_retainAutoreleasedReturnValue or objc_unsafeClaimAutoreleasedReturnV...

CompoundStmt - This represents a group of statements like { stmt stmt }.

SourceLocation getLBracLoc() const

SourceLocation getRBracLoc() const

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

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

SourceLocation getBodyRBrace() const

getBodyRBrace - Gets the right brace of the body, if a body exists.

SourceLocation getLocation() const

DeclContext * getDeclContext()

Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...

This represents one expression.

Expr * IgnoreParenCasts() LLVM_READONLY

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

Expr * IgnoreParens() LLVM_READONLY

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

Represents difference between two FPOptions values.

Represents a member of a struct/union/class.

bool isBitField() const

Determines whether this field is a bitfield.

Represents a function declaration or definition.

static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})

GlobalDecl - represents a global declaration.

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.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...

clang::ObjCRuntime ObjCRuntime

ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...

Expr * getElement(unsigned Index)

getElement - Return the Element at the specified index.

unsigned getNumElements() const

getNumElements - Return number of elements of objective-c array literal.

ObjCMethodDecl * getArrayWithObjectsMethod() const

Represents Objective-C's @synchronized statement.

Represents Objective-C's @throw statement.

Represents Objective-C's @try ... @catch ... @finally statement.

Represents Objective-C's @autoreleasepool Statement.

const Stmt * getSubStmt() const

ObjCBoxedExpr - used for generalized expression boxing.

ObjCMethodDecl * getBoxingMethod() const

bool isExpressibleAsConstantInitializer() const

ObjCContainerDecl - Represents a container for method declarations.

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

unsigned getNumElements() const

getNumElements - Return number of elements of objective-c dictionary literal.

ObjCMethodDecl * getDictWithObjectsMethod() const

ObjCDictionaryElement getKeyValueElement(unsigned Index) const

Represents Objective-C's collection statement.

SourceLocation getBeginLoc() const LLVM_READONLY

const ObjCInterfaceDecl * getClassInterface() const

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

Represents an ObjC class declaration.

ObjCIvarDecl * all_declared_ivar_begin()

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

ObjCInterfaceDecl * getSuperClass() const

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

ObjCInterfaceDecl * getDecl() const

Get the declaration of this interface.

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCIvarDecl * getNextIvar()

ObjCIvarRefExpr - A reference to an ObjC instance variable.

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

bool isDelegateInitCall() const

isDelegateInitCall - Answers whether this message send has been tagged as a "delegate init call",...

Expr * getInstanceReceiver()

Returns the object expression (receiver) for an instance message, or null for a message that is not a...

Selector getSelector() const

@ SuperInstance

The receiver is the instance of the superclass object.

@ Instance

The receiver is an object instance.

@ SuperClass

The receiver is a superclass.

@ Class

The receiver is a class.

QualType getClassReceiver() const

Returns the type of a class message send, or NULL if the message is not a class message.

llvm::iterator_range< arg_iterator > arguments()

QualType getSuperType() const

Retrieve the type referred to by 'super'.

const ObjCMethodDecl * getMethodDecl() const

ReceiverKind getReceiverKind() const

Determine the kind of receiver that this message is being sent to.

ObjCMethodDecl - Represents an instance or class method declaration.

ImplicitParamDecl * getSelfDecl() const

ArrayRef< ParmVarDecl * > parameters() const

param_const_iterator param_end() const

param_const_iterator param_begin() const

Stmt * getBody() const override

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

SourceLocation getEndLoc() const LLVM_READONLY

const ParmVarDecl *const * param_const_iterator

SourceLocation getBeginLoc() const LLVM_READONLY

bool isDirectMethod() const

True if the method is tagged as objc_direct.

Selector getSelector() const

ImplicitParamDecl * getCmdDecl() const

bool isInstanceMethod() const

ObjCMethodFamily getMethodFamily() const

Determines the family of this method.

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

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

QualType getReturnType() const

bool isClassMethod() const

ObjCInterfaceDecl * getClassInterface()

Represents a pointer to an Objective C object.

const ObjCObjectType * getObjectType() const

Gets the type pointed to by this ObjC pointer.

QualType getPointeeType() const

Gets the type pointed to by this ObjC pointer.

const ObjCInterfaceType * getInterfaceType() const

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

Represents one property declaration in an Objective-C interface.

bool isAtomic() const

isAtomic - Return true if the property is atomic.

SetterKind getSetterKind() const

getSetterKind - Return the method used for doing assignment in the property setter.

ObjCPropertyAttribute::Kind getPropertyAttributes() const

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

ObjCIvarDecl * getPropertyIvarDecl() const

Expr * getSetterCXXAssignment() const

ObjCPropertyDecl * getPropertyDecl() const

Expr * getGetterCXXConstructor() const

ObjCMethodDecl * getSetterMethodDecl() const

ObjCMethodDecl * getGetterMethodDecl() const

Represents an Objective-C protocol declaration.

bool isNonRuntimeProtocol() const

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

ObjCProtocolList::iterator protocol_iterator

ObjCProtocolDecl * getCanonicalDecl() override

Retrieves the canonical declaration of this Objective-C protocol.

protocol_range protocols() const

ObjCProtocolExpr used for protocol expression in Objective-C.

ObjCProtocolDecl * getProtocol() const

The basic abstraction for the target Objective-C runtime.

bool hasAtomicCopyHelper() const

bool hasNativeARC() const

Does this runtime natively provide the ARC entrypoints?

bool hasOptimizedSetter() const

Does this runtime supports optimized setter entrypoints?

ObjCSelectorExpr used for @selector in Objective-C.

Selector getSelector() const

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

StringLiteral * getString()

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)

Pointer-authentication qualifiers.

semantics_iterator semantics_end()

semantics_iterator semantics_begin()

const Expr *const * const_semantics_iterator

Expr * getResultExpr()

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

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

PointerAuthQualifier getPointerAuth() const

@ DK_objc_strong_lifetime

QualType withConst() const

void addConst()

Add the const type qualifier to this QualType.

PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const

Check if this is a non-trivial type that would cause a C struct transitively containing this type to ...

Qualifiers::ObjCLifetime getObjCLifetime() const

Returns lifetime attribute of this type.

QualType getNonReferenceType() const

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

QualType getCanonicalType() const

QualType getUnqualifiedType() const

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

bool hasNonTrivialObjCLifetime() const

@ PCK_Struct

The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.

The collection of all-type qualifiers we support.

@ OCL_Strong

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

@ OCL_ExplicitNone

This object can be modified without requiring retains or releases.

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

@ OCL_Autoreleasing

Assigning into this object requires a lifetime extension.

ObjCLifetime getObjCLifetime() const

void setObjCLifetime(ObjCLifetime type)

static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)

Create a return statement.

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

Selector getNullarySelector(const IdentifierInfo *ID)

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

Can create any sort of selector.

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

StringRef getNameForSlot(unsigned argIndex) const

Retrieve the name at a given position in the selector.

const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const

Retrieve the identifier at a given position in the selector.

bool isKeywordSelector() const

ObjCMethodFamily getMethodFamily() const

Derive the conventional family of this method.

bool isUnarySelector() const

unsigned getNumArgs() const

Encodes a location in the source.

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Stmt - This represents one statement.

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

Exposes information about the current target.

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

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

bool isBlockPointerType() const

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

bool isPointerType() const

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

const ObjCObjectPointerType * getAsObjCInterfacePointerType() const

QualType getPointeeType() const

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

bool isAtomicType() const

bool isObjCObjectPointerType() const

bool isObjCClassType() const

bool isRecordType() const

bool isObjCRetainableType() const

bool hasPointerRepresentation() const

Whether this type is represented natively as a pointer.

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

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

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

bool isARCPseudoStrong() const

Determine whether this variable is an ARC pseudo-__strong variable.

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

llvm::Function * getNonTrivialCStructCopyConstructor(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)

Returns the copy constructor for a C struct with non-trivially copyable fields, generating it if nece...

@ NormalCleanup

Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...

@ EHCleanup

Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...

llvm::Function * getNonTrivialCStructMoveAssignmentOperator(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)

Return the move assignment operator for a C struct with non-trivially copyable fields,...

ARCPreciseLifetime_t

Does an ARC strong l-value have precise lifetime?

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr

Matches expressions.

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

bool isa(CodeGen::Address addr)

@ OK_Ordinary

An ordinary object is located at an address in memory.

@ Self

'self' clause, allowed on Compute and Combined Constructs, plus 'update'.

Selector GetUnarySelector(StringRef name, ASTContext &Ctx)

Utility function for constructing an unary selector.

@ Result

The result type of a method or function.

CastKind

CastKind - The kind of operation required for a conversion.

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

U cast(CodeGen::Address addr)

@ Class

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

A jump destination is an abstract label, branching to which may require a jump out through normal cle...

llvm::BasicBlock * getBlock() const

llvm::PointerType * VoidPtrTy

llvm::PointerType * Int8PtrPtrTy

unsigned char PointerSizeInBytes

llvm::IntegerType * Int32Ty

unsigned char PointerAlignInBytes

llvm::PointerType * Int8PtrTy

CharUnits getPointerAlign() const

llvm::Function * objc_retainAutoreleasedReturnValue

id objc_retainAutoreleasedReturnValue(id);

llvm::InlineAsm * retainAutoreleasedReturnValueMarker

A void(void) inline asm to use to mark that the return value of a call will be immediately retain.

llvm::Function * objc_unsafeClaimAutoreleasedReturnValue

id objc_unsafeClaimAutoreleasedReturnValue(id);

Expr * Value

The value of the dictionary element.

Expr * Key

The key for the dictionary element.