Introduce a CXXTemporariesCleanupScope RAII object and use it to cleanup the temporaries code.

llvm-svn: 99865
This commit is contained in:
Anders Carlsson
2010-03-30 03:14:41 +00:00
parent 10834b8d56
commit b9fd57f198
3 changed files with 49 additions and 33 deletions

View File

@@ -550,29 +550,27 @@ void CodeGenFunction::EmitClassMemberwiseCopy(
CallArgs.push_back(std::make_pair(RValue::get(Src),
BaseCopyCtor->getParamDecl(0)->getType()));
unsigned OldNumLiveTemporaries = LiveTemporaries.size();
{
CXXTemporariesCleanupScope Scope(*this);
// If the copy constructor has default arguments, emit them.
for (unsigned I = 1, E = BaseCopyCtor->getNumParams(); I < E; ++I) {
const ParmVarDecl *Param = BaseCopyCtor->getParamDecl(I);
const Expr *DefaultArgExpr = Param->getDefaultArg();
assert(DefaultArgExpr && "Ctor parameter must have default arg!");
// If the copy constructor has default arguments, emit them.
for (unsigned I = 1, E = BaseCopyCtor->getNumParams(); I < E; ++I) {
const ParmVarDecl *Param = BaseCopyCtor->getParamDecl(I);
const Expr *DefaultArgExpr = Param->getDefaultArg();
QualType ArgType = Param->getType();
CallArgs.push_back(std::make_pair(EmitCallArg(DefaultArgExpr, ArgType),
ArgType));
assert(DefaultArgExpr && "Ctor parameter must have default arg!");
QualType ArgType = Param->getType();
CallArgs.push_back(std::make_pair(EmitCallArg(DefaultArgExpr, ArgType),
ArgType));
}
const FunctionProtoType *FPT =
BaseCopyCtor->getType()->getAs<FunctionProtoType>();
EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
}
const FunctionProtoType *FPT =
BaseCopyCtor->getType()->getAs<FunctionProtoType>();
EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
// Pop temporaries.
while (LiveTemporaries.size() > OldNumLiveTemporaries)
PopCXXTemporary();
}
}
@@ -1306,14 +1304,12 @@ CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
// before the construction of the next array element, if any.
// Keep track of the current number of live temporaries.
unsigned OldNumLiveTemporaries = LiveTemporaries.size();
{
CXXTemporariesCleanupScope Scope(*this);
EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
EmitCXXConstructorCall(D, Ctor_Complete, Address, ArgBeg, ArgEnd);
}
// Pop temporaries.
while (LiveTemporaries.size() > OldNumLiveTemporaries)
PopCXXTemporary();
EmitBlock(ContinueBlock);
// Emit the increment of the loop counter.

View File

@@ -127,15 +127,14 @@ CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
size_t CleanupStackDepth = CleanupEntries.size();
(void) CleanupStackDepth;
unsigned OldNumLiveTemporaries = LiveTemporaries.size();
RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
/*IgnoreResult=*/false, IsInitializer);
// Pop temporaries.
while (LiveTemporaries.size() > OldNumLiveTemporaries)
PopCXXTemporary();
RValue RV;
{
CXXTemporariesCleanupScope Scope(*this);
RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
/*IgnoreResult=*/false, IsInitializer);
}
assert(CleanupEntries.size() == CleanupStackDepth &&
"Cleanup size mismatch!");

View File

@@ -254,6 +254,27 @@ public:
}
};
/// CXXTemporariesCleanupScope - Enters a new scope for catching live
/// temporaries, all of which will be popped once the scope is exited.
class CXXTemporariesCleanupScope {
CodeGenFunction &CGF;
size_t NumLiveTemporaries;
// DO NOT IMPLEMENT
CXXTemporariesCleanupScope(const CXXTemporariesCleanupScope &);
CXXTemporariesCleanupScope &operator=(const CXXTemporariesCleanupScope &);
public:
explicit CXXTemporariesCleanupScope(CodeGenFunction &CGF)
: CGF(CGF), NumLiveTemporaries(CGF.LiveTemporaries.size()) { }
~CXXTemporariesCleanupScope() {
while (CGF.LiveTemporaries.size() > NumLiveTemporaries)
CGF.PopCXXTemporary();
}
};
/// EmitCleanupBlocks - Takes the old cleanup stack size and emits the cleanup
/// blocks that have been added.
void EmitCleanupBlocks(size_t OldCleanupStackSize);