summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/CGTemporaries.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGTemporaries.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGTemporaries.cpp144
1 files changed, 41 insertions, 103 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGTemporaries.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGTemporaries.cpp
index a8f0467..fd7c616 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGTemporaries.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGTemporaries.cpp
@@ -15,14 +15,38 @@
using namespace clang;
using namespace CodeGen;
-void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
- llvm::Value *Ptr) {
- assert((LiveTemporaries.empty() ||
- LiveTemporaries.back().ThisPtr != Ptr ||
- ConditionalBranchLevel) &&
- "Pushed the same temporary twice; AST is likely wrong");
- llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");
+static void EmitTemporaryCleanup(CodeGenFunction &CGF,
+ const CXXTemporary *Temporary,
+ llvm::Value *Addr,
+ llvm::Value *CondPtr) {
+ llvm::BasicBlock *CondEnd = 0;
+
+ // If this is a conditional temporary, we need to check the condition
+ // boolean and only call the destructor if it's true.
+ if (CondPtr) {
+ llvm::BasicBlock *CondBlock = CGF.createBasicBlock("temp.cond-dtor.call");
+ CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont");
+
+ llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr);
+ CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd);
+ CGF.EmitBlock(CondBlock);
+ }
+
+ CGF.EmitCXXDestructorCall(Temporary->getDestructor(),
+ Dtor_Complete, /*ForVirtualBase=*/false,
+ Addr);
+
+ if (CondPtr) {
+ // Reset the condition to false.
+ CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(CGF.getLLVMContext()),
+ CondPtr);
+ CGF.EmitBlock(CondEnd);
+ }
+}
+/// Emits all the code to cause the given temporary to be cleaned up.
+void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
+ llvm::Value *Ptr) {
llvm::AllocaInst *CondPtr = 0;
// Check if temporaries need to be conditional. If so, we'll create a
@@ -38,82 +62,13 @@ void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), CondPtr);
}
- LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock,
- CondPtr));
-
- PushCleanupBlock(DtorBlock);
+ CleanupBlock Cleanup(*this, NormalCleanup);
+ EmitTemporaryCleanup(*this, Temporary, Ptr, CondPtr);
if (Exceptions) {
- const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
- llvm::BasicBlock *CondEnd = 0;
-
- EHCleanupBlock Cleanup(*this);
-
- // If this is a conditional temporary, we need to check the condition
- // boolean and only call the destructor if it's true.
- if (Info.CondPtr) {
- llvm::BasicBlock *CondBlock = createBasicBlock("cond.dtor.call");
- CondEnd = createBasicBlock("cond.dtor.end");
-
- llvm::Value *Cond = Builder.CreateLoad(Info.CondPtr);
- Builder.CreateCondBr(Cond, CondBlock, CondEnd);
- EmitBlock(CondBlock);
- }
-
- EmitCXXDestructorCall(Info.Temporary->getDestructor(),
- Dtor_Complete, /*ForVirtualBase=*/false,
- Info.ThisPtr);
-
- if (CondEnd) {
- // Reset the condition. to false.
- Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), Info.CondPtr);
- EmitBlock(CondEnd);
- }
- }
-}
-
-void CodeGenFunction::PopCXXTemporary() {
- const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
-
- CleanupBlockInfo CleanupInfo = PopCleanupBlock();
- assert(CleanupInfo.CleanupBlock == Info.DtorBlock &&
- "Cleanup block mismatch!");
- assert(!CleanupInfo.SwitchBlock &&
- "Should not have a switch block for temporary cleanup!");
- assert(!CleanupInfo.EndBlock &&
- "Should not have an end block for temporary cleanup!");
-
- llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
- if (CurBB && !CurBB->getTerminator() &&
- Info.DtorBlock->getNumUses() == 0) {
- CurBB->getInstList().splice(CurBB->end(), Info.DtorBlock->getInstList());
- delete Info.DtorBlock;
- } else
- EmitBlock(Info.DtorBlock);
-
- llvm::BasicBlock *CondEnd = 0;
-
- // If this is a conditional temporary, we need to check the condition
- // boolean and only call the destructor if it's true.
- if (Info.CondPtr) {
- llvm::BasicBlock *CondBlock = createBasicBlock("cond.dtor.call");
- CondEnd = createBasicBlock("cond.dtor.end");
-
- llvm::Value *Cond = Builder.CreateLoad(Info.CondPtr);
- Builder.CreateCondBr(Cond, CondBlock, CondEnd);
- EmitBlock(CondBlock);
- }
-
- EmitCXXDestructorCall(Info.Temporary->getDestructor(),
- Dtor_Complete, /*ForVirtualBase=*/false, Info.ThisPtr);
-
- if (CondEnd) {
- // Reset the condition. to false.
- Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), Info.CondPtr);
- EmitBlock(CondEnd);
+ Cleanup.beginEHCleanup();
+ EmitTemporaryCleanup(*this, Temporary, Ptr, CondPtr);
}
-
- LiveTemporaries.pop_back();
}
RValue
@@ -121,40 +76,23 @@ CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
llvm::Value *AggLoc,
bool IsAggLocVolatile,
bool IsInitializer) {
- // Keep track of the current cleanup stack depth.
- size_t CleanupStackDepth = CleanupEntries.size();
- (void) CleanupStackDepth;
-
RValue RV;
-
{
- CXXTemporariesCleanupScope Scope(*this);
+ RunCleanupsScope Scope(*this);
RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
/*IgnoreResult=*/false, IsInitializer);
}
- assert(CleanupEntries.size() == CleanupStackDepth &&
- "Cleanup size mismatch!");
-
return RV;
}
LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
const CXXExprWithTemporaries *E) {
- // Keep track of the current cleanup stack depth.
- size_t CleanupStackDepth = CleanupEntries.size();
- (void) CleanupStackDepth;
-
- unsigned OldNumLiveTemporaries = LiveTemporaries.size();
-
- LValue LV = EmitLValue(E->getSubExpr());
-
- // Pop temporaries.
- while (LiveTemporaries.size() > OldNumLiveTemporaries)
- PopCXXTemporary();
-
- assert(CleanupEntries.size() == CleanupStackDepth &&
- "Cleanup size mismatch!");
+ LValue LV;
+ {
+ RunCleanupsScope Scope(*this);
+ LV = EmitLValue(E->getSubExpr());
+ }
return LV;
}
OpenPOWER on IntegriCloud