[cfe-commits] r72837 - /cfe/trunk/lib/CodeGen/CGCXXTemp.cpp

Anders Carlsson andersca at mac.com
Wed Jun 3 19:47:36 PDT 2009


Author: andersca
Date: Wed Jun  3 21:47:33 2009
New Revision: 72837

URL: http://llvm.org/viewvc/llvm-project?rev=72837&view=rev
Log:
Make PushCXXTemporary and PopCXXTemporary handle conditional temporaries.

Modified:
    cfe/trunk/lib/CodeGen/CGCXXTemp.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXXTemp.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXTemp.cpp?rev=72837&r1=72836&r2=72837&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXTemp.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXTemp.cpp Wed Jun  3 21:47:33 2009
@@ -18,8 +18,27 @@
 void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary, 
                                        llvm::Value *Ptr) {
   llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");
-    
-  LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock, 0));
+  
+  llvm::Value *CondPtr = 0;
+  
+  // Check if temporaries need to be conditional. If so, we'll create a 
+  // condition boolean, initialize it to 0 and 
+  if (!ConditionalTempDestructionStack.empty()) {
+    CondPtr = CreateTempAlloca(llvm::Type::Int1Ty, "cond");
+  
+    // Initialize it to false. This initialization takes place right after
+    // the alloca insert point.
+    llvm::StoreInst *SI = 
+      new llvm::StoreInst(llvm::ConstantInt::getFalse(), CondPtr);
+    llvm::BasicBlock *Block = AllocaInsertPt->getParent();
+    Block->getInstList().insertAfter((llvm::Instruction *)AllocaInsertPt, SI);
+
+    // Now set it to true.
+    Builder.CreateStore(llvm::ConstantInt::getTrue(), CondPtr);
+  }
+  
+  LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock, 
+                                                 CondPtr));
 
   PushCleanupBlock(DtorBlock);
 }
@@ -37,9 +56,28 @@
   
   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, Info.ThisPtr);
 
+  if (CondEnd) {
+    // Reset the condition. to false.
+    Builder.CreateStore(llvm::ConstantInt::getFalse(), Info.CondPtr);
+    EmitBlock(CondEnd);
+  }
+  
   LiveTemporaries.pop_back();
 }
 
@@ -54,17 +92,13 @@
   
   RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
   
-  // Go through the temporaries backwards.
-  for (unsigned i = E->getNumTemporaries(); i != 0; --i) {
-    assert(LiveTemporaries.back().Temporary == E->getTemporary(i - 1));
-    LiveTemporaries.pop_back();
-  }
-
-  assert(OldNumLiveTemporaries == LiveTemporaries.size() &&
-         "Live temporary stack mismatch!");
+  // Pop temporaries.
+  while (LiveTemporaries.size() > OldNumLiveTemporaries)
+    PopCXXTemporary();
+  
+  assert(CleanupEntries.size() == CleanupStackDepth &&
+         "Cleanup size mismatch!");
   
-  EmitCleanupBlocks(CleanupStackDepth);
-
   return RV;
 }
 
@@ -75,6 +109,16 @@
 }
 
 void CodeGenFunction::PopConditionalTempDestruction() {
-  ConditionalTempDestructionStack.pop_back();
+ size_t NumLiveTemporaries = ConditionalTempDestructionStack.back();
+ ConditionalTempDestructionStack.pop_back();
+  
+  // Pop temporaries.
+  while (LiveTemporaries.size() > NumLiveTemporaries) {
+    const CXXLiveTemporaryInfo& TempInfo = LiveTemporaries.back();
+
+    assert(TempInfo.CondPtr && "Conditional temporary must have a cond ptr!");
+
+    PopCXXTemporary();
+  }  
 }
   





More information about the cfe-commits mailing list