1 //===--- CGCXXTemp.cpp - Emit LLVM Code for C++ temporaries ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This contains code dealing with C++ code generation of temporaries
12 //===----------------------------------------------------------------------===//
14 #include "CodeGenFunction.h"
15 using namespace clang;
16 using namespace CodeGen;
18 void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
20 llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");
22 llvm::Value *CondPtr = 0;
24 // Check if temporaries need to be conditional. If so, we'll create a
25 // condition boolean, initialize it to 0 and
26 if (!ConditionalTempDestructionStack.empty()) {
27 CondPtr = CreateTempAlloca(llvm::Type::Int1Ty, "cond");
29 // Initialize it to false. This initialization takes place right after
30 // the alloca insert point.
32 new llvm::StoreInst(llvm::ConstantInt::getFalse(), CondPtr);
33 llvm::BasicBlock *Block = AllocaInsertPt->getParent();
34 Block->getInstList().insertAfter((llvm::Instruction *)AllocaInsertPt, SI);
36 // Now set it to true.
37 Builder.CreateStore(llvm::ConstantInt::getTrue(), CondPtr);
40 LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock,
43 PushCleanupBlock(DtorBlock);
46 void CodeGenFunction::PopCXXTemporary() {
47 const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
49 CleanupBlockInfo CleanupInfo = PopCleanupBlock();
50 assert(CleanupInfo.CleanupBlock == Info.DtorBlock &&
51 "Cleanup block mismatch!");
52 assert(!CleanupInfo.SwitchBlock &&
53 "Should not have a switch block for temporary cleanup!");
54 assert(!CleanupInfo.EndBlock &&
55 "Should not have an end block for temporary cleanup!");
57 EmitBlock(Info.DtorBlock);
59 llvm::BasicBlock *CondEnd = 0;
61 // If this is a conditional temporary, we need to check the condition
62 // boolean and only call the destructor if it's true.
64 llvm::BasicBlock *CondBlock = createBasicBlock("cond.dtor.call");
65 CondEnd = createBasicBlock("cond.dtor.end");
67 llvm::Value *Cond = Builder.CreateLoad(Info.CondPtr);
68 Builder.CreateCondBr(Cond, CondBlock, CondEnd);
72 EmitCXXDestructorCall(Info.Temporary->getDestructor(),
73 Dtor_Complete, Info.ThisPtr);
76 // Reset the condition. to false.
77 Builder.CreateStore(llvm::ConstantInt::getFalse(), Info.CondPtr);
81 LiveTemporaries.pop_back();
85 CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
87 bool isAggLocVolatile) {
88 // If we shouldn't destroy the temporaries, just emit the
90 if (!E->shouldDestroyTemporaries())
91 return EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
93 // Keep track of the current cleanup stack depth.
94 size_t CleanupStackDepth = CleanupEntries.size();
95 (void) CleanupStackDepth;
97 unsigned OldNumLiveTemporaries = LiveTemporaries.size();
99 RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
102 while (LiveTemporaries.size() > OldNumLiveTemporaries)
105 assert(CleanupEntries.size() == CleanupStackDepth &&
106 "Cleanup size mismatch!");
112 CodeGenFunction::PushConditionalTempDestruction() {
113 // Store the current number of live temporaries.
114 ConditionalTempDestructionStack.push_back(LiveTemporaries.size());
117 void CodeGenFunction::PopConditionalTempDestruction() {
118 size_t NumLiveTemporaries = ConditionalTempDestructionStack.back();
119 ConditionalTempDestructionStack.pop_back();
122 while (LiveTemporaries.size() > NumLiveTemporaries) {
123 assert(LiveTemporaries.back().CondPtr &&
124 "Conditional temporary must have a cond ptr!");