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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

21#include "llvm/Support/SaveAndRestore.h"

22

23using namespace clang;

25

31 return true;

32}

33

40 : ScalarLiteral);

41 }

42

47 }

48

53 ? AggregateAddress

54 : AggregateLiteral);

55}

56

57

58

59

61 switch (K) {

62 case ScalarLiteral:

63 case ScalarAddress:

65 case AggregateLiteral:

66 case AggregateAddress:

69 case ComplexAddress: {

73 }

74 }

75

76 llvm_unreachable("bad saved r-value kind");

77}

78

79

80char *EHScopeStack::allocate(size_t Size) {

82 if (!StartOfBuffer) {

83 unsigned Capacity = 1024;

84 while (Capacity < Size) Capacity *= 2;

85 StartOfBuffer = new char[Capacity];

86 StartOfData = EndOfBuffer = StartOfBuffer + Capacity;

87 } else if (static_cast<size_t>(StartOfData - StartOfBuffer) < Size) {

88 unsigned CurrentCapacity = EndOfBuffer - StartOfBuffer;

89 unsigned UsedCapacity = CurrentCapacity - (StartOfData - StartOfBuffer);

90

91 unsigned NewCapacity = CurrentCapacity;

92 do {

93 NewCapacity *= 2;

94 } while (NewCapacity < UsedCapacity + Size);

95

96 char *NewStartOfBuffer = new char[NewCapacity];

97 char *NewEndOfBuffer = NewStartOfBuffer + NewCapacity;

98 char *NewStartOfData = NewEndOfBuffer - UsedCapacity;

99 memcpy(NewStartOfData, StartOfData, UsedCapacity);

100 delete [] StartOfBuffer;

101 StartOfBuffer = NewStartOfBuffer;

102 EndOfBuffer = NewEndOfBuffer;

103 StartOfData = NewStartOfData;

104 }

105

106 assert(StartOfBuffer + Size <= StartOfData);

107 StartOfData -= Size;

108 return StartOfData;

109}

110

111void EHScopeStack::deallocate(size_t Size) {

113}

114

117 for (EHScopeStack::iterator it = begin(); stabilize(it) != Old; it++) {

118 EHCleanupScope *cleanup = dyn_cast(&*it);

119

120

122 return false;

123 if (cleanup->isLifetimeMarker() && cleanup->isFakeUse())

124 return false;

125 }

126

127 return true;

128}

129

132

133 if (auto *cleanup = dyn_cast(&*find(si)))

134 if (cleanup->isLifetimeMarker()) {

135 si = cleanup->getEnclosingEHScope();

136 continue;

137 }

138 return true;

139 }

140

141 return false;

142}

143

147 si != se; ) {

149 if (cleanup.isActive()) return si;

150 si = cleanup.getEnclosingNormalCleanup();

151 }

153}

154

155

156void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) {

162

163

164

165

166

167 if (InnermostEHScope != stable_end() &&

169 IsEHCleanup = false;

170

171 EHCleanupScope *Scope =

172 new (Buffer) EHCleanupScope(IsNormalCleanup,

173 IsEHCleanup,

174 Size,

175 BranchFixups.size(),

176 InnermostNormalCleanup,

177 InnermostEHScope);

178 if (IsNormalCleanup)

180 if (IsEHCleanup)

182 if (IsLifetimeMarker)

184 if (IsFakeUse)

186

187

188

189

190

191

192

193 if (CGF->getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&

194 CGF->getTarget().getCXXABI().isMicrosoft() && CGF->getInvokeDest())

195 CGF->EmitSehCppScopeBegin();

196

198}

199

201 assert(empty() && "popping exception stack when not empty");

202

208

209

211

212

213 if (!BranchFixups.empty()) {

214

215

217 BranchFixups.clear();

218

219

220 else

222 }

223}

224

228 EHFilterScope *filter = new (buffer) EHFilterScope(numFilters);

230 return filter;

231}

232

234 assert(empty() && "popping exception stack when not empty");

235

238

240}

241

244 EHCatchScope *scope =

245 new (buffer) EHCatchScope(numHandlers, InnermostEHScope);

247 return scope;

248}

249

252 new (Buffer) EHTerminateScope(InnermostEHScope);

254}

255

256

257

258

259

260

262

263

265

266 EHScopeStack::iterator it = find(InnermostNormalCleanup);

268 assert(BranchFixups.size() >= MinSize && "fixup stack out of order");

269

270 while (BranchFixups.size() > MinSize &&

271 BranchFixups.back().Destination == nullptr)

272 BranchFixups.pop_back();

273}

274

276

279

280

281

283

284

286

287 return active;

288}

289

291

293 assert(cleanup.hasActiveFlag() && "cleanup already has active flag?");

294 cleanup.setActiveFlag(ActiveFlag);

295

296 if (cleanup.isNormalCleanup()) cleanup.setTestFlagInNormalCleanup();

297 if (cleanup.isEHCleanup()) cleanup.setTestFlagInEHCleanup();

298}

299

300void EHScopeStack::Cleanup::anchor() {}

301

303 llvm::BasicBlock::iterator beforeInst,

305 auto store = new llvm::StoreInst(value, addr.emitRawPointer(CGF), beforeInst);

307}

308

309static llvm::LoadInst *

311 llvm::BasicBlock::iterator beforeInst,

315 beforeInst);

316}

317

323

324

325

326

328 llvm::SwitchInst *Switch,

329 llvm::BasicBlock *CleanupEntry) {

331

333

335 if (Fixup.Destination == nullptr) continue;

336

337

338

339

340

341

342

343

344

349 Fixup.InitialBranch->setSuccessor(0, CleanupEntry);

350 }

351

352

353 if (!CasesAdded.insert(Fixup.Destination).second)

354 continue;

355

358 }

359

361}

362

363

364

366 llvm::BasicBlock *Block) {

367

368

369 llvm::Instruction *Term = Block->getTerminator();

370 assert(Term && "can't transition block without terminator");

371

372 if (llvm::BranchInst *Br = dyn_castllvm::BranchInst(Term)) {

373 assert(Br->isUnconditional());

375 "cleanup.dest", Term->getIterator(), CGF);

376 llvm::SwitchInst *Switch =

377 llvm::SwitchInst::Create(Load, Br->getSuccessor(0), 4, Block);

378 Br->eraseFromParent();

380 } else {

382 }

383}

384

386 assert(Block && "resolving a null target block");

387 if (EHStack.getNumBranchFixups()) return;

388

389 assert(EHStack.hasNormalCleanups() &&

390 "branch fixups exist with no normal cleanups on stack");

391

393 bool ResolvedAny = false;

394

395 for (unsigned I = 0, E = EHStack.getNumBranchFixups(); I != E; ++I) {

396

399

401 ResolvedAny = true;

402

403

404

406 if (!BranchBB)

407 continue;

408

409

410 if (!ModifiedOptimisticBlocks.insert(BranchBB).second)

411 continue;

412

414

415

417 }

418

419 if (ResolvedAny)

421}

422

423

426 std::initializer_list<llvm::Value **> ValuesToReload) {

428

429 bool HadBranches = false;

430 while (EHStack.stable_begin() != Old) {

432 HadBranches |= Scope.hasBranches();

433

434

435

436

437 bool FallThroughIsBranchThrough =

439

441 }

442

443

444

445

446 if (!HadBranches)

447 return;

448

449

450

451 for (llvm::Value **ReloadedValue : ValuesToReload) {

452 auto *Inst = dyn_cast_or_nullllvm::Instruction(*ReloadedValue);

453 if (!Inst)

454 continue;

455

456

457

458 auto *AI = dyn_castllvm::AllocaInst(Inst);

459 if (AI && AI->isStaticAlloca())

460 continue;

461

464

465

466 llvm::BasicBlock::iterator InsertBefore;

467 if (auto *Invoke = dyn_castllvm::InvokeInst(Inst))

468 InsertBefore = Invoke->getNormalDest()->getFirstInsertionPt();

469 else

470 InsertBefore = std::next(Inst->getIterator());

472

473

474 *ReloadedValue = Builder.CreateLoad(Tmp);

475 }

476}

477

478

479

482 std::initializer_list<llvm::Value **> ValuesToReload) {

484

485

486 for (size_t I = OldLifetimeExtendedSize,

488

490 "misaligned cleanup stack entry");

491

495 I += sizeof(Header);

496

501

506 I += sizeof(ActiveFlag);

507 }

508 }

510}

511

514 assert(Scope.isNormalCleanup());

515 llvm::BasicBlock *Entry = Scope.getNormalBlock();

516 if (!Entry) {

518 Scope.setNormalBlock(Entry);

519 }

520 return Entry;

521}

522

523

524

525

526

527

529 llvm::BasicBlock *Entry) {

530 llvm::BasicBlock *Pred = Entry->getSinglePredecessor();

531 if (!Pred) return Entry;

532

533 llvm::BranchInst *Br = dyn_castllvm::BranchInst(Pred->getTerminator());

534 if (!Br || Br->isConditional()) return Entry;

535 assert(Br->getSuccessor(0) == Entry);

536

537

538

539

540 bool WasInsertBlock = CGF.Builder.GetInsertBlock() == Entry;

541 assert(!WasInsertBlock || CGF.Builder.GetInsertPoint() == Entry->end());

542

543

544 Br->eraseFromParent();

545

546

547

548 Entry->replaceAllUsesWith(Pred);

549

550

551 Pred->splice(Pred->end(), Entry);

552

553

554 Entry->eraseFromParent();

555

556 if (WasInsertBlock)

557 CGF.Builder.SetInsertPoint(Pred);

558

559 return Pred;

560}

561

563 EHScopeStack::Cleanup *Fn,

564 EHScopeStack::Cleanup::Flags flags,

566

567

568 llvm::BasicBlock *ContBB = nullptr;

569 if (ActiveFlag.isValid()) {

571 llvm::BasicBlock *CleanupBB = CGF.createBasicBlock("cleanup.action");

572 llvm::Value *IsActive

574 CGF.Builder.CreateCondBr(IsActive, CleanupBB, ContBB);

576 }

577

578

579 Fn->Emit(CGF, flags);

580 assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?");

581

582

583 if (ActiveFlag.isValid())

585}

586

588 llvm::BasicBlock *From,

589 llvm::BasicBlock *To) {

590

591

592 llvm::Instruction *Term = Exit->getTerminator();

593

594 if (llvm::BranchInst *Br = dyn_castllvm::BranchInst(Term)) {

595 assert(Br->isUnconditional() && Br->getSuccessor(0) == From);

596 Br->setSuccessor(0, To);

597 } else {

599 for (unsigned I = 0, E = Switch->getNumSuccessors(); I != E; ++I)

600 if (Switch->getSuccessor(I) == From)

601 Switch->setSuccessor(I, To);

602 }

603}

604

605

606

607

608

609

610

614 if (!entry) return;

615

616

618 for (llvm::BasicBlock::use_iterator

619 i = entry->use_begin(), e = entry->use_end(); i != e; ) {

620 llvm::Use &use = *i;

621 ++i;

622

623 use.set(unreachableBB);

624

625

627 if (si->getNumCases() == 1 && si->getDefaultDest() == unreachableBB) {

628

629 llvm::BranchInst::Create(si->case_begin()->getCaseSuccessor(),

630 si->getIterator());

631

632

634

635

636 si->eraseFromParent();

637

638

640 assert(condition->use_empty());

641 condition->eraseFromParent();

642 }

643 }

644

645 assert(entry->use_empty());

646 delete entry;

647}

648

649

650

651

654 assert(EHStack.empty() && "cleanup stack is empty!");

657 assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups());

658

659

660

661 CGBuilderTy::InsertPoint NormalDeactivateOrigIP;

663 NormalDeactivateOrigIP = Builder.saveAndClearIP();

664 }

665

666 bool IsActive = Scope.isActive();

667 Address NormalActiveFlag =

668 Scope.shouldTestFlagInNormalCleanup() ? Scope.getActiveFlag()

671 Scope.shouldTestFlagInEHCleanup() ? Scope.getActiveFlag()

673

674

675

676 llvm::BasicBlock *EHEntry = Scope.getCachedEHDispatchBlock();

677 assert(Scope.hasEHBranches() == (EHEntry != nullptr));

678 bool RequiresEHCleanup = (EHEntry != nullptr);

680

681

682

683

684 unsigned FixupDepth = Scope.getFixupDepth();

685 bool HasFixups = EHStack.getNumBranchFixups() != FixupDepth;

686

687

688 bool HasExistingBranches = Scope.hasBranches();

689

690

691 llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();

692 bool HasFallthrough =

693 FallthroughSource != nullptr && (IsActive || HasExistingBranches);

694

695

696

697

698

699 bool HasPrebranchedFallthrough =

700 (FallthroughSource && FallthroughSource->getTerminator());

701

702

703

704

705 assert(Scope.isNormalCleanup() || !HasPrebranchedFallthrough ||

706 (Scope.getNormalBlock() &&

707 FallthroughSource->getTerminator()->getSuccessor(0)

708 == Scope.getNormalBlock()));

709

710 bool RequiresNormalCleanup = false;

711 if (Scope.isNormalCleanup() &&

712 (HasFixups || HasExistingBranches || HasFallthrough)) {

713 RequiresNormalCleanup = true;

714 }

715

716

717

718 if (Scope.isNormalCleanup() && HasPrebranchedFallthrough &&

719 !RequiresNormalCleanup) {

720

721

722 assert(!IsActive);

723 llvm::BasicBlock *prebranchDest;

724

725

726

727

728 if (FallthroughIsBranchThrough) {

731

732

733

734

735

736 } else {

739 }

740

741 llvm::BasicBlock *normalEntry = Scope.getNormalBlock();

742 assert(normalEntry && !normalEntry->use_empty());

743

745 normalEntry, prebranchDest);

746 }

747

748

749 if (!RequiresNormalCleanup && !RequiresEHCleanup) {

751 EHStack.popCleanup();

752 assert(EHStack.getNumBranchFixups() == 0 ||

753 EHStack.hasNormalCleanups());

754 if (NormalDeactivateOrigIP.isSet())

755 Builder.restoreIP(NormalDeactivateOrigIP);

756 return;

757 }

758

759

760

761

762

763

764 auto *CleanupSource = reinterpret_cast<char *>(Scope.getCleanupBuffer());

766 CleanupBufferStack[8 * sizeof(void *)];

767 std::unique_ptr<char[]> CleanupBufferHeap;

768 size_t CleanupSize = Scope.getCleanupSize();

769 EHScopeStack::Cleanup *Fn;

770

771 if (CleanupSize <= sizeof(CleanupBufferStack)) {

772 memcpy(CleanupBufferStack, CleanupSource, CleanupSize);

773 Fn = reinterpret_cast<EHScopeStack::Cleanup *>(CleanupBufferStack);

774 } else {

775 CleanupBufferHeap.reset(new char[CleanupSize]);

776 memcpy(CleanupBufferHeap.get(), CleanupSource, CleanupSize);

777 Fn = reinterpret_cast<EHScopeStack::Cleanup *>(CleanupBufferHeap.get());

778 }

779

780 EHScopeStack::Cleanup::Flags cleanupFlags;

781 if (Scope.isNormalCleanup())

782 cleanupFlags.setIsNormalCleanupKind();

783 if (Scope.isEHCleanup())

784 cleanupFlags.setIsEHCleanupKind();

785

786

787 bool IsEHa = getLangOpts().EHAsynch && Scope.isLifetimeMarker();

789 if (!RequiresNormalCleanup) {

790

791

793

794

795

796 if (NormalDeactivateOrigIP.isSet())

797 Builder.restoreIP(NormalDeactivateOrigIP);

800 if (NormalDeactivateOrigIP.isSet())

801 NormalDeactivateOrigIP = Builder.saveAndClearIP();

802 }

804 Scope.MarkEmitted();

806 } else {

807

808

809 if (HasFallthrough && !HasPrebranchedFallthrough && !HasFixups &&

810 !HasExistingBranches) {

811

812

816 else

818 }

819

821 Scope.MarkEmitted();

823

824 EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag);

825

826

827

828 } else {

829

831

832

833

834 CGBuilderTy::InsertPoint savedInactiveFallthroughIP;

835

836

837

838 if (HasFallthrough) {

839 if (!HasPrebranchedFallthrough)

841

842

843

844 } else if (FallthroughSource) {

845 assert(!IsActive && "source without fallthrough for active cleanup");

846 savedInactiveFallthroughIP = Builder.saveAndClearIP();

847 }

848

849

850

851

853

854

858 else

860 }

861

862

863

864

865 bool HasEnclosingCleanups =

866 (Scope.getEnclosingNormalCleanup() != EHStack.stable_end());

867

868

869

870

871

872

873 llvm::BasicBlock *BranchThroughDest = nullptr;

874 if (Scope.hasBranchThroughs() ||

875 (FallthroughSource && FallthroughIsBranchThrough) ||

876 (HasFixups && HasEnclosingCleanups)) {

877 assert(HasEnclosingCleanups);

880 }

881

882 llvm::BasicBlock *FallthroughDest = nullptr;

884

885

886

887

888

889

890

891

892 if (Scope.hasBranchThroughs() && !HasFixups && !HasFallthrough &&

894 assert(!BranchThroughDest || !IsActive);

895

896

897 llvm::Instruction *NormalCleanupDestSlot =

899 if (NormalCleanupDestSlot->hasOneUse()) {

900 NormalCleanupDestSlot->user_back()->eraseFromParent();

901 NormalCleanupDestSlot->eraseFromParent();

903 }

904

905 llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0);

906 InstsToAppend.push_back(llvm::BranchInst::Create(BranchAfter));

907

908

909

910

911

912

913 } else if (Scope.getNumBranchAfters() ||

914 (HasFallthrough && !FallthroughIsBranchThrough) ||

915 (HasFixups && !HasEnclosingCleanups)) {

916

917 llvm::BasicBlock *Default =

919

920

921 const unsigned SwitchCapacity = 10;

922

923

924 cleanupFlags.setHasExitSwitch();

925

927 "cleanup.dest", *this);

928 llvm::SwitchInst *Switch =

929 llvm::SwitchInst::Create(Load, Default, SwitchCapacity);

930

931 InstsToAppend.push_back(Load);

932 InstsToAppend.push_back(Switch);

933

934

935 if (FallthroughSource && !FallthroughIsBranchThrough) {

937 if (HasFallthrough)

938 Switch->addCase(Builder.getInt32(0), FallthroughDest);

939 }

940

941 for (unsigned I = 0, E = Scope.getNumBranchAfters(); I != E; ++I) {

942 Switch->addCase(Scope.getBranchAfterIndex(I),

943 Scope.getBranchAfterBlock(I));

944 }

945

946

947

948 if (HasFixups && !HasEnclosingCleanups)

950 } else {

951

952 assert(BranchThroughDest);

953 InstsToAppend.push_back(llvm::BranchInst::Create(BranchThroughDest));

954 }

955

956

957 Scope.MarkEmitted();

959 assert(EHStack.hasNormalCleanups() == HasEnclosingCleanups);

960

961 EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag);

962

963

964 llvm::BasicBlock *NormalExit = Builder.GetInsertBlock();

965 for (llvm::Instruction *Inst : InstsToAppend)

966 Inst->insertInto(NormalExit, NormalExit->end());

967

968

969 for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();

970 I < E; ++I) {

973 continue;

978 Fixup.InitialBranch->setSuccessor(0, NormalEntry);

979 }

981 }

982

983

984

985

986

987 if (!HasFallthrough && FallthroughSource) {

988

989

990

991 assert(!IsActive);

992 Builder.restoreIP(savedInactiveFallthroughIP);

993

994

995

996

997 } else if (HasFallthrough && FallthroughDest) {

998 assert(!FallthroughIsBranchThrough);

1000

1001

1002

1003 } else if (HasFallthrough) {

1004

1005

1006

1007 } else {

1008 Builder.ClearInsertionPoint();

1009 }

1010

1011

1012

1013

1014

1015 llvm::BasicBlock *NewNormalEntry =

1017

1018

1019

1020 if (NewNormalEntry != NormalEntry && NormalEntry == NormalExit)

1021 for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();

1022 I < E; ++I)

1023 EHStack.getBranchFixup(I).OptimisticBranchBlock = NewNormalEntry;

1024 }

1025 }

1026

1027 if (NormalDeactivateOrigIP.isSet())

1028 Builder.restoreIP(NormalDeactivateOrigIP);

1029 assert(EHStack.hasNormalCleanups() || EHStack.getNumBranchFixups() == 0);

1030

1031

1032 if (RequiresEHCleanup) {

1033 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();

1034

1036

1038

1039

1040

1041

1042 bool PushedTerminate = false;

1044 llvm::CleanupPadInst *CPI = nullptr;

1045

1049 if (!ParentPad)

1050 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());

1052 }

1053

1054

1056 EHStack.pushTerminate();

1057 PushedTerminate = true;

1060 }

1061

1062

1063

1064 if (EHActiveFlag.isValid() || IsActive) {

1065 cleanupFlags.setIsForEHCleanup();

1066 EmitCleanup(*this, Fn, cleanupFlags, EHActiveFlag);

1067 }

1068

1069 if (CPI)

1070 Builder.CreateCleanupRet(CPI, NextAction);

1071 else

1072 Builder.CreateBr(NextAction);

1073

1074

1075 if (PushedTerminate)

1077

1078 Builder.restoreIP(SavedIP);

1079

1081 }

1082}

1083

1084

1085

1086

1089 && "stale jump destination");

1090

1091

1093 EHStack.getInnermostActiveNormalCleanup();

1094

1095

1096

1097

1098 if (TopCleanup == EHStack.stable_end() ||

1100 return true;

1101

1102

1103 return false;

1104}

1105

1106

1107

1108

1109

1110

1111

1114 && "stale jump destination");

1115

1117 return;

1118

1119

1120 llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());

1122

1123

1125 TopCleanup = EHStack.getInnermostActiveNormalCleanup();

1126

1127

1128

1129

1130 if (TopCleanup == EHStack.stable_end() ||

1132 Builder.ClearInsertionPoint();

1133 return;

1134 }

1135

1136

1137

1144

1145 Builder.ClearInsertionPoint();

1146 return;

1147 }

1148

1149

1150

1151

1154 *this);

1155

1156

1157 {

1161 }

1162

1163

1167 while (true) {

1169 assert(Scope.isNormalCleanup());

1170 I = Scope.getEnclosingNormalCleanup();

1171

1172

1173

1176 break;

1177 }

1178

1179

1180

1181

1183 break;

1184 }

1185 }

1186

1187 Builder.ClearInsertionPoint();

1188}

1189

1191 EHScopeStack::stable_iterator cleanup) {

1192

1194 return true;

1195

1196

1197 for (EHScopeStack::stable_iterator

1199 assert(cleanup.strictlyEncloses(i));

1200

1203 return true;

1204

1206 }

1207

1208 return false;

1209}

1210

1215

1216

1217

1218

1219

1220

1222 EHScopeStack::stable_iterator C,

1224 llvm::Instruction *dominatingIP) {

1226

1227

1228

1229

1230 bool isActivatedInConditional =

1232

1233 bool needFlag = false;

1234

1235

1236

1237

1238 if (Scope.isNormalCleanup()) {

1239 Scope.setTestFlagInNormalCleanup();

1240 needFlag = true;

1241 }

1242

1243

1244 if (Scope.isEHCleanup() &&

1246 Scope.setTestFlagInEHCleanup();

1247 needFlag = true;

1248 }

1249

1250

1251 if (!needFlag)

1252 return;

1253

1255 if (!var.isValid()) {

1258 "cleanup.isactive");

1259 Scope.setActiveFlag(var);

1260 Scope.AddAuxAllocas(AllocaTracker.Take());

1261

1262 assert(dominatingIP && "no existing variable and no dominating IP!");

1263

1264

1265

1267

1268

1269

1272 } else {

1274 }

1275 }

1276

1278}

1279

1280

1282 llvm::Instruction *dominatingIP) {

1283 assert(C != EHStack.stable_end() && "activating bottom of stack?");

1285 assert(Scope.isActive() && "double activation");

1286

1288

1289 Scope.setActive(true);

1290}

1291

1292

1294 llvm::Instruction *dominatingIP) {

1295 assert(C != EHStack.stable_end() && "deactivating bottom of stack?");

1297 assert(Scope.isActive() && "double deactivation");

1298

1299

1300

1301 if (C == EHStack.stable_begin() &&

1304 true);

1305 return;

1306 }

1307

1308

1310

1311 Scope.setActive(false);

1312}

1313

1320

1321

1328

1329

1330

1332 llvm::FunctionCallee &SehCppScope) {

1333 llvm::BasicBlock *InvokeDest = CGF.getInvokeDest();

1334 assert(CGF.Builder.GetInsertBlock() && InvokeDest);

1335 llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");

1340 CGF.Builder.CreateInvoke(SehCppScope, Cont, InvokeDest, {}, BundleList);

1342}

1343

1344

1347 llvm::FunctionType *FTy =

1348 llvm::FunctionType::get(CGM.VoidTy, false);

1349 llvm::FunctionCallee SehCppScope =

1350 CGM.CreateRuntimeFunction(FTy, "llvm.seh.scope.begin");

1352}

1353

1354

1355

1358 llvm::FunctionType *FTy =

1359 llvm::FunctionType::get(CGM.VoidTy, false);

1360 llvm::FunctionCallee SehCppScope =

1361 CGM.CreateRuntimeFunction(FTy, "llvm.seh.scope.end");

1363}

1364

1365

1368 llvm::FunctionType *FTy =

1369 llvm::FunctionType::get(CGM.VoidTy, false);

1370 llvm::FunctionCallee SehCppScope =

1371 CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.begin");

1373}

1374

1375

1378 llvm::FunctionType *FTy =

1379 llvm::FunctionType::get(CGM.VoidTy, false);

1380 llvm::FunctionCallee SehCppScope =

1381 CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.end");

1383}

static llvm::LoadInst * createLoadInstBefore(Address addr, const Twine &name, llvm::BasicBlock::iterator beforeInst, CodeGenFunction &CGF)

Definition CGCleanup.cpp:310

static void EmitSehScope(CodeGenFunction &CGF, llvm::FunctionCallee &SehCppScope)

Definition CGCleanup.cpp:1331

static llvm::BasicBlock * CreateNormalEntry(CodeGenFunction &CGF, EHCleanupScope &Scope)

Definition CGCleanup.cpp:512

ForActivation_t

Definition CGCleanup.cpp:1211

@ ForActivation

Definition CGCleanup.cpp:1212

@ ForDeactivation

Definition CGCleanup.cpp:1213

static void EmitCleanup(CodeGenFunction &CGF, EHScopeStack::Cleanup *Fn, EHScopeStack::Cleanup::Flags flags, Address ActiveFlag)

Definition CGCleanup.cpp:562

static void destroyOptimisticNormalEntry(CodeGenFunction &CGF, EHCleanupScope &scope)

We don't need a normal entry block for the given cleanup.

Definition CGCleanup.cpp:611

static void SetupCleanupBlockActivation(CodeGenFunction &CGF, EHScopeStack::stable_iterator C, ForActivation_t kind, llvm::Instruction *dominatingIP)

The given cleanup block is changing activation state.

Definition CGCleanup.cpp:1221

static void ForwardPrebranchedFallthrough(llvm::BasicBlock *Exit, llvm::BasicBlock *From, llvm::BasicBlock *To)

Definition CGCleanup.cpp:587

static void createStoreInstBefore(llvm::Value *value, Address addr, llvm::BasicBlock::iterator beforeInst, CodeGenFunction &CGF)

Definition CGCleanup.cpp:302

static void ResolveAllBranchFixups(CodeGenFunction &CGF, llvm::SwitchInst *Switch, llvm::BasicBlock *CleanupEntry)

All the branch fixups on the EH stack have propagated out past the outermost normal cleanup; resolve ...

Definition CGCleanup.cpp:327

static bool IsUsedAsEHCleanup(EHScopeStack &EHStack, EHScopeStack::stable_iterator cleanup)

Definition CGCleanup.cpp:1190

static llvm::BasicBlock * SimplifyCleanupEntry(CodeGenFunction &CGF, llvm::BasicBlock *Entry)

Attempts to reduce a cleanup's entry block to a fallthrough.

Definition CGCleanup.cpp:528

static llvm::SwitchInst * TransitionToCleanupSwitch(CodeGenFunction &CGF, llvm::BasicBlock *Block)

Transitions the terminator of the given exit-block of a cleanup to be a cleanup switch.

Definition CGCleanup.cpp:365

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

tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")

Clean up any erroneous/redundant code in the given Ranges in Code.

__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)

Represents a C++ temporary.

llvm::Align getAsAlign() const

getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...

static CharUnits One()

One - Construct a CharUnits quantity of one.

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

CharUnits getAlignment() const

llvm::Type * getElementType() const

Return the type of the values stored in this address.

llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

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

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

EHScopeStack::stable_iterator CurrentCleanupScopeDepth

void EmitSehCppScopeBegin()

Definition CGCleanup.cpp:1345

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

ActivateCleanupBlock - Activates an initially-inactive cleanup.

Definition CGCleanup.cpp:1281

void EmitSehTryScopeEnd()

Definition CGCleanup.cpp:1376

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

createBasicBlock - Create an LLVM basic block.

void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)

See CGDebugInfo::addInstToCurrentSourceAtom.

const LangOptions & getLangOpts() const

void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)

pushDestroy - Push the standard destructor for the given type as at least a normal cleanup.

static Destroyer destroyCXXObject

void EmitSehCppScopeEnd()

Definition CGCleanup.cpp:1356

void EmitBranchThroughCleanup(JumpDest Dest)

EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...

Definition CGCleanup.cpp:1112

llvm::BasicBlock * getUnreachableBlock()

bool currentFunctionUsesSEHTry() const

@ Default

! No language constraints on evaluation order.

void initFullExprCleanupWithFlag(RawAddress ActiveFlag)

Definition CGCleanup.cpp:290

RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")

CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...

bool isInConditionalBranch() const

isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...

void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, std::initializer_list< llvm::Value ** > ValuesToReload={})

Takes the old cleanup stack size and emits the cleanup blocks that have been added.

Definition CGCleanup.cpp:424

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

DeactivateCleanupBlock - Deactivates the given cleanup block.

Definition CGCleanup.cpp:1293

llvm::BasicBlock * getInvokeDest()

void ResolveBranchFixups(llvm::BasicBlock *Target)

Definition CGCleanup.cpp:385

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)

CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...

void EmitSehTryScopeBegin()

Definition CGCleanup.cpp:1366

void setBeforeOutermostConditional(llvm::Value *value, Address addr, CodeGenFunction &CGF)

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

RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)

CreateTempAlloca - This creates a alloca and inserts it into the entry block.

llvm::SmallVector< char, 256 > LifetimeExtendedCleanupStack

RawAddress getNormalCleanupDestSlot()

Definition CGCleanup.cpp:1314

void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, Address Ptr)

Emits all the code to cause the given temporary to be cleaned up.

Definition CGCleanup.cpp:1322

llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)

RawAddress NormalCleanupDest

i32s containing the indexes of the cleanup destinations.

RawAddress createCleanupActiveFlag()

Definition CGCleanup.cpp:275

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

llvm::Instruction * CurrentFuncletPad

bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const

isObviouslyBranchWithoutCleanups - Return true if a branch to the specified destination obviously has...

Definition CGCleanup.cpp:1087

void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)

PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.

Definition CGCleanup.cpp:652

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

EmitBlock - Emit the given block.

A scope which attempts to handle some, possibly all, types of exceptions.

static size_t getSizeForNumHandlers(unsigned N)

A cleanup scope which generates the cleanup blocks lazily.

EHScopeStack::stable_iterator getEnclosingNormalCleanup() const

size_t getAllocatedSize() const

void * getCleanupBuffer()

static size_t getSizeForCleanupSize(size_t Size)

Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.

llvm::BasicBlock * getNormalBlock() const

An exceptions scope which filters exceptions thrown through it.

static size_t getSizeForNumFilters(unsigned numFilters)

unsigned getNumFilters() const

A saved depth on the scope stack.

bool encloses(stable_iterator I) const

Returns true if this scope encloses I.

bool strictlyEncloses(stable_iterator I) const

Returns true if this scope strictly encloses I: that is, if it encloses I and is not I.

A stack of scopes which respond to exceptions, including cleanups and catch blocks.

void popNullFixups()

Pops lazily-removed fixups from the end of the list.

BranchFixup & getBranchFixup(unsigned I)

bool requiresLandingPad() const

stable_iterator getInnermostNormalCleanup() const

Returns the innermost normal cleanup on the stack, or stable_end() if there are no normal cleanups.

stable_iterator stable_begin() const

Create a stable reference to the top of the EH stack.

unsigned getNumBranchFixups() const

class EHFilterScope * pushFilter(unsigned NumFilters)

Push an exceptions filter on the stack.

stable_iterator getInnermostEHScope() const

bool empty() const

Determines whether the exception-scopes stack is empty.

bool containsOnlyNoopCleanups(stable_iterator Old) const

iterator begin() const

Returns an iterator pointing to the innermost EH scope.

void pushTerminate()

Push a terminate handler on the stack.

void popCleanup()

Pops a cleanup scope off the stack. This is private to CGCleanup.cpp.

iterator find(stable_iterator save) const

Turn a stable reference to a scope depth into a unstable pointer to the EH stack.

stable_iterator getInnermostActiveNormalCleanup() const

void popFilter()

Pops an exceptions filter off the stack.

bool hasNormalCleanups() const

Determines whether there are any normal cleanups on the stack.

stable_iterator stabilize(iterator it) const

Translates an iterator into a stable_iterator.

static stable_iterator stable_end()

Create a stable reference to the bottom of the EH stack.

void clearFixups()

Clears the branch-fixups list.

class EHCatchScope * pushCatch(unsigned NumHandlers)

Push a set of catch handlers on the stack.

A protected scope for zero-cost EH handling.

EHScopeStack::stable_iterator getEnclosingEHScope() const

bool hasEHBranches() const

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

static RValue get(llvm::Value *V)

static RValue getAggregate(Address addr, bool isVolatile=false)

Convert an Address to an RValue.

static RValue getComplex(llvm::Value *V1, llvm::Value *V2)

Address getAggregateAddress() const

getAggregateAddr() - Return the Value* of the address of the aggregate.

llvm::Value * getScalarVal() const

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

std::pair< llvm::Value *, llvm::Value * > getComplexVal() const

getComplexVal - Return the real/imag components of this complex value.

An abstract representation of an aligned address.

llvm::Value * getPointer() const

static RawAddress invalid()

A (possibly-)qualified type.

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

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

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

bool isa(CodeGen::Address addr)

U cast(CodeGen::Address addr)

unsigned DestinationIndex

The destination index value.

llvm::BasicBlock * Destination

The ultimate destination of the branch.

llvm::BasicBlock * OptimisticBranchBlock

The block containing the terminator which needs to be modified into a switch if this fixup is resolve...

llvm::BranchInst * InitialBranch

The initial branch of the fixup.

llvm::SmallVector< llvm::AllocaInst * > Take()

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

llvm::BasicBlock * getBlock() const

EHScopeStack::stable_iterator getScopeDepth() const

unsigned getDestIndex() const

static llvm::Value * restore(CodeGenFunction &CGF, saved_type value)

static saved_type save(CodeGenFunction &CGF, llvm::Value *value)

static bool needsSaving(llvm::Value *value)

Answer whether the given value needs extra work to be saved.

A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function.

The exceptions personality for a function.

bool isMSVCXXPersonality() const

static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)

bool usesFuncletPads() const

Does this personality use landingpads or the family of pad instructions designed to form funclets?

bool isMSVCPersonality() const