blob: dfb8dc63c5c574280af22b114ac4bdfc17b465fc [file] [log] [blame]
Anders Carlsson5b955922009-11-24 05:51:11 +00001//===--- CGTemporaries.cpp - Emit LLVM Code for C++ temporaries -----------===//
Anders Carlsson2ce66122009-06-03 18:40:21 +00002//
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
John McCall45483b42010-07-21 06:44:28 +000018namespace {
John McCall1f0fca52010-07-21 07:22:38 +000019 struct DestroyTemporary : EHScopeStack::Cleanup {
John McCall45483b42010-07-21 06:44:28 +000020 const CXXTemporary *Temporary;
21 llvm::Value *Addr;
22 llvm::Value *CondPtr;
23
24 DestroyTemporary(const CXXTemporary *Temporary, llvm::Value *Addr,
25 llvm::Value *CondPtr)
26 : Temporary(Temporary), Addr(Addr), CondPtr(CondPtr) {}
27
28 void Emit(CodeGenFunction &CGF, bool IsForEH) {
29 llvm::BasicBlock *CondEnd = 0;
John McCallf1549f62010-07-06 01:34:17 +000030
John McCall45483b42010-07-21 06:44:28 +000031 // If this is a conditional temporary, we need to check the condition
32 // boolean and only call the destructor if it's true.
33 if (CondPtr) {
34 llvm::BasicBlock *CondBlock =
35 CGF.createBasicBlock("temp.cond-dtor.call");
36 CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont");
Mike Stump1eb44332009-09-09 15:08:12 +000037
John McCall45483b42010-07-21 06:44:28 +000038 llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr);
39 CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd);
40 CGF.EmitBlock(CondBlock);
41 }
John McCallf1549f62010-07-06 01:34:17 +000042
John McCall45483b42010-07-21 06:44:28 +000043 CGF.EmitCXXDestructorCall(Temporary->getDestructor(),
44 Dtor_Complete, /*ForVirtualBase=*/false,
45 Addr);
John McCallf1549f62010-07-06 01:34:17 +000046
John McCall45483b42010-07-21 06:44:28 +000047 if (CondPtr) {
48 // Reset the condition to false.
49 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CondPtr);
50 CGF.EmitBlock(CondEnd);
51 }
52 }
53 };
54}
John McCallf1549f62010-07-06 01:34:17 +000055
56/// Emits all the code to cause the given temporary to be cleaned up.
57void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
58 llvm::Value *Ptr) {
John McCallac418162010-04-22 01:10:34 +000059 llvm::AllocaInst *CondPtr = 0;
Mike Stump1eb44332009-09-09 15:08:12 +000060
61 // Check if temporaries need to be conditional. If so, we'll create a
62 // condition boolean, initialize it to 0 and
Anders Carlssona36bf8f2009-11-20 17:27:56 +000063 if (ConditionalBranchLevel != 0) {
Owen Anderson0032b272009-08-13 21:57:51 +000064 CondPtr = CreateTempAlloca(llvm::Type::getInt1Ty(VMContext), "cond");
Mike Stump1eb44332009-09-09 15:08:12 +000065
Anders Carlsson8c0b2032009-06-04 02:47:33 +000066 // Initialize it to false. This initialization takes place right after
67 // the alloca insert point.
John McCallac418162010-04-22 01:10:34 +000068 InitTempAlloca(CondPtr, llvm::ConstantInt::getFalse(VMContext));
Anders Carlsson8c0b2032009-06-04 02:47:33 +000069
70 // Now set it to true.
John McCall45483b42010-07-21 06:44:28 +000071 Builder.CreateStore(Builder.getTrue(), CondPtr);
Anders Carlsson8c0b2032009-06-04 02:47:33 +000072 }
Mike Stump1eb44332009-09-09 15:08:12 +000073
John McCall1f0fca52010-07-21 07:22:38 +000074 EHStack.pushCleanup<DestroyTemporary>(NormalAndEHCleanup,
75 Temporary, Ptr, CondPtr);
Anders Carlsson2ce66122009-06-03 18:40:21 +000076}
77
Anders Carlssonf4b8fea2009-06-03 19:05:16 +000078RValue
Anders Carlsson2ce66122009-06-03 18:40:21 +000079CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
80 llvm::Value *AggLoc,
Anders Carlsson14c5cbf2009-08-16 07:36:22 +000081 bool IsAggLocVolatile,
82 bool IsInitializer) {
John McCalldf054db2010-07-21 06:45:54 +000083 RunCleanupsScope Scope(*this);
84 return EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
Anders Carlsson44ec82b2010-03-30 03:14:41 +000085 /*IgnoreResult=*/false, IsInitializer);
Anders Carlsson2ce66122009-06-03 18:40:21 +000086}
Anders Carlsson1d847502009-06-04 02:22:12 +000087
Anders Carlssonb9ea0b52009-09-14 01:10:45 +000088LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
89 const CXXExprWithTemporaries *E) {
John McCalldf054db2010-07-21 06:45:54 +000090 RunCleanupsScope Scope(*this);
91 return EmitLValue(E->getSubExpr());
Anders Carlssonb9ea0b52009-09-14 01:10:45 +000092}