blob: fd7c616b1162fc3139c04560b37376b423f1c67c [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 McCallf1549f62010-07-06 01:34:17 +000018static void EmitTemporaryCleanup(CodeGenFunction &CGF,
19 const CXXTemporary *Temporary,
20 llvm::Value *Addr,
21 llvm::Value *CondPtr) {
22 llvm::BasicBlock *CondEnd = 0;
23
24 // If this is a conditional temporary, we need to check the condition
25 // boolean and only call the destructor if it's true.
26 if (CondPtr) {
27 llvm::BasicBlock *CondBlock = CGF.createBasicBlock("temp.cond-dtor.call");
28 CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont");
Mike Stump1eb44332009-09-09 15:08:12 +000029
John McCallf1549f62010-07-06 01:34:17 +000030 llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr);
31 CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd);
32 CGF.EmitBlock(CondBlock);
33 }
34
35 CGF.EmitCXXDestructorCall(Temporary->getDestructor(),
36 Dtor_Complete, /*ForVirtualBase=*/false,
37 Addr);
38
39 if (CondPtr) {
40 // Reset the condition to false.
41 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(CGF.getLLVMContext()),
42 CondPtr);
43 CGF.EmitBlock(CondEnd);
44 }
45}
46
47/// Emits all the code to cause the given temporary to be cleaned up.
48void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
49 llvm::Value *Ptr) {
John McCallac418162010-04-22 01:10:34 +000050 llvm::AllocaInst *CondPtr = 0;
Mike Stump1eb44332009-09-09 15:08:12 +000051
52 // Check if temporaries need to be conditional. If so, we'll create a
53 // condition boolean, initialize it to 0 and
Anders Carlssona36bf8f2009-11-20 17:27:56 +000054 if (ConditionalBranchLevel != 0) {
Owen Anderson0032b272009-08-13 21:57:51 +000055 CondPtr = CreateTempAlloca(llvm::Type::getInt1Ty(VMContext), "cond");
Mike Stump1eb44332009-09-09 15:08:12 +000056
Anders Carlsson8c0b2032009-06-04 02:47:33 +000057 // Initialize it to false. This initialization takes place right after
58 // the alloca insert point.
John McCallac418162010-04-22 01:10:34 +000059 InitTempAlloca(CondPtr, llvm::ConstantInt::getFalse(VMContext));
Anders Carlsson8c0b2032009-06-04 02:47:33 +000060
61 // Now set it to true.
Owen Anderson3b144ba2009-07-31 17:39:36 +000062 Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), CondPtr);
Anders Carlsson8c0b2032009-06-04 02:47:33 +000063 }
Mike Stump1eb44332009-09-09 15:08:12 +000064
John McCallf1549f62010-07-06 01:34:17 +000065 CleanupBlock Cleanup(*this, NormalCleanup);
66 EmitTemporaryCleanup(*this, Temporary, Ptr, CondPtr);
Mike Stumpf2945c02009-12-17 06:08:47 +000067
68 if (Exceptions) {
John McCallf1549f62010-07-06 01:34:17 +000069 Cleanup.beginEHCleanup();
70 EmitTemporaryCleanup(*this, Temporary, Ptr, CondPtr);
Mike Stumpf2945c02009-12-17 06:08:47 +000071 }
Anders Carlsson2ce66122009-06-03 18:40:21 +000072}
73
Anders Carlssonf4b8fea2009-06-03 19:05:16 +000074RValue
Anders Carlsson2ce66122009-06-03 18:40:21 +000075CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
76 llvm::Value *AggLoc,
Anders Carlsson14c5cbf2009-08-16 07:36:22 +000077 bool IsAggLocVolatile,
78 bool IsInitializer) {
Anders Carlsson44ec82b2010-03-30 03:14:41 +000079 RValue RV;
Anders Carlsson44ec82b2010-03-30 03:14:41 +000080 {
John McCallf1549f62010-07-06 01:34:17 +000081 RunCleanupsScope Scope(*this);
Mike Stump1eb44332009-09-09 15:08:12 +000082
Anders Carlsson44ec82b2010-03-30 03:14:41 +000083 RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
84 /*IgnoreResult=*/false, IsInitializer);
85 }
Anders Carlsson2ce66122009-06-03 18:40:21 +000086 return RV;
87}
Anders Carlsson1d847502009-06-04 02:22:12 +000088
Anders Carlssonb9ea0b52009-09-14 01:10:45 +000089LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
90 const CXXExprWithTemporaries *E) {
John McCallf1549f62010-07-06 01:34:17 +000091 LValue LV;
92 {
93 RunCleanupsScope Scope(*this);
Anders Carlssonb9ea0b52009-09-14 01:10:45 +000094
John McCallf1549f62010-07-06 01:34:17 +000095 LV = EmitLValue(E->getSubExpr());
96 }
Anders Carlssonb9ea0b52009-09-14 01:10:45 +000097 return LV;
98}