@@ -1298,28 +1298,29 @@ namespace {
1298
1298
// / Enters a finally block for an implementation using zero-cost
1299
1299
// / exceptions. This is mostly general, but hard-codes some
1300
1300
// / language/ABI-specific behavior in the catch-all sections.
1301
- CodeGenFunction::FinallyInfo
1302
- CodeGenFunction::EnterFinallyBlock ( const Stmt *Body ,
1303
- llvm::Constant *BeginCatchFn ,
1304
- llvm::Constant *EndCatchFn ,
1305
- llvm::Constant *RethrowFn ) {
1306
- assert ((BeginCatchFn != 0 ) == (EndCatchFn != 0 ) &&
1301
+ void CodeGenFunction::FinallyInfo::enter (CodeGenFunction &CGF,
1302
+ const Stmt *body ,
1303
+ llvm::Constant *beginCatchFn ,
1304
+ llvm::Constant *endCatchFn ,
1305
+ llvm::Constant *rethrowFn ) {
1306
+ assert ((beginCatchFn != 0 ) == (endCatchFn != 0 ) &&
1307
1307
" begin/end catch functions not paired" );
1308
- assert (RethrowFn && " rethrow function is required" );
1308
+ assert (rethrowFn && " rethrow function is required" );
1309
+
1310
+ BeginCatchFn = beginCatchFn;
1309
1311
1310
1312
// The rethrow function has one of the following two types:
1311
1313
// void (*)()
1312
1314
// void (*)(void*)
1313
1315
// In the latter case we need to pass it the exception object.
1314
1316
// But we can't use the exception slot because the @finally might
1315
1317
// have a landing pad (which would overwrite the exception slot).
1316
- const llvm::FunctionType *RethrowFnTy =
1318
+ const llvm::FunctionType *rethrowFnTy =
1317
1319
cast<llvm::FunctionType>(
1318
- cast<llvm::PointerType>(RethrowFn->getType ())
1319
- ->getElementType ());
1320
- llvm::Value *SavedExnVar = 0 ;
1321
- if (RethrowFnTy->getNumParams ())
1322
- SavedExnVar = CreateTempAlloca (Builder.getInt8PtrTy (), " finally.exn" );
1320
+ cast<llvm::PointerType>(rethrowFn->getType ())->getElementType ());
1321
+ SavedExnVar = 0 ;
1322
+ if (rethrowFnTy->getNumParams ())
1323
+ SavedExnVar = CGF.CreateTempAlloca (CGF.Int8PtrTy , " finally.exn" );
1323
1324
1324
1325
// A finally block is a statement which must be executed on any edge
1325
1326
// out of a given scope. Unlike a cleanup, the finally block may
@@ -1333,67 +1334,64 @@ CodeGenFunction::EnterFinallyBlock(const Stmt *Body,
1333
1334
// The finally block itself is generated in the context of a cleanup
1334
1335
// which conditionally leaves the catch-all.
1335
1336
1336
- FinallyInfo Info;
1337
-
1338
1337
// Jump destination for performing the finally block on an exception
1339
1338
// edge. We'll never actually reach this block, so unreachable is
1340
1339
// fine.
1341
- JumpDest RethrowDest = getJumpDestInCurrentScope (getUnreachableBlock ());
1340
+ RethrowDest = CGF. getJumpDestInCurrentScope (CGF. getUnreachableBlock ());
1342
1341
1343
1342
// Whether the finally block is being executed for EH purposes.
1344
- llvm::AllocaInst *ForEHVar = CreateTempAlloca (Builder.getInt1Ty (),
1345
- " finally.for-eh" );
1346
- InitTempAlloca (ForEHVar, llvm::ConstantInt::getFalse (getLLVMContext ()));
1343
+ ForEHVar = CGF.CreateTempAlloca (CGF.Builder .getInt1Ty (), " finally.for-eh" );
1344
+ CGF.Builder .CreateStore (CGF.Builder .getFalse (), ForEHVar);
1347
1345
1348
1346
// Enter a normal cleanup which will perform the @finally block.
1349
- EHStack.pushCleanup <PerformFinally>(NormalCleanup, Body ,
1350
- ForEHVar, EndCatchFn ,
1351
- RethrowFn , SavedExnVar);
1347
+ CGF. EHStack .pushCleanup <PerformFinally>(NormalCleanup, body ,
1348
+ ForEHVar, endCatchFn ,
1349
+ rethrowFn , SavedExnVar);
1352
1350
1353
1351
// Enter a catch-all scope.
1354
- llvm::BasicBlock *CatchAllBB = createBasicBlock (" finally.catchall" );
1355
- CGBuilderTy::InsertPoint SavedIP = Builder.saveIP ();
1356
- Builder.SetInsertPoint (CatchAllBB);
1357
-
1358
- // If there's a begin-catch function, call it.
1359
- if (BeginCatchFn) {
1360
- Builder.CreateCall (BeginCatchFn, Builder.CreateLoad (getExceptionSlot ()))
1361
- ->setDoesNotThrow ();
1362
- }
1352
+ llvm::BasicBlock *catchBB = CGF.createBasicBlock (" finally.catchall" );
1353
+ EHCatchScope *catchScope = CGF.EHStack .pushCatch (1 );
1354
+ catchScope->setCatchAllHandler (0 , catchBB);
1355
+ }
1363
1356
1364
- // If we need to remember the exception pointer to rethrow later, do so.
1365
- if (SavedExnVar) {
1366
- llvm::Value *SavedExn = Builder. CreateLoad ( getExceptionSlot ());
1367
- Builder. CreateStore (SavedExn, SavedExnVar) ;
1368
- }
1357
+ void CodeGenFunction::FinallyInfo::exit (CodeGenFunction &CGF) {
1358
+ // Leave the finally catch-all.
1359
+ EHCatchScope &catchScope = cast<EHCatchScope>(*CGF. EHStack . begin ());
1360
+ llvm::BasicBlock *catchBB = catchScope. getHandler ( 0 ). Block ;
1361
+ CGF. EHStack . popCatch ();
1369
1362
1370
- // Tell the finally block that we're in EH.
1371
- Builder.CreateStore (llvm::ConstantInt::getTrue (getLLVMContext ()), ForEHVar);
1363
+ // If there are any references to the catch-all block, emit it.
1364
+ if (catchBB->use_empty ()) {
1365
+ delete catchBB;
1366
+ } else {
1367
+ CGBuilderTy::InsertPoint savedIP = CGF.Builder .saveAndClearIP ();
1368
+ CGF.EmitBlock (catchBB);
1372
1369
1373
- // Thread a jump through the finally cleanup.
1374
- EmitBranchThroughCleanup (RethrowDest);
1370
+ llvm::Value *exn = 0 ;
1375
1371
1376
- Builder.restoreIP (SavedIP);
1372
+ // If there's a begin-catch function, call it.
1373
+ if (BeginCatchFn) {
1374
+ exn = CGF.Builder .CreateLoad (CGF.getExceptionSlot ());
1375
+ CGF.Builder .CreateCall (BeginCatchFn, exn)->setDoesNotThrow ();
1376
+ }
1377
1377
1378
- EHCatchScope *CatchScope = EHStack.pushCatch (1 );
1379
- CatchScope->setCatchAllHandler (0 , CatchAllBB);
1378
+ // If we need to remember the exception pointer to rethrow later, do so.
1379
+ if (SavedExnVar) {
1380
+ if (!exn) exn = CGF.Builder .CreateLoad (CGF.getExceptionSlot ());
1381
+ CGF.Builder .CreateStore (exn, SavedExnVar);
1382
+ }
1380
1383
1381
- return Info;
1382
- }
1384
+ // Tell the cleanups in the finally block that we're do this for EH.
1385
+ CGF. Builder . CreateStore (CGF. Builder . getTrue (), ForEHVar);
1383
1386
1384
- void CodeGenFunction::ExitFinallyBlock (FinallyInfo &Info) {
1385
- // Leave the finally catch-all.
1386
- EHCatchScope &Catch = cast<EHCatchScope>(*EHStack.begin ());
1387
- llvm::BasicBlock *CatchAllBB = Catch.getHandler (0 ).Block ;
1388
- EHStack.popCatch ();
1387
+ // Thread a jump through the finally cleanup.
1388
+ CGF.EmitBranchThroughCleanup (RethrowDest);
1389
1389
1390
- // And leave the normal cleanup.
1391
- PopCleanupBlock ();
1392
-
1393
- CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP ();
1394
- EmitBlock (CatchAllBB, true );
1390
+ CGF.Builder .restoreIP (savedIP);
1391
+ }
1395
1392
1396
- Builder.restoreIP (SavedIP);
1393
+ // Finally, leave the @finally cleanup.
1394
+ CGF.PopCleanupBlock ();
1397
1395
}
1398
1396
1399
1397
llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad () {
0 commit comments