blob: b7bc6b703344c8ba8e73b741fe734b2e0b235c47 [file] [log] [blame]
Anders Carlsson2ce66122009-06-03 18:40:21 +00001//===--- CGCXXTemp.cpp - Emit LLVM Code for C++ temporaries ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code dealing with C++ code generation of temporaries
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15using namespace clang;
16using namespace CodeGen;
17
18void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
19 llvm::Value *Ptr) {
Anders Carlssonf4b8fea2009-06-03 19:05:16 +000020 llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");
21
22 LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock, 0));
Anders Carlssond8bc5a92009-06-04 02:08:08 +000023
24 PushCleanupBlock(DtorBlock);
Anders Carlsson2ce66122009-06-03 18:40:21 +000025}
26
Anders Carlssonf4b8fea2009-06-03 19:05:16 +000027void CodeGenFunction::PopCXXTemporary() {
28 const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
29
30 CleanupBlockInfo CleanupInfo = PopCleanupBlock();
31 assert(CleanupInfo.CleanupBlock == Info.DtorBlock &&
32 "Cleanup block mismatch!");
33 assert(!CleanupInfo.SwitchBlock &&
34 "Should not have a switch block for temporary cleanup!");
35 assert(!CleanupInfo.EndBlock &&
36 "Should not have an end block for temporary cleanup!");
37
38 EmitBlock(Info.DtorBlock);
39
40 EmitCXXDestructorCall(Info.Temporary->getDestructor(),
41 Dtor_Complete, Info.ThisPtr);
42
43 LiveTemporaries.pop_back();
44}
45
46RValue
Anders Carlsson2ce66122009-06-03 18:40:21 +000047CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
48 llvm::Value *AggLoc,
49 bool isAggLocVolatile) {
50 // Keep track of the current cleanup stack depth.
51 size_t CleanupStackDepth = CleanupEntries.size();
52
53 unsigned OldNumLiveTemporaries = LiveTemporaries.size();
54
55 RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
56
57 // Go through the temporaries backwards.
58 for (unsigned i = E->getNumTemporaries(); i != 0; --i) {
Anders Carlssone8b55782009-06-03 18:54:26 +000059 assert(LiveTemporaries.back().Temporary == E->getTemporary(i - 1));
Anders Carlsson2ce66122009-06-03 18:40:21 +000060 LiveTemporaries.pop_back();
61 }
62
63 assert(OldNumLiveTemporaries == LiveTemporaries.size() &&
64 "Live temporary stack mismatch!");
65
66 EmitCleanupBlocks(CleanupStackDepth);
67
68 return RV;
69}
Anders Carlsson1d847502009-06-04 02:22:12 +000070
71void
72CodeGenFunction::PushConditionalTempDestruction() {
73 // Store the current number of live temporaries.
74 ConditionalTempDestructionStack.push_back(LiveTemporaries.size());
75}
76
77void CodeGenFunction::PopConditionalTempDestruction() {
78 ConditionalTempDestructionStack.pop_back();
79}
80