diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 37 | ||||
-rw-r--r-- | lib/CodeGen/CGCXXTemp.cpp | 67 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 26 |
4 files changed, 98 insertions, 44 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 731e38c..4f9a4ca 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -189,43 +189,6 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest, E->arg_begin(), E->arg_end()); } -void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary, - llvm::Value *Ptr) { - LiveTemporaries.push_back(Temporary); - - // Make a cleanup scope and emit the destructor. - { - CleanupScope Scope(*this); - - EmitCXXDestructorCall(Temporary->getDestructor(), Dtor_Complete, Ptr); - } -} - -RValue -CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E, - llvm::Value *AggLoc, - bool isAggLocVolatile) { - // Keep track of the current cleanup stack depth. - size_t CleanupStackDepth = CleanupEntries.size(); - - unsigned OldNumLiveTemporaries = LiveTemporaries.size(); - - RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile); - - // Go through the temporaries backwards. - for (unsigned i = E->getNumTemporaries(); i != 0; --i) { - assert(LiveTemporaries.back() == E->getTemporary(i - 1)); - LiveTemporaries.pop_back(); - } - - assert(OldNumLiveTemporaries == LiveTemporaries.size() && - "Live temporary stack mismatch!"); - - EmitCleanupBlocks(CleanupStackDepth); - - return RV; -} - llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { if (E->isArray()) { ErrorUnsupported(E, "new[] expression"); diff --git a/lib/CodeGen/CGCXXTemp.cpp b/lib/CodeGen/CGCXXTemp.cpp new file mode 100644 index 0000000..d53a56f --- /dev/null +++ b/lib/CodeGen/CGCXXTemp.cpp @@ -0,0 +1,67 @@ +//===--- CGCXXTemp.cpp - Emit LLVM Code for C++ temporaries ---------------===// +// +// 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; + +void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary, + llvm::Value *Ptr) { + llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor"); + + LiveTemporaries.push_back(CXXLiveTemporaryInfo(Temporary, Ptr, DtorBlock, 0)); +} + +void CodeGenFunction::PopCXXTemporary() { + const CXXLiveTemporaryInfo& Info = LiveTemporaries.back(); + + CleanupBlockInfo CleanupInfo = PopCleanupBlock(); + assert(CleanupInfo.CleanupBlock == Info.DtorBlock && + "Cleanup block mismatch!"); + assert(!CleanupInfo.SwitchBlock && + "Should not have a switch block for temporary cleanup!"); + assert(!CleanupInfo.EndBlock && + "Should not have an end block for temporary cleanup!"); + + EmitBlock(Info.DtorBlock); + + EmitCXXDestructorCall(Info.Temporary->getDestructor(), + Dtor_Complete, Info.ThisPtr); + + LiveTemporaries.pop_back(); +} + +RValue +CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E, + llvm::Value *AggLoc, + bool isAggLocVolatile) { + // Keep track of the current cleanup stack depth. + size_t CleanupStackDepth = CleanupEntries.size(); + + unsigned OldNumLiveTemporaries = LiveTemporaries.size(); + + RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile); + + // Go through the temporaries backwards. + for (unsigned i = E->getNumTemporaries(); i != 0; --i) { + assert(LiveTemporaries.back().Temporary == E->getTemporary(i - 1)); + LiveTemporaries.pop_back(); + } + + assert(OldNumLiveTemporaries == LiveTemporaries.size() && + "Live temporary stack mismatch!"); + + EmitCleanupBlocks(CleanupStackDepth); + + return RV; +} diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 469c830..8d903d9 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -166,12 +166,12 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) { void AggExprEmitter::VisitCStyleCastExpr(CStyleCastExpr *E) { // GCC union extension - if (E->getType()->isUnionType()) { - RecordDecl *SD = E->getType()->getAsRecordType()->getDecl(); - LValue FieldLoc = CGF.EmitLValueForField(DestPtr, - *SD->field_begin(CGF.getContext()), - true, 0); - EmitInitializationToLValue(E->getSubExpr(), FieldLoc); + if (E->getSubExpr()->getType()->isScalarType()) { + QualType PtrTy = + CGF.getContext().getPointerType(E->getSubExpr()->getType()); + llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr, + CGF.ConvertType(PtrTy)); + EmitInitializationToLValue(E->getSubExpr(), LValue::MakeAddr(CastPtr, 0)); return; } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index b7894a4..c91a052 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -239,7 +239,30 @@ private: /// 'this' declaration. ImplicitParamDecl *CXXThisDecl; - llvm::SmallVector<const CXXTemporary*, 4> LiveTemporaries; + /// CXXLiveTemporaryInfo - Holds information about a live C++ temporary. + struct CXXLiveTemporaryInfo { + /// Temporary - The live temporary. + const CXXTemporary *Temporary; + + /// ThisPtr - The pointer to the temporary. + llvm::Value *ThisPtr; + + /// DtorBlock - The destructor block. + llvm::BasicBlock *DtorBlock; + + /// CondPtr - If this is a conditional temporary, this is the pointer to + /// the condition variable that states whether the destructor should be + /// called or not. + llvm::Value *CondPtr; + + CXXLiveTemporaryInfo(const CXXTemporary *temporary, + llvm::Value *thisptr, llvm::BasicBlock *dtorblock, + llvm::Value *condptr) + : Temporary(temporary), ThisPtr(thisptr), DtorBlock(dtorblock), + CondPtr(condptr) { } + }; + + llvm::SmallVector<CXXLiveTemporaryInfo, 4> LiveTemporaries; public: CodeGenFunction(CodeGenModule &cgm); @@ -483,6 +506,7 @@ public: llvm::Value *This); void PushCXXTemporary(const CXXTemporary *Temporary, llvm::Value *Ptr); + void PopCXXTemporary(); llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E); |