2009-11-24 08:51:11 +03:00
|
|
|
//===--- CGTemporaries.cpp - Emit LLVM Code for C++ temporaries -----------===//
|
2009-06-03 22:40:21 +04:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code dealing with C++ code generation of temporaries
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "CodeGenFunction.h"
|
|
|
|
using namespace clang;
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
2010-07-06 05:34:17 +04:00
|
|
|
static void EmitTemporaryCleanup(CodeGenFunction &CGF,
|
|
|
|
const CXXTemporary *Temporary,
|
|
|
|
llvm::Value *Addr,
|
|
|
|
llvm::Value *CondPtr) {
|
|
|
|
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 (CondPtr) {
|
|
|
|
llvm::BasicBlock *CondBlock = CGF.createBasicBlock("temp.cond-dtor.call");
|
|
|
|
CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont");
|
|
|
|
|
|
|
|
llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr);
|
|
|
|
CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd);
|
|
|
|
CGF.EmitBlock(CondBlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
CGF.EmitCXXDestructorCall(Temporary->getDestructor(),
|
|
|
|
Dtor_Complete, /*ForVirtualBase=*/false,
|
|
|
|
Addr);
|
|
|
|
|
|
|
|
if (CondPtr) {
|
|
|
|
// Reset the condition to false.
|
|
|
|
CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(CGF.getLLVMContext()),
|
|
|
|
CondPtr);
|
|
|
|
CGF.EmitBlock(CondEnd);
|
|
|
|
}
|
|
|
|
}
|
2009-09-09 19:08:12 +04:00
|
|
|
|
2010-07-06 05:34:17 +04:00
|
|
|
/// Emits all the code to cause the given temporary to be cleaned up.
|
|
|
|
void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
|
|
|
|
llvm::Value *Ptr) {
|
2010-04-22 05:10:34 +04:00
|
|
|
llvm::AllocaInst *CondPtr = 0;
|
2009-09-09 19:08:12 +04:00
|
|
|
|
|
|
|
// Check if temporaries need to be conditional. If so, we'll create a
|
|
|
|
// condition boolean, initialize it to 0 and
|
2009-11-20 20:27:56 +03:00
|
|
|
if (ConditionalBranchLevel != 0) {
|
2009-08-14 01:57:51 +04:00
|
|
|
CondPtr = CreateTempAlloca(llvm::Type::getInt1Ty(VMContext), "cond");
|
2009-09-09 19:08:12 +04:00
|
|
|
|
2009-06-04 06:47:33 +04:00
|
|
|
// Initialize it to false. This initialization takes place right after
|
|
|
|
// the alloca insert point.
|
2010-04-22 05:10:34 +04:00
|
|
|
InitTempAlloca(CondPtr, llvm::ConstantInt::getFalse(VMContext));
|
2009-06-04 06:47:33 +04:00
|
|
|
|
|
|
|
// Now set it to true.
|
2009-07-31 21:39:36 +04:00
|
|
|
Builder.CreateStore(llvm::ConstantInt::getTrue(VMContext), CondPtr);
|
2009-06-04 06:47:33 +04:00
|
|
|
}
|
2009-09-09 19:08:12 +04:00
|
|
|
|
2010-07-06 05:34:17 +04:00
|
|
|
CleanupBlock Cleanup(*this, NormalCleanup);
|
|
|
|
EmitTemporaryCleanup(*this, Temporary, Ptr, CondPtr);
|
2009-12-17 09:08:47 +03:00
|
|
|
|
|
|
|
if (Exceptions) {
|
2010-07-06 05:34:17 +04:00
|
|
|
Cleanup.beginEHCleanup();
|
|
|
|
EmitTemporaryCleanup(*this, Temporary, Ptr, CondPtr);
|
2009-06-04 06:47:33 +04:00
|
|
|
}
|
2009-06-03 22:40:21 +04:00
|
|
|
}
|
|
|
|
|
2009-06-03 23:05:16 +04:00
|
|
|
RValue
|
2009-06-03 22:40:21 +04:00
|
|
|
CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
|
|
|
|
llvm::Value *AggLoc,
|
2009-08-16 11:36:22 +04:00
|
|
|
bool IsAggLocVolatile,
|
|
|
|
bool IsInitializer) {
|
2010-03-30 07:14:41 +04:00
|
|
|
RValue RV;
|
|
|
|
{
|
2010-07-06 05:34:17 +04:00
|
|
|
RunCleanupsScope Scope(*this);
|
2009-09-09 19:08:12 +04:00
|
|
|
|
2010-03-30 07:14:41 +04:00
|
|
|
RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
|
|
|
|
/*IgnoreResult=*/false, IsInitializer);
|
|
|
|
}
|
2009-06-03 22:40:21 +04:00
|
|
|
return RV;
|
|
|
|
}
|
2009-06-04 06:22:12 +04:00
|
|
|
|
2009-09-14 05:10:45 +04:00
|
|
|
LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
|
|
|
|
const CXXExprWithTemporaries *E) {
|
2010-07-06 05:34:17 +04:00
|
|
|
LValue LV;
|
|
|
|
{
|
|
|
|
RunCleanupsScope Scope(*this);
|
2009-09-14 05:10:45 +04:00
|
|
|
|
2010-07-06 05:34:17 +04:00
|
|
|
LV = EmitLValue(E->getSubExpr());
|
|
|
|
}
|
2009-09-14 05:10:45 +04:00
|
|
|
return LV;
|
|
|
|
}
|