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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

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

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

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

31#include

32using namespace clang;

33using namespace CodeGen;

34

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

41

42

43

46 return llvm::ConstantPointerNull::get(castllvm::PointerType(type));

47}

48

49

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

51{

52 llvm::Constant *C =

54 return C;

55}

56

57

58

59

60

61

62llvm::Value *

64

65

66 const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod();

67 const Expr *SubExpr = E->getSubExpr();

68

69 if (E->isExpressibleAsConstantInitializer()) {

71 return ConstEmitter.tryEmitAbstract(E, E->getType());

72 }

73

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

76

77

78

79

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

83

87

88

89

91 if (ValueType->isObjCBoxableRecordType()) {

92

93

99

100

101 std::string Str;

104

105

109

111 } else {

113 }

114

117 Args, ClassDecl, BoxingMethod);

120}

121

127 if (!ALE)

128 DLE = cast(E);

129

130

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

136 llvm::Constant *Constant =

140 castllvm::LoadInst(Ptr)->setMetadata(

141 llvm::LLVMContext::MD_invariant_load,

144 }

145

146

148 NumElements);

152 0);

153

154

157 if (DLE)

159

160

161

163 bool TrackNeededObjects =

166

167

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

169 if (ALE) {

170

174

177 if (TrackNeededObjects) {

178 NeededObjects.push_back(value);

179 }

180 } else {

181

187

188

194 if (TrackNeededObjects) {

195 NeededObjects.push_back(keyValue);

196 NeededObjects.push_back(valueValue);

197 }

198 }

199 }

200

201

207 if (DLE) {

208 argDecl = *PI++;

211 }

212 argDecl = *PI;

214 llvm::Value *Count =

217

218

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

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

228

229

232 Receiver, Args, Class, MethodWithObjects);

233

234

235

236

237

238 if (TrackNeededObjects) {

240 }

241

244}

245

248}

249

253}

254

255

257

258

259

260

262}

263

265

267}

268

269

270

271

276

277

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

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

281

282

284 ExpLLVMTy));

285}

286

287

288

289static bool

292

293

294

297

298

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

300 if (opaque->getSourceExpr())

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

302 }

303

304 const ImplicitCastExpr *ice = dyn_cast(receiver);

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

307

308

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

310 if (opaque->getSourceExpr())

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

312 }

313

314

316 return true;

317

318

319 if (isa(receiver) || isa(receiver))

320 return false;

321

322

324 if (!declRef) return true;

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

326 if (!var) return true;

327

328

329

330 return (var->hasLocalStorage() &&

331 !var->hasAttr());

332 }

333

336

337 return false;

338

340

341 return false;

342 }

343

344 llvm_unreachable("invalid receiver kind");

345}

346

347

348

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

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

355 return CE->getSubExpr();

356 }

357 }

358

359 return nullptr;

360}

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

379 bool isClassMessage) {

380 auto &CGM = CGF.CGM;

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

382 return std::nullopt;

383

384 auto &Runtime = CGM.getLangOpts().ObjCRuntime;

387 if (isClassMessage &&

388 Runtime.shouldUseRuntimeFunctionsForAlloc() &&

390

391

394

395

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

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

400 if (isallvm::ConstantPointerNull(arg))

403 return std::nullopt;

404 }

405 }

406 break;

407

411 Runtime.shouldUseARCFunctionsForRetainRelease())

413 break;

414

418 Runtime.shouldUseARCFunctionsForRetainRelease())

420 break;

421

425 Runtime.shouldUseARCFunctionsForRetainRelease()) {

427 return nullptr;

428 }

429 break;

430

431 default:

432 break;

433 }

434 return std::nullopt;

435}

436

441 bool isClassMessage) {

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

444 Sel, Method, isClassMessage)) {

446 }

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

448 Method);

449}

450

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

456 PDs.insert(Can);

457 return;

458 }

459

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

462}

463

464std::vector<const ObjCProtocolDecl *>

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

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

469

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

471 const auto *It = *begin;

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

473 if (Can->isNonRuntimeProtocol())

474 NonRuntimePDs.insert(Can);

475 else

476 RuntimePds.push_back(Can);

477 }

478

479

480 if (NonRuntimePDs.empty())

481 return RuntimePds;

482

483

484

485

486

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

488 for (const auto *PD : NonRuntimePDs)

490

491

492

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

494 for (const auto *PD : RuntimePds) {

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

496 AllImpliedProtocols.insert(Can);

497 Can->getImpliedProtocols(AllImpliedProtocols);

498 }

499

500

501

502

503 for (const auto *PD : FirstImpliedProtos) {

504 PD->getImpliedProtocols(AllImpliedProtocols);

505 }

506

507

508

509

510

511 for (const auto *PD : FirstImpliedProtos) {

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

513 RuntimePds.push_back(PD);

514 }

515 }

516

517 return RuntimePds;

518}

519

520

521

522

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

526 if (!Runtime.shouldUseRuntimeFunctionForCombinedAllocInit())

527 return std::nullopt;

528

529

534 return std::nullopt;

535

536

537

538 auto *SubOME =

540 if (!SubOME)

541 return std::nullopt;

542 Selector SubSel = SubOME->getSelector();

543

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

546 return std::nullopt;

547

548 llvm::Value *Receiver = nullptr;

549 switch (SubOME->getReceiverKind()) {

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

552 return std::nullopt;

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

554 break;

555

557 QualType ReceiverType = SubOME->getClassReceiver();

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

562 break;

563 }

566 return std::nullopt;

567 }

568

570}

571

574

575

576

577

578 bool isDelegateInit = E->isDelegateInitCall();

579

581

582

583

586 if (auto lvalueExpr = findWeakLValue(E->getInstanceReceiver())) {

590 }

591 }

592

595

596

597

598

599

600 bool retainSelf =

601 (!isDelegateInit &&

603 method &&

604 method->hasAttr());

605

607 bool isSuperMessage = false;

608 bool isClassMessage = false;

610

612 llvm::Value *Receiver = nullptr;

613 switch (E->getReceiverKind()) {

615 ReceiverType = E->getInstanceReceiver()->getType();

617 if (retainSelf) {

619 E->getInstanceReceiver());

620 Receiver = ter.getPointer();

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

622 } else

624 break;

625

627 ReceiverType = E->getClassReceiver();

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

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

631 isClassMessage = true;

632 break;

633 }

634

636 ReceiverType = E->getSuperType();

638 isSuperMessage = true;

639 break;

640

642 ReceiverType = E->getSuperType();

644 isSuperMessage = true;

645 isClassMessage = true;

646 break;

647 }

648

649 if (retainSelf)

651

652

653

654

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

656 method->hasAttr() &&

659

661

663 EmitCallArgs(Args, method, E->arguments(), AbstractCallee(method));

664

665

666

667

668

669

670

671

672 if (isDelegateInit) {

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

675

676

680 }

681

683 if (isSuperMessage) {

684

686 bool isCategoryImpl = isa(OMD->getDeclContext());

688 E->getSelector(),

690 isCategoryImpl,

691 Receiver,

692 isClassMessage,

693 Args,

694 method);

695 } else {

696

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

699 method, isClassMessage);

700 }

701

702

703

704 if (isDelegateInit) {

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

708

709

710

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

713

715 }

716

718}

719

720namespace {

724

728

729 bool isCategory = isa(impl);

730

731

733

738 iface,

739 isCategory,

740 self,

741 false,

742 args,

743 method);

744 }

745};

746}

747

748

749

750

755

756 if (OMD->hasAttr())

757 DebugInfo = nullptr;

758

760

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

766 } else {

768 }

769

773

775

777 CurEHLocation = OMD->getEndLoc();

778

781

783

784

785

786

788 }

789

790

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

798 }

799}

800

803

804

805

809 assert(isa(OMD->getBody()));

813}

814

815

816

818 bool isAtomic, bool hasStrong) {

820

821 llvm::Value *src =

824

825

826

828

832

837

842}

843

844

845

846

848

849

850 return false;

851}

852

853

854

856 llvm::Triple::ArchType arch) {

857

858

859

860

861

863}

864

865namespace {

866 class PropertyImplStrategy {

867 public:

868 enum StrategyKind {

869

870

871 Native,

872

873

874 GetSetProperty,

875

876

877

878 SetPropertyAndExpressionGet,

879

880

881 CopyStruct,

882

883

884

886 };

887

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

889

890 bool hasStrongMember() const { return HasStrong; }

891 bool isAtomic() const { return IsAtomic; }

892 bool isCopy() const { return IsCopy; }

893

894 CharUnits getIvarSize() const { return IvarSize; }

895 CharUnits getIvarAlignment() const { return IvarAlignment; }

896

899

900 private:

901 LLVM_PREFERRED_TYPE(StrategyKind)

902 unsigned Kind : 8;

903 LLVM_PREFERRED_TYPE(bool)

904 unsigned IsAtomic : 1;

905 LLVM_PREFERRED_TYPE(bool)

906 unsigned IsCopy : 1;

907 LLVM_PREFERRED_TYPE(bool)

908 unsigned HasStrong : 1;

909

912 };

913}

914

915

916PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,

920

923 HasStrong = false;

924

925

929 IvarSize = TInfo.Width;

930 IvarAlignment = TInfo.Align;

931

932

933

934

935 if (IsCopy) {

936 Kind = IsAtomic ? GetSetProperty : SetPropertyAndExpressionGet;

937 return;

938 }

939

940

942

944

945

946

947

948

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

950

951

952

953

954

955

958 else

959 Kind = SetPropertyAndExpressionGet;

960 return;

961

962

963

964

965 } else if (!IsAtomic) {

966 Kind = SetPropertyAndExpressionGet;

967 return;

968

969

970 } else {

971 Kind = GetSetProperty;

972 return;

973 }

974 }

975

976

977 if (!IsAtomic) {

979 return;

980 }

981

982

983

986 return;

987 }

988

989

990

991

996 return;

997 }

998

999

1002 HasStrong = recordType->getDecl()->hasObjectMember();

1003

1004

1005

1006

1007 if (HasStrong) {

1008 Kind = CopyStruct;

1009 return;

1010 }

1011

1012

1013

1014

1015

1016

1017 if (!IvarSize.isPowerOfTwo()) {

1018 Kind = CopyStruct;

1019 return;

1020 }

1021

1022 llvm::Triple::ArchType arch =

1024

1025

1026

1027

1029 Kind = CopyStruct;

1030 return;

1031 }

1032

1033

1034

1036 Kind = CopyStruct;

1037 return;

1038 }

1039

1040

1041 Kind = Native;

1042}

1043

1044

1045

1046

1047

1050 llvm::Constant *AtomicHelperFn =

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

1055

1057

1059}

1060

1063 if (!getter) return true;

1064

1065

1066

1067

1068

1069

1070

1072 return false;

1073

1074

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

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

1077

1078

1079

1080 assert(isa(getter));

1081 return false;

1082}

1083

1084

1085

1087 llvm::Value *returnAddr,

1089 llvm::Constant *AtomicHelperFn) {

1090

1091

1093

1094

1096

1097

1098 llvm::Value *ivarAddr =

1102

1103

1105

1106 llvm::FunctionCallee copyCppAtomicObjectFn =

1112}

1113

1114

1115

1116

1117

1118

1119

1123

1124

1125

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

1128 }

1129

1131}

1132

1133void

1137 llvm::Constant *AtomicHelperFn) {

1138

1140

1142 if (!AtomicHelperFn) {

1147 } else {

1150 ivar, AtomicHelperFn);

1151 }

1152 return;

1153 }

1154

1155

1157 if (!AtomicHelperFn) {

1160 nullptr);

1162 }

1163 else {

1166 ivar, AtomicHelperFn);

1167 }

1168 return;

1169 }

1170

1174

1175

1176 PropertyImplStrategy strategy(CGM, propImpl);

1177 switch (strategy.getKind()) {

1178 case PropertyImplStrategy::Native: {

1179

1180 if (strategy.getIvarSize().isZero())

1181 return;

1182

1184

1185

1186

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

1189

1190

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

1195

1196

1197

1198

1201 llvm::Value *ivarVal = load;

1202 if (ivarSize > retTySize) {

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

1204 ivarVal = Builder.CreateTrunc(load, bitcastType);

1205 }

1207

1208

1210 return;

1211 }

1212

1213 case PropertyImplStrategy::GetSetProperty: {

1214 llvm::FunctionCallee getPropertyFn =

1216 if (!getPropertyFn) {

1218 return;

1219 }

1221

1222

1223

1224

1227 llvm::Value *ivarOffset =

1229

1236

1237

1238

1239 llvm::CallBase *CallInstruction;

1241 getContext().getObjCIdType(), args),

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

1244 call->setTailCall();

1245

1246

1247

1248

1252

1253 EmitReturnOfRValue(RV, propType);

1254

1255

1257

1258 return;

1259 }

1260

1261 case PropertyImplStrategy::CopyStruct:

1263 strategy.hasStrongMember());

1264 return;

1265

1266 case PropertyImplStrategy::Expression:

1267 case PropertyImplStrategy::SetPropertyAndExpressionGet: {

1269

1275 true);

1276 return;

1277 }

1279

1280

1281

1284 return;

1285 }

1287 llvm::Value *value;

1290 } else {

1291

1295 } else {

1297 }

1298

1299

1300

1301 } else {

1304 }

1305

1306 value = Builder.CreateBitCast(

1308 }

1309

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

1311 return;

1312 }

1313 }

1314 llvm_unreachable("bad evaluation kind");

1315 }

1316

1317 }

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

1319}

1320

1321

1322

1325

1326

1328

1329

1330 llvm::Value *ivarAddr =

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

1335

1336

1343

1344

1345 llvm::Value *size =

1348

1349

1351

1352

1353

1355

1361}

1362

1363

1364

1365

1369 llvm::Constant *AtomicHelperFn) {

1370

1371

1373

1374

1375 llvm::Value *ivarAddr =

1379

1380

1387

1388

1390

1391 llvm::FunctionCallee fn =

1397}

1398

1399

1402 if (!setter) return true;

1403

1404

1405

1406

1407

1408

1409

1410

1411

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

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

1415 if (callee->isTrivial())

1416 return true;

1417 return false;

1418 }

1419

1420 assert(isa(setter));

1421 return false;

1422}

1423

1426 return false;

1428}

1429

1430void

1433 llvm::Constant *AtomicHelperFn) {

1436

1439 if (!AtomicHelperFn) {

1440

1441

1443 0);

1446 } else {

1447

1449 }

1450

1452 return;

1453 }

1454

1455

1456

1458 if (!AtomicHelperFn)

1459

1461 else

1462

1464 AtomicHelperFn);

1465 return;

1466 }

1467

1468 PropertyImplStrategy strategy(CGM, propImpl);

1469 switch (strategy.getKind()) {

1470 case PropertyImplStrategy::Native: {

1471

1472 if (strategy.getIvarSize().isZero())

1473 return;

1474

1476

1480

1481

1482

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

1485

1486

1489

1491

1492

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

1495 return;

1496 }

1497

1498 case PropertyImplStrategy::GetSetProperty:

1499 case PropertyImplStrategy::SetPropertyAndExpressionGet: {

1500

1501 llvm::FunctionCallee setOptimizedPropertyFn = nullptr;

1502 llvm::FunctionCallee setPropertyFn = nullptr;

1504

1505 setOptimizedPropertyFn =

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

1508 if (!setOptimizedPropertyFn) {

1510 return;

1511 }

1512 }

1513 else {

1515 if (!setPropertyFn) {

1517 return;

1518 }

1519 }

1520

1521

1522

1524 llvm::Value *self =

1526 llvm::Value *ivarOffset =

1531

1535 if (setOptimizedPropertyFn) {

1541 } else {

1548

1549

1553 }

1554

1555 return;

1556 }

1557

1558 case PropertyImplStrategy::CopyStruct:

1560 return;

1561

1562 case PropertyImplStrategy::Expression:

1563 break;

1564 }

1565

1566

1571 CK_LValueToRValue, &self, VK_PRValue,

1575 &selfLoad, true, true);

1576

1584

1585

1586

1587

1589 if (ivarRef.getType()->isObjCObjectPointerType()) {

1590 if (argLoad.getType()->isObjCObjectPointerType())

1591 argCK = CK_BitCast;

1592 else if (argLoad.getType()->isBlockPointerType())

1593 argCK = CK_BlockPointerToObjCPointerCast;

1594 else

1595 argCK = CK_CPointerToObjCPointerCast;

1596 } else if (ivarRef.getType()->isBlockPointerType()) {

1597 if (argLoad.getType()->isBlockPointerType())

1598 argCK = CK_BitCast;

1599 else

1600 argCK = CK_AnyPointerToBlockPointerCast;

1601 } else if (ivarRef.getType()->isPointerType()) {

1602 argCK = CK_BitCast;

1603 } else if (argLoad.getType()->isAtomicType() &&

1604 !ivarRef.getType()->isAtomicType()) {

1605 argCK = CK_AtomicToNonAtomic;

1606 } else if (!argLoad.getType()->isAtomicType() &&

1607 ivarRef.getType()->isAtomicType()) {

1608 argCK = CK_NonAtomicToAtomic;

1609 }

1612 Expr *finalArg = &argLoad;

1613 if (getContext().hasSameUnqualifiedType(ivarRef.getType(),

1614 argLoad.getType()))

1615 finalArg = &argCast;

1616

1618 getContext(), &ivarRef, finalArg, BO_Assign, ivarRef.getType(),

1621}

1622

1623

1624

1625

1626

1629 llvm::Constant *AtomicHelperFn =

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

1634

1636

1638}

1639

1640namespace {

1642 private:

1643 llvm::Value *addr;

1645 CodeGenFunction::Destroyer *destroyer;

1646 bool useEHCleanupForArray;

1647 public:

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

1649 CodeGenFunction::Destroyer *destroyer,

1650 bool useEHCleanupForArray)

1651 : addr(addr), ivar(ivar), destroyer(destroyer),

1652 useEHCleanupForArray(useEHCleanupForArray) {}

1653

1658 flags.isForNormalCleanup() && useEHCleanupForArray);

1659 }

1660 };

1661}

1662

1663

1669}

1670

1673 CodeGenFunction::RunCleanupsScope scope(CGF);

1674

1676

1681

1682

1684 if (!dtorKind) continue;

1685

1687

1688

1689

1692

1693

1694 } else {

1696 }

1697

1699

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

1702 }

1703

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

1705}

1706

1709 bool ctor) {

1712

1713

1714 if (ctor) {

1715

1717

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

1720 ObjCIvarDecl *Ivar = cast(Field);

1728 }

1729

1732 llvm::Value *SelfAsId =

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

1735

1736

1737 } else {

1739 }

1741}

1742

1749}

1750

1757}

1758

1760 llvm::FunctionCallee EnumerationMutationFnPtr =

1762 if (!EnumerationMutationFnPtr) {

1764 return;

1765 }

1766 CGCallee EnumerationMutationFn =

1768

1770 if (DI)

1772

1773 RunCleanupsScope ForScope(*this);

1774

1775

1777 if (const DeclStmt *SD = dyn_cast(S.getElement()))

1778 variable = EmitAutoVarAlloca(*cast(SD->getSingleDecl()));

1779

1781

1782

1786

1787

1788 static const unsigned NumItems = 16;

1789

1790

1797

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

1802

1803

1804 llvm::Value *Collection;

1807

1808

1810 } else {

1812 }

1813

1814

1815

1817

1818

1820

1821

1823

1824

1825

1826

1827

1828

1830

1831

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

1835

1836

1840 FastEnumSel, Collection, Args);

1841

1842

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

1844

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

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

1847

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

1849

1850

1851

1852

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

1856 LoopInitBB,

1857 createProfileWeights(EntryCount, getProfileCount(S.getBody())));

1858

1859

1861

1862

1863

1864

1865 Address StateMutationsPtrPtr =

1867 llvm::Value *StateMutationsPtr

1869

1871 llvm::Value *initialMutations =

1874

1875

1876

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

1879

1880

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

1882 index->addIncoming(zero, LoopInitBB);

1883

1884

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

1886 count->addIncoming(initialBufferLimit, LoopInitBB);

1887

1889

1890

1891

1892

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

1894 llvm::Value *currentMutations

1897

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

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

1900

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

1902 WasNotMutatedBB, WasMutatedBB);

1903

1904

1907 llvm::Value *V =

1908 Builder.CreateBitCast(Collection, ObjCIdType);

1911

1912

1916

1917

1919

1920

1921 RunCleanupsScope elementVariableScope(*this);

1922 bool elementIsVariable;

1923 LValue elementLValue;

1925 if (const DeclStmt *SD = dyn_cast(S.getElement())) {

1926

1928

1929 const VarDecl *D = cast(SD->getSingleDecl());

1932 elementLValue = EmitLValue(&tempDRE);

1933 elementType = D->getType();

1934 elementIsVariable = true;

1935

1936 if (D->isARCPseudoStrong())

1938 } else {

1939 elementLValue = LValue();

1940 elementType = cast(S.getElement())->getType();

1941 elementIsVariable = false;

1942 }

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

1944

1945

1946

1947

1950 llvm::Value *EnumStateItems =

1952

1953

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

1956 llvm::Value *CurrentItem =

1958

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

1960

1961

1962

1963

1964

1969 if (InterfaceTy) {

1970 SanitizerScope SanScope(this);

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

1975 llvm::Value *Cls =

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

1978 llvm::Value *IsClass =

1981 IsKindOfClassSel, CurrentItem,

1982 IsKindOfClassArgs)

1984 llvm::Constant *StaticData[] = {

1987 EmitCheck({{IsClass, SanitizerKind::SO_ObjCCast}},

1988 SanitizerHandler::InvalidObjCCast,

1990 }

1991 }

1992

1993

1994 CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,

1995 "currentitem");

1996

1997

1998

1999 if (!elementIsVariable) {

2000 elementLValue = EmitLValue(cast(S.getElement()));

2002 } else {

2004 true);

2005 }

2006

2007

2008

2009 if (elementIsVariable)

2011

2012

2013 BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));

2014 {

2015 RunCleanupsScope Scope(*this);

2017 }

2018 BreakContinueStack.pop_back();

2019

2020

2021 elementVariableScope.ForceCleanup();

2022

2023

2024 EmitBlock(AfterBody.getBlock());

2025

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

2027

2028

2029 llvm::Value *indexPlusOne =

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

2031

2032

2033

2034

2035

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

2038 createProfileWeights(getProfileCount(S.getBody()), EntryCount));

2039

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

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

2042

2043

2045

2046 CountRV =

2049 FastEnumSel, Collection, Args);

2050

2051

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

2053

2054

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

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

2057

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

2059 EmptyBB, LoopBodyBB);

2060

2061

2063

2064 if (!elementIsVariable) {

2065

2066

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

2068 elementLValue = EmitLValue(cast(S.getElement()));

2070 }

2071

2072 if (DI)

2074

2075 ForScope.ForceCleanup();

2077}

2078

2081}

2082

2085}

2086

2090}

2091

2092namespace {

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

2095 llvm::Value *object;

2096

2098

2100 }

2101 };

2102}

2103

2104

2105

2107 llvm::Value *object) {

2108

2109

2110 pushFullExprCleanup(getARCCleanupKind(), object);

2111 return object;

2112}

2113

2115 llvm::Value *value) {

2117}

2118

2119

2120

2123 if (!fn)

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

2125

2126

2127

2129}

2130

2131

2132

2135 if (!fn)

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

2138}

2139

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

2142

2143

2144

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

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

2148 }

2149 }

2150}

2151

2153 llvm::FunctionCallee RTF) {

2155}

2156

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

2161 return fn;

2162}

2163

2164

2165

2166

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

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

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

2171 if (isallvm::ConstantPointerNull(value))

2172 return value;

2173

2174 if (!fn)

2176

2177

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

2180

2181

2183 call->setTailCallKind(tailKind);

2184

2185

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

2187}

2188

2189

2190

2192 llvm::Function *&fn,

2193 llvm::Intrinsic::ID IntID) {

2194 if (!fn)

2196

2198}

2199

2200

2201

2203 llvm::Value *value,

2204 llvm::Function *&fn,

2205 llvm::Intrinsic::ID IntID,

2206 bool ignored) {

2208

2209 if (!fn)

2211

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

2213

2214 llvm::Value *args[] = {

2218

2219 if (ignored) return nullptr;

2220

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

2222}

2223

2224

2225

2227 llvm::Function *&fn,

2228 llvm::Intrinsic::ID IntID) {

2230

2231 if (!fn)

2233

2234 llvm::Value *args[] = {

2238}

2239

2240

2241

2242

2244 llvm::Value *value,

2245 llvm::Type *returnType,

2246 llvm::FunctionCallee &fn,

2247 StringRef fnName) {

2248 if (isallvm::ConstantPointerNull(value))

2249 return value;

2250

2251 if (!fn) {

2252 llvm::FunctionType *fnType =

2255

2256

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

2258 if (fnName == "objc_retain")

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

2260 }

2261

2262

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

2265

2266

2268

2269

2270

2271 if (fnName == "objc_autorelease")

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

2273 Call->setTailCall();

2274

2275

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

2277}

2278

2279

2280

2281

2283 if (type->isBlockPointerType())

2285 else

2287}

2288

2289

2290

2294 llvm::Intrinsic::objc_retain);

2295}

2296

2297

2298

2299

2300

2301

2302

2304 bool mandatory) {

2305 llvm::Value *result

2308 llvm::Intrinsic::objc_retainBlock);

2309

2310

2311

2312

2313

2314 if (!mandatory && isallvm::Instruction(result)) {

2315 llvm::CallInst *call

2316 = castllvm::CallInst(result->stripPointerCasts());

2317 assert(call->getCalledOperand() ==

2319

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

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

2322 }

2323

2324 return result;

2325}

2326

2328

2329

2330 llvm::InlineAsm *&marker

2332 if (!marker) {

2333 StringRef assembly

2336

2337

2338 if (assembly.empty()) {

2339

2340

2341

2343 llvm::FunctionType *type =

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

2345

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

2347

2348

2349

2350

2351 } else {

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

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

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

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

2356 retainRVMarkerKey, str);

2357 }

2358 }

2359 }

2360

2361

2362 if (marker)

2364}

2365

2367 bool IsRetainRV,

2370

2371

2372

2373

2374

2376 llvm::Function *&EP = IsRetainRV

2379 llvm::Intrinsic::ID IID =

2380 IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue

2381 : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;

2383

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

2385

2386

2387

2389 (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::x86_64)) {

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

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

2392 auto *oldCall = castllvm::CallBase(value);

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

2394 oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB,

2395 oldCall->getIterator());

2396 newCall->copyMetadata(*oldCall);

2397 oldCall->replaceAllUsesWith(newCall);

2398 oldCall->eraseFromParent();

2400 return newCall;

2401 }

2402

2403 bool isNoTail =

2405 llvm::CallInst::TailCallKind tailKind =

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

2408}

2409

2410

2411

2412

2413

2414

2415llvm::Value *

2418}

2419

2420

2421

2422

2423

2424

2425

2426

2427llvm::Value *

2430}

2431

2432

2433

2436 if (isallvm::ConstantPointerNull(value)) return;

2437

2439 if (!fn)

2441

2442

2444

2445

2447

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

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

2451 }

2452}

2453

2454

2455

2456

2457

2458

2459

2460

2461

2462

2468 return;

2469 }

2470

2473}

2474

2475

2476

2478 llvm::Value *value,

2479 bool ignored) {

2481

2483 if (!fn)

2485

2486 llvm::Value *args[] = {

2490

2491 if (ignored) return nullptr;

2492 return value;

2493}

2494

2495

2496

2497

2499 llvm::Value *newValue,

2500 bool ignored) {

2502 bool isBlock = type->isBlockPointerType();

2503

2504

2505

2507 !isBlock &&

2511 }

2512

2513

2514

2515

2517

2518

2520

2521

2522

2524

2525

2527

2528 return newValue;

2529}

2530

2531

2532

2536 llvm::Intrinsic::objc_autorelease);

2537}

2538

2539

2540

2541llvm::Value *

2545 llvm::Intrinsic::objc_autoreleaseReturnValue,

2546 llvm::CallInst::TCK_Tail);

2547}

2548

2549

2550

2551llvm::Value *

2555 llvm::Intrinsic::objc_retainAutoreleaseReturnValue,

2556 llvm::CallInst::TCK_Tail);

2557}

2558

2559

2560

2561

2562

2563

2565 llvm::Value *value) {

2566 if (type->isBlockPointerType())

2568

2569 if (isallvm::ConstantPointerNull(value)) return value;

2570

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

2575 return Builder.CreateBitCast(value, origType);

2576}

2577

2578

2579

2580llvm::Value *

2584 llvm::Intrinsic::objc_retainAutorelease);

2585}

2586

2587

2588

2592 llvm::Intrinsic::objc_loadWeak);

2593}

2594

2595

2599 llvm::Intrinsic::objc_loadWeakRetained);

2600}

2601

2602

2603

2605 llvm::Value *value,

2606 bool ignored) {

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

2610}

2611

2612

2613

2614

2615

2617

2618

2619

2620

2621 if (isallvm::ConstantPointerNull(value) &&

2624 return;

2625 }

2626

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

2630}

2631

2632

2633

2636 if (!fn)

2638

2640}

2641

2642

2643

2644

2648 llvm::Intrinsic::objc_moveWeak);

2649}

2650

2651

2652

2653

2657 llvm::Intrinsic::objc_copyWeak);

2658}

2659

2665}

2666

2673}

2674

2675

2676

2679 if (!fn)

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

2681

2683}

2684

2685

2686

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

2689

2691

2692 llvm::FunctionCallee &fn =

2694 if (!fn) {

2695 llvm::FunctionType *fnType =

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

2699 }

2700

2701

2703 } else {

2705 if (!fn)

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

2707

2709 }

2710}

2711

2712

2713

2714

2715

2716

2720

2727 AllocSel, Receiver, Args);

2728

2729

2736 InitSel, Receiver, Args);

2738}

2739

2740

2741

2743 llvm::Type *resultType) {

2746 "objc_alloc");

2747}

2748

2749

2750

2752 llvm::Type *resultType) {

2755 "objc_allocWithZone");

2756}

2757

2759 llvm::Type *resultType) {

2762 "objc_alloc_init");

2763}

2764

2765

2766

2773}

2774

2779}

2780

2785}

2786

2791}

2792

2797}

2798

2799

2800

2802 llvm::Type *returnType) {

2804 *this, value, returnType,

2806 "objc_autorelease");

2807}

2808

2809

2810

2812 llvm::Type *returnType) {

2814 *this, value, returnType,

2816}

2817

2818

2819

2822 if (isallvm::ConstantPointerNull(value)) return;

2823

2824 llvm::FunctionCallee &fn =

2826 if (!fn) {

2827 llvm::FunctionType *fnType =

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

2831

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

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

2834 }

2835

2836

2838

2839

2841

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

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

2845 }

2846}

2847

2848namespace {

2850 llvm::Value *Token;

2851

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

2853

2856 }

2857 };

2859 llvm::Value *Token;

2860

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

2862

2865 }

2866 };

2867}

2868

2872 else

2874}

2875

2877 switch (lifetime) {

2882 return true;

2883

2885 return false;

2886 }

2887

2888 llvm_unreachable("impossible lifetime!");

2889}

2890

2894 llvm::Value *result;

2896 if (shouldRetain) {

2898 } else {

2901 }

2903}

2904

2906 const Expr *e) {

2909

2910

2911

2912

2914 type.isConstQualified() &&

2916

2918

2919

2922

2923

2925

2927 }

2928

2929

2930

2931

2933 type.isVolatileQualified() &&

2935 isa(e) &&

2936 cast(e)->getOpcode() == BO_Assign)

2938

2939

2940

2941

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

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

2944 if (CodeGenFunction::ConstantEmission constant = CGF.tryEmitAsConstant(DRE))

2947 }

2948

2950}

2951

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

2953 llvm::Value *value)>

2955

2956

2957

2958

2959

2961 llvm::Value *value,

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

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

2966

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

2968

2969 value = doFallback(CGF, value);

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

2971

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

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

2974 value = doAfterCall(CGF, value);

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

2976

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

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

2979 value = doAfterCall(CGF, value);

2980

2981

2982

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

2984

2985

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

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

2989 bitcast->setOperand(0, operand);

2990 value = bitcast;

2991 } else {

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

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

2994 isallvm::ConstantPointerNull(phi->getIncomingValue(1)) &&

2995 isallvm::CallBase(phi->getIncomingValue(0))) {

2996

2997

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

3000 phi->setIncomingValue(0, inVal);

3001 value = phi;

3002 } else {

3003

3004

3005

3006 value = doFallback(CGF, value);

3007 }

3008 }

3009

3010 CGF.Builder.restoreIP(ip);

3011 return value;

3012}

3013

3014

3015

3017 const Expr *e) {

3022 },

3025 });

3026}

3027

3028

3029

3031 const Expr *e) {

3036 },

3038 return value;

3039 });

3040}

3041

3043 bool allowUnsafeClaim) {

3044 if (allowUnsafeClaim &&

3047 } else {

3050 }

3051}

3052

3053

3054

3055

3059

3060

3061

3062 if (isa(e))

3063 return false;

3064

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

3066 switch (cast->getCastKind()) {

3067

3068 case CK_LValueToRValue:

3069 case CK_ARCReclaimReturnedObject:

3070 case CK_ARCConsumeObject:

3071 case CK_ARCProduceObject:

3072 return false;

3073

3074

3075 case CK_NoOp:

3076 case CK_BitCast:

3078

3079

3080 case CK_AnyPointerToBlockPointerCast:

3081 default:

3082 return true;

3083 }

3084 }

3085

3086 return true;

3087}

3088

3089namespace {

3090

3091

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

3093protected:

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

3096

3098

3099public:

3100 Result visit(const Expr *e);

3101 Result visitCastExpr(const CastExpr *e);

3103 Result visitBlockExpr(const BlockExpr *e);

3104 Result visitBinaryOperator(const BinaryOperator *e);

3106 Result visitBinAssignUnsafeUnretained(const BinaryOperator *e);

3107 Result visitBinAssignAutoreleasing(const BinaryOperator *e);

3109 Result visitBinAssignStrong(const BinaryOperator *e);

3110

3111

3112

3113

3114

3115

3116

3117

3118

3119

3120

3121};

3122}

3123

3124

3125

3126

3127template <typename Impl, typename Result>

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

3131

3132

3133 const Expr *resultExpr = E->getResultExpr();

3134 assert(resultExpr);

3136

3138 i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {

3139 const Expr *semantic = *i;

3140

3141

3142

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

3144 typedef CodeGenFunction::OpaqueValueMappingData OVMA;

3145 OVMA opaqueData;

3146

3147

3148

3149 if (ov == resultExpr) {

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

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

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

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

3154

3155

3156 } else {

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

3158 }

3159 opaques.push_back(opaqueData);

3160

3161

3162

3163 } else if (semantic == resultExpr) {

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

3165

3166

3167 } else {

3168 CGF.EmitIgnoredExpr(semantic);

3169 }

3170 }

3171

3172

3173 for (unsigned i = 0, e = opaques.size(); i != e; ++i)

3174 opaques[i].unbind(CGF);

3175

3176 return result;

3177}

3178

3179template <typename Impl, typename Result>

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

3181

3182 return asImpl().visitExpr(e);

3183}

3184

3185template <typename Impl, typename Result>

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

3188

3189

3190 case CK_NoOp:

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

3192

3193

3194 case CK_CPointerToObjCPointerCast:

3195 case CK_BlockPointerToObjCPointerCast:

3196 case CK_AnyPointerToBlockPointerCast:

3197 case CK_BitCast: {

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

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

3202 }

3203

3204

3205 case CK_LValueToRValue:

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

3207 case CK_ARCConsumeObject:

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

3209 case CK_ARCExtendBlockObject:

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

3211 case CK_ARCReclaimReturnedObject:

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

3213

3214

3215 default:

3216 return asImpl().visitExpr(e);

3217 }

3218}

3219

3220template <typename Impl, typename Result>

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

3224 case BO_Comma:

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

3226 CGF.EnsureInsertPoint();

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

3228

3229 case BO_Assign:

3230 return asImpl().visitBinAssign(e);

3231

3232 default:

3233 return asImpl().visitExpr(e);

3234 }

3235}

3236

3237template <typename Impl, typename Result>

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

3241 return asImpl().visitBinAssignUnsafeUnretained(e);

3242

3244 return asImpl().visitBinAssignWeak(e);

3245

3247 return asImpl().visitBinAssignAutoreleasing(e);

3248

3250 return asImpl().visitBinAssignStrong(e);

3251

3253 return asImpl().visitExpr(e);

3254 }

3255 llvm_unreachable("bad ObjC ownership qualifier");

3256}

3257

3258

3259

3260template <typename Impl, typename Result>

3261Result ARCExprEmitter<Impl,Result>::

3262 visitBinAssignUnsafeUnretained(const BinaryOperator *e) {

3263

3264

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

3266

3267

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

3271 lvalue);

3272

3273 return result;

3274}

3275

3276template <typename Impl, typename Result>

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

3279 return asImpl().visitExpr(e);

3280}

3281

3282template <typename Impl, typename Result>

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

3285 return asImpl().visitExpr(e);

3286}

3287

3288template <typename Impl, typename Result>

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

3291 return asImpl().visitExpr(e);

3292}

3293

3294

3295template <typename Impl, typename Result>

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

3297

3298

3299

3300

3301 assert(!isa(e));

3302

3303

3305

3306

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

3308 return asImpl().visitCastExpr(ce);

3309

3310

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

3312 return asImpl().visitBinaryOperator(op);

3313

3314

3315

3316

3317

3318

3319

3320 } else if (isa(e) ||

3321 (isa(e) &&

3322 !cast(e)->isDelegateInitCall())) {

3323 return asImpl().visitCall(e);

3324

3325

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

3327 return asImpl().visitPseudoObjectExpr(pseudo);

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

3329 return asImpl().visitBlockExpr(be);

3330

3331 return asImpl().visitExpr(e);

3332}

3333

3334namespace {

3335

3336

3337struct ARCRetainExprEmitter :

3338 public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> {

3339

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

3341

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

3343 return result.getPointer();

3344 }

3345

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

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

3349 result.setPointer(value);

3350 return result;

3351 }

3352

3355 }

3356

3357

3358

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

3362 }

3363

3366

3367

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

3370 result.setInt(true);

3371 return result;

3372 }

3373

3374

3375

3376

3378 llvm::Value *result;

3379

3380

3381

3383 result = CGF.EmitScalarExpr(e);

3384

3385

3386 } else {

3388

3389

3390 if (subresult.getInt()) {

3391 return subresult;

3392 }

3393

3394

3395 result = subresult.getPointer();

3396 }

3397

3398

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

3401 }

3402

3403

3404

3408 }

3409

3410

3414 }

3415

3416

3417

3419

3420

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

3423 }

3424};

3425}

3426

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

3430}

3431

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

3437 if (!result.getInt())

3439 return value;

3440}

3441

3442

3443

3444

3445

3447

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

3449 RunCleanupsScope scope(*this);

3451 }

3452

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

3455 if (!result.getInt())

3457 return value;

3458}

3459

3460llvm::Value *

3462

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

3464 RunCleanupsScope scope(*this);

3466 }

3467

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

3470 if (result.getInt())

3472 else

3474 return value;

3475}

3476

3478 llvm::Value *result;

3479 bool doRetain;

3480

3483 doRetain = true;

3484 } else {

3486 result = subresult.getPointer();

3487 doRetain = !subresult.getInt();

3488 }

3489

3490 if (doRetain)

3493}

3494

3496

3498

3499

3501 }

3502

3503

3504

3505

3506

3507

3509}

3510

3511namespace {

3512

3513

3514struct ARCUnsafeUnretainedExprEmitter :

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

3516

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

3518

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

3520 return value;

3521 }

3522

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

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

3525 }

3526

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

3528 return CGF.EmitScalarExpr(e);

3529 }

3530

3531

3532

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

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

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

3536 }

3537

3538

3539

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

3541 return CGF.EmitARCExtendBlockObject(e);

3542 }

3543

3544

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

3546 return CGF.EmitARCReclaimReturnedObject(e, true);

3547 }

3548

3549

3550

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

3552 return CGF.EmitScalarExpr(e);

3553 }

3554

3555

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

3557 return CGF.EmitScalarExpr(e);

3558 }

3559};

3560}

3561

3563 const Expr *e) {

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

3565}

3566

3567

3568

3569

3570

3572

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

3574 RunCleanupsScope scope(*this);

3576 }

3577

3579}

3580

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

3583 bool ignored) {

3584

3585

3586 llvm::Value *value;

3587 if (ignored) {

3589 } else {

3591 }

3592

3593

3596

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

3598}

3599

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

3602 bool ignored) {

3603

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

3606

3607 bool hasImmediateRetain = result.getInt();

3608

3609

3610

3611

3614 hasImmediateRetain = true;

3615 }

3616

3618

3619

3620 if (hasImmediateRetain) {

3624 } else {

3626 }

3627

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

3629}

3630

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

3635

3637

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

3639}

3640

3644 const CompoundStmt &S = cast(*subStmt);

3645

3647 if (DI)

3649

3650

3651 RunCleanupsScope Scope(*this);

3655 } else {

3657 EHStack.pushCleanup(NormalCleanup, token);

3658 }

3659

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

3662

3663 if (DI)

3665}

3666

3667

3668

3670

3671 llvm::FunctionType *extenderType

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

3674 "",

3675 "r",

3676 true);

3677

3679}

3680

3681

3682

3683

3684

3685llvm::Constant *

3690 return nullptr;

3691

3694

3696

3697

3698 CharUnits Alignment = C.getTypeAlignInChars(Ty);

3701 return Fn;

3702 }

3703

3706 return nullptr;

3708 return nullptr;

3709 llvm::Constant *HelperFn = nullptr;

3711 return nullptr;

3714 return HelperFn;

3715

3718

3720 QualType DestTy = C.getPointerType(Ty);

3723 SrcTy = C.getPointerType(SrcTy);

3724

3726 ArgTys.push_back(DestTy);

3727 ArgTys.push_back(SrcTy);

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

3729

3732 FunctionTy, nullptr, SC_Static, false, false, false);

3733

3739 nullptr);

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

3744 nullptr);

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

3746 FD->setParams(Params);

3747

3750

3752

3753 llvm::Function *Fn =

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

3755 "__assign_helper_atomic_property_",

3757

3759

3761

3766

3771

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

3777

3779

3781 HelperFn = Fn;

3783 return HelperFn;

3784}

3785

3790 return nullptr;

3791

3794

3796 CharUnits Alignment = C.getTypeAlignInChars(Ty);

3799 return Fn;

3800 }

3801

3804 return nullptr;

3806 return nullptr;

3807 llvm::Constant *HelperFn = nullptr;

3809 return nullptr;

3812 return HelperFn;

3813

3816

3818 QualType DestTy = C.getPointerType(Ty);

3821 SrcTy = C.getPointerType(SrcTy);

3822

3824 ArgTys.push_back(DestTy);

3825 ArgTys.push_back(SrcTy);

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

3827

3830 FunctionTy, nullptr, SC_Static, false, false, false);

3831

3837 nullptr);

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

3842 nullptr);

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

3844 FD->setParams(Params);

3845

3848

3850

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

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

3854

3856

3858

3861

3865

3868

3870 ConstructorArgs.push_back(SRC);

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

3872 CXXConstExpr->arg_end());

3873

3878 ConstructorArgs,

3885

3888

3898

3900 HelperFn = Fn;

3902 return HelperFn;

3903}

3904

3905llvm::Value *

3907

3912 Selector AutoreleaseSelector =

3914

3915

3917 llvm::Value *Val = Block;

3920 Ty, CopySelector,

3922 Val = Result.getScalarVal();

3924 Ty, AutoreleaseSelector,

3926 Val = Result.getScalarVal();

3927 return Val;

3928}

3929

3931 switch (TT.getOS()) {

3932 case llvm::Triple::Darwin:

3933 case llvm::Triple::MacOSX:

3934 return llvm::MachO::PLATFORM_MACOS;

3935 case llvm::Triple::IOS:

3936 return llvm::MachO::PLATFORM_IOS;

3937 case llvm::Triple::TvOS:

3938 return llvm::MachO::PLATFORM_TVOS;

3939 case llvm::Triple::WatchOS:

3940 return llvm::MachO::PLATFORM_WATCHOS;

3941 case llvm::Triple::XROS:

3942 return llvm::MachO::PLATFORM_XROS;

3943 case llvm::Triple::DriverKit:

3944 return llvm::MachO::PLATFORM_DRIVERKIT;

3945 default:

3946 return llvm::MachO::PLATFORM_UNKNOWN;

3947 }

3948}

3949

3951 const VersionTuple &Version) {

3953

3954

3955

3957

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

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

3960 SMin = Version.getSubminor();

3961 Args.push_back(

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

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

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

3966 };

3967

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

3970

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

3973 CGM.Int32Ty, {CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty},

3974 false);

3977 }

3978

3979 llvm::Value *Check =

3981 return CGF.Builder.CreateICmpNE(Check,

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

3983}

3984

3985llvm::Value *

3987

3990

3992 llvm::FunctionType *FTy =

3996 }

3997

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

3999 SMin = Version.getSubminor();

4000 llvm::Value *Args[] = {

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

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

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

4004

4005 llvm::Value *CallRes =

4007

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

4009}

4010

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

4013 VersionTuple FoundationDroppedInVersion;

4014 switch (TT.getOS()) {

4015 case llvm::Triple::IOS:

4016 case llvm::Triple::TvOS:

4017 FoundationDroppedInVersion = VersionTuple(13);

4018 break;

4019 case llvm::Triple::WatchOS:

4020 FoundationDroppedInVersion = VersionTuple(6);

4021 break;

4022 case llvm::Triple::Darwin:

4023 case llvm::Triple::MacOSX:

4024 FoundationDroppedInVersion = VersionTuple(10, 15);

4025 break;

4026 case llvm::Triple::XROS:

4027

4028 return false;

4029 case llvm::Triple::DriverKit:

4030

4031 return false;

4032 default:

4033 llvm_unreachable("Unexpected OS");

4034 }

4035 return TargetVersion < FoundationDroppedInVersion;

4036}

4037

4038void CodeGenModule::emitAtAvailableLinkGuard() {

4040 return;

4041

4042 if (Target.getTriple().isOSDarwin())

4043 return;

4044

4045

4047 Target.getTriple(), Target.getPlatformMinVersion()))

4048 return;

4049

4050

4051

4052

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

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

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

4057

4058

4059 llvm::FunctionType *FTy =

4061 llvm::FunctionCallee CFFunc =

4063

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

4066 CheckFTy, "__clang_at_available_requires_core_foundation_framework",

4067 llvm::AttributeList(), true);

4068 llvm::Function *CFLinkCheckFunc =

4069 castllvm::Function(CFLinkCheckFuncRef.getCallee()->stripPointerCasts());

4070 if (CFLinkCheckFunc->empty()) {

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

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

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

4075 CGF.EmitNounwindRuntimeCall(CFFunc,

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

4077 CGF.Builder.CreateUnreachable();

4079 }

4080}

4081

Defines the clang::ASTContext interface.

Defines the Diagnostic-related interfaces.

CodeGenFunction::ComplexPairTy ComplexPairTy

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

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

static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl)

static bool shouldRetainObjCLifetime(Qualifiers::ObjCLifetime lifetime)

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

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

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

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

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

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

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

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

static llvm::Constant * getNullForVariable(Address addr)

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

static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF)

static const Expr * findWeakLValue(const Expr *E)

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

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

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

Determine whether the given architecture supports unaligned atomic accesses.

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

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

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

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

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

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

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

static bool shouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message)

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

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

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

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

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

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

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

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

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

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

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.

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

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

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

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

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

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.

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

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

Insert code immediately after a call.

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

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

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

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

static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID)

static bool UseOptimizedSetter(CodeGenModule &CGM)

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

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

llvm::MachO::Target Target

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.

CanQualType getSizeType() const

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

TypeInfoChars getTypeInfoInChars(const Type *T) const

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

QualType getObjCIdType() const

Represents the Objective-CC id type.

uint64_t getTypeSize(QualType T) const

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

CharUnits getTypeSizeInChars(QualType T) const

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

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

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

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.

bool isZero() const

isZero - Test whether the quantity equals zero.

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::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")

Given addr = [n x T]* ... produce name = getelementptr inbounds addr, i64 0, i64 index where i64 is a...

Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")

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

llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")

Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const 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 llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0

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

virtual llvm::FunctionCallee GetPropertySetFunction()=0

Return the runtime function for setting properties.

virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0

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

virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0

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.

virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0

virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0

Generate a function preamble for a method with the specified types.

virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0

Emit the code to return the named protocol as an object, as in a @protocol expression.

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 EnumerationMutationFunction()=0

EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...

virtual llvm::FunctionCallee GetGetStructFunction()=0

virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0

Generate a constant string object.

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

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

virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0

Return the runtime function for optimized setting properties.

virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0

Get a selector for the specified name and type values.

virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0

Generates prologue for direct Objective-C Methods.

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

virtual llvm::FunctionCallee GetPropertyGetFunction()=0

Return the runtime function for getting properties.

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

virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0

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

void add(RValue rvalue, QualType type)

static AutoVarEmission invalid()

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

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

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

void EmitARCDestroyWeak(Address addr)

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

void EmitNullInitialization(Address DestPtr, QualType Ty)

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

GlobalDecl CurGD

CurGD - The GlobalDecl for the current function being compiled.

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

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

DeactivateCleanupBlock - Deactivates the given cleanup block.

static TypeEvaluationKind getEvaluationKind(QualType T)

getEvaluationKind - Return the TypeEvaluationKind of QualType T.

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

SanitizerSet SanOpts

Sanitizers enabled for this function.

void EmitARCMoveWeak(Address dst, Address src)

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

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

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

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

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

llvm::Value * EmitObjCAutoreleasePoolPush()

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

void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr)

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

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

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

CleanupKind getARCCleanupKind()

Retrieves the default cleanup kind for an ARC cleanup.

bool shouldUseFusedARCCalls()

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

void GenerateObjCMethod(const ObjCMethodDecl *OMD)

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 * EmitARCAutorelease(llvm::Value *value)

void EmitExtendGCLifetime(llvm::Value *object)

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

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

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

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

void callCStructCopyConstructor(LValue Dst, LValue Src)

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

createBasicBlock - Create an LLVM basic block.

llvm::Value * EmitARCLoadWeakRetained(Address addr)

const LangOptions & getLangOpts() const

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

llvm::Constant * EmitCheckTypeDescriptor(QualType T)

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

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

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

EmitBlock - Emit the given block.

void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)

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

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

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

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

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

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

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

@ TCK_Store

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

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

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

llvm::Type * ConvertTypeForMem(QualType T)

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

const Decl * CurCodeDecl

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

void EmitAutoVarInit(const AutoVarEmission &emission)

llvm::AssertingVH< llvm::Instruction > AllocaInsertPt

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

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

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

QualType TypeOfSelfObject()

TypeOfSelfObject - Return type of object that this self represents.

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 * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)

Destroyer * getDestroyer(QualType::DestructionKind destructionKind)

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

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

ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)

llvm::Value * EmitARCLoadWeak(Address addr)

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

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

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

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

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

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

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

llvm::BasicBlock * getInvokeDest()

llvm::Value * LoadObjCSelf()

LoadObjCSelf - Load the value of self.

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

void EmitARCCopyWeak(Address dst, Address src)

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

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

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.

uint64_t getCurrentProfileCount()

Get the profiler's current count.

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.

ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)

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

llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)

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

CGDebugInfo * getDebugInfo()

LValue EmitDeclRefLValue(const DeclRefExpr *E)

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

EmitAggregateCopy - Emit an aggregate copy.

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

void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr)

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

void EmitAggExpr(const Expr *E, AggValueSlot AS)

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

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

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

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

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

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

ASTContext & getContext() const

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

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

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 Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)

const Decl * CurFuncDecl

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

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

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

AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)

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

EmitStmt - Emit the code for the statement.

void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)

void EmitAutoVarCleanups(const AutoVarEmission &emission)

static Destroyer destroyARCWeak

void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)

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

llvm::Value * EmitObjCMRRAutoreleasePoolPush()

llvm::Type * ConvertType(QualType T)

CodeGenTypes & getTypes() const

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

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

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

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

static Destroyer destroyARCStrongPrecise

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

void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)

void EmitReturnStmt(const ReturnStmt &S)

AggValueSlot::Overlap_t getOverlapForReturnValue()

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

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

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

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

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

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

uint64_t getProfileCount(const Stmt *S)

Get the profiler's count for the given statement.

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

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

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

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

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

GenerateObjCGetter - Synthesize an Objective-C property getter function.

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

Address GetAddrOfLocalVar(const VarDecl *VD)

GetAddrOfLocalVar - Return the address of a local variable.

void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

static Destroyer destroyARCStrongImprecise

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

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

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

void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)

llvm::LLVMContext & getLLVMContext()

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

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

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

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

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

static Destroyer emitARCIntrinsicUse

void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)

void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)

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

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

void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)

Set the attributes on the LLVM function for the given decl and function info.

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.

void ErrorUnsupported(const Stmt *S, const char *Type)

Print out an error that codegen doesn't support the specified stmt yet.

llvm::Constant * getAtomicGetterHelperFnMap(QualType Ty)

const LangOptions & getLangOpts() const

QualType getObjCFastEnumerationStateType()

Retrieve the record type that describes the state of an Objective-C fast enumeration loop (for....

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

llvm::FunctionCallee IsOSVersionAtLeastFn

const llvm::DataLayout & getDataLayout() const

ObjCEntrypoints & getObjCEntrypoints() const

const llvm::Triple & getTriple() const

void setAtomicSetterHelperFnMap(QualType Ty, llvm::Constant *Fn)

llvm::Constant * getAtomicSetterHelperFnMap(QualType Ty)

llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)

Create a new runtime global variable with the specified type and name.

ASTContext & getContext() const

const TargetCodeGenInfo & getTargetCodeGenInfo()

const CodeGenOptions & getCodeGenOpts() const

llvm::LLVMContext & getLLVMContext()

void setAtomicGetterHelperFnMap(QualType Ty, llvm::Constant *Fn)

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

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)

Set the LLVM function attributes (sext, zext, etc).

llvm::FunctionCallee IsPlatformVersionAtLeastFn

void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)

Set the LLVM function attributes which only apply to a function definition.

ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)

Returns a pointer to a character array containing the literal and a terminating '\0' character.

llvm::ConstantInt * getSize(CharUnits numChars)

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

void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)

Assign counters to regions and configure them for PGO of a given function.

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.

llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)

GetFunctionType - Get the LLVM function type for.

const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)

A builtin function is a freestanding function using the default C conventions.

const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)

Objective-C methods are C functions with some implicit parameters.

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

llvm::Constant * getPointer() const

Information for lazily generating a cleanup.

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

LValue - This represents an lvalue references.

CharUnits getAlignment() const

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

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, Expr *TrailingRequiresClause=nullptr)

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.

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.

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.

ObjCDictionaryElement getKeyValueElement(unsigned Index) const

Represents Objective-C's collection statement.

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

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

ObjCInterfaceDecl * getDecl() const

Get the declaration of this interface.

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCIvarDecl * getNextIvar()

ObjCIvarRefExpr - A reference to an ObjC instance variable.

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

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.

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 a class type in Objective C.

ObjCInterfaceDecl * getInterface() const

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

Represents one property declaration in an Objective-C interface.

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.

The basic abstraction for the target Objective-C runtime.

bool hasEmptyCollections() const

Are the empty collection symbols available?

bool hasAtomicCopyHelper() const

bool hasARCUnsafeClaimAutoreleasedReturnValue() const

Is objc_unsafeClaimAutoreleasedReturnValue available?

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.

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

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

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)

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

const Expr *const * const_semantics_iterator

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

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

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

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.

Stmt - This represents one statement.

SourceLocation getBeginLoc() const LLVM_READONLY

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

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

bool isObjCClassType() const

const T * getAs() const

Member-template getAs'.

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.

@ 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 AstTypeMatcher< RecordType > recordType

Matches record types (e.g.

const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr

Matches expressions.

bool BitCast(InterpState &S, CodePtr OpPC)

bool Cast(InterpState &S, CodePtr OpPC)

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

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

__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)

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::Function * objc_retainAutoreleaseReturnValue

id objc_retainAutoreleaseReturnValue(id);

llvm::FunctionCallee objc_alloc

void objc_alloc(id);

llvm::Function * objc_retain

id objc_retain(id);

llvm::FunctionCallee objc_alloc_init

void objc_alloc_init(id);

llvm::Function * objc_autorelease

id objc_autorelease(id);

llvm::Function * objc_moveWeak

void objc_moveWeak(id *dest, id *src);

llvm::FunctionCallee objc_autoreleasePoolPopInvoke

void objc_autoreleasePoolPop(void*); Note this method is used when we are using exception handling

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 * clang_arc_use

void clang.arc.use(...);

llvm::Function * objc_initWeak

id objc_initWeak(id*, id);

llvm::FunctionCallee objc_retainRuntimeFunction

id objc_retain(id); Note this is the runtime method not the intrinsic.

llvm::Function * objc_copyWeak

void objc_copyWeak(id *dest, id *src);

llvm::Function * objc_destroyWeak

void objc_destroyWeak(id*);

llvm::Function * objc_retainAutorelease

id objc_retainAutorelease(id);

llvm::Function * objc_autoreleasePoolPush

void *objc_autoreleasePoolPush(void);

llvm::Function * objc_retainBlock

id objc_retainBlock(id);

llvm::Function * objc_storeStrong

void objc_storeStrong(id*, id);

llvm::Function * objc_loadWeak

id objc_loadWeak(id*);

llvm::Function * clang_arc_noop_use

void clang.arc.noop.use(...);

llvm::Function * objc_loadWeakRetained

id objc_loadWeakRetained(id*);

llvm::Function * objc_release

void objc_release(id);

llvm::FunctionCallee objc_autoreleaseRuntimeFunction

id objc_autorelease(id); Note this is the runtime method not the intrinsic.

llvm::Function * objc_autoreleaseReturnValue

id objc_autoreleaseReturnValue(id);

llvm::FunctionCallee objc_releaseRuntimeFunction

void objc_release(id); Note this is the runtime method not the intrinsic.

llvm::FunctionCallee objc_allocWithZone

void objc_allocWithZone(id);

llvm::FunctionCallee objc_autoreleasePoolPop

void objc_autoreleasePoolPop(void*);

llvm::Function * objc_storeWeak

id objc_storeWeak(id*, id);

llvm::Function * objc_unsafeClaimAutoreleasedReturnValue

id objc_unsafeClaimAutoreleasedReturnValue(id);

Expr * Value

The value of the dictionary element.

Expr * Key

The key for the dictionary element.

bool has(SanitizerMask K) const

Check if a certain (single) sanitizer is enabled.