forked from OSchip/llvm-project
This patch extends CleanupScope to support destruction
of array objects on block exit. Patch is by Anders Calrsson. llvm-svn: 86032
This commit is contained in:
parent
2de8f4149e
commit
09cc10f9f8
|
@ -515,18 +515,22 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
|
|||
const CXXDestructorDecl *D = ClassDecl->getDestructor(getContext());
|
||||
assert(D && "EmitLocalBlockVarDecl - destructor is nul");
|
||||
|
||||
CleanupScope scope(*this);
|
||||
if (const ConstantArrayType *Array =
|
||||
getContext().getAsConstantArrayType(Ty)) {
|
||||
CleanupScope Scope(*this);
|
||||
QualType BaseElementTy = getContext().getBaseElementType(Array);
|
||||
const llvm::Type *BasePtr = ConvertType(BaseElementTy);
|
||||
BasePtr = llvm::PointerType::getUnqual(BasePtr);
|
||||
llvm::Value *BaseAddrPtr =
|
||||
Builder.CreateBitCast(DeclPtr, BasePtr);
|
||||
EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
|
||||
}
|
||||
else
|
||||
|
||||
// Make sure to jump to the exit block.
|
||||
EmitBranch(Scope.getCleanupExitBlock());
|
||||
} else {
|
||||
CleanupScope Scope(*this);
|
||||
EmitCXXDestructorCall(D, Dtor_Complete, DeclPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -665,8 +665,9 @@ llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) {
|
|||
return EmitLValue(E).getAddress();
|
||||
}
|
||||
|
||||
void CodeGenFunction::PushCleanupBlock(llvm::BasicBlock *CleanupBlock) {
|
||||
CleanupEntries.push_back(CleanupEntry(CleanupBlock));
|
||||
void CodeGenFunction::PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock,
|
||||
llvm::BasicBlock *CleanupExitBlock) {
|
||||
CleanupEntries.push_back(CleanupEntry(CleanupEntryBlock, CleanupExitBlock));
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) {
|
||||
|
@ -680,7 +681,7 @@ void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) {
|
|||
CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
|
||||
CleanupEntry &CE = CleanupEntries.back();
|
||||
|
||||
llvm::BasicBlock *CleanupBlock = CE.CleanupBlock;
|
||||
llvm::BasicBlock *CleanupEntryBlock = CE.CleanupEntryBlock;
|
||||
|
||||
std::vector<llvm::BasicBlock *> Blocks;
|
||||
std::swap(Blocks, CE.Blocks);
|
||||
|
@ -711,10 +712,11 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
|
|||
}
|
||||
}
|
||||
|
||||
llvm::BasicBlock *SwitchBlock = 0;
|
||||
llvm::BasicBlock *SwitchBlock = CE.CleanupExitBlock;
|
||||
llvm::BasicBlock *EndBlock = 0;
|
||||
if (!BranchFixups.empty()) {
|
||||
SwitchBlock = createBasicBlock("cleanup.switch");
|
||||
if (!SwitchBlock)
|
||||
SwitchBlock = createBasicBlock("cleanup.switch");
|
||||
EndBlock = createBasicBlock("cleanup.end");
|
||||
|
||||
llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
|
@ -745,7 +747,7 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
|
|||
llvm::BasicBlock *Dest = BI->getSuccessor(0);
|
||||
|
||||
// Fixup the branch instruction to point to the cleanup block.
|
||||
BI->setSuccessor(0, CleanupBlock);
|
||||
BI->setSuccessor(0, CleanupEntryBlock);
|
||||
|
||||
if (CleanupEntries.empty()) {
|
||||
llvm::ConstantInt *ID;
|
||||
|
@ -802,7 +804,7 @@ CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() {
|
|||
BlockScopes.erase(Blocks[i]);
|
||||
}
|
||||
|
||||
return CleanupBlockInfo(CleanupBlock, SwitchBlock, EndBlock);
|
||||
return CleanupBlockInfo(CleanupEntryBlock, SwitchBlock, EndBlock);
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitCleanupBlock() {
|
||||
|
|
|
@ -108,11 +108,12 @@ public:
|
|||
|
||||
/// PushCleanupBlock - Push a new cleanup entry on the stack and set the
|
||||
/// passed in block as the cleanup block.
|
||||
void PushCleanupBlock(llvm::BasicBlock *CleanupBlock);
|
||||
void PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock,
|
||||
llvm::BasicBlock *CleanupExitBlock = 0);
|
||||
|
||||
/// CleanupBlockInfo - A struct representing a popped cleanup block.
|
||||
struct CleanupBlockInfo {
|
||||
/// CleanupBlock - the cleanup block
|
||||
/// CleanupEntryBlock - the cleanup entry block
|
||||
llvm::BasicBlock *CleanupBlock;
|
||||
|
||||
/// SwitchBlock - the block (if any) containing the switch instruction used
|
||||
|
@ -138,17 +139,24 @@ public:
|
|||
class CleanupScope {
|
||||
CodeGenFunction& CGF;
|
||||
llvm::BasicBlock *CurBB;
|
||||
llvm::BasicBlock *CleanupBB;
|
||||
|
||||
llvm::BasicBlock *CleanupEntryBB;
|
||||
llvm::BasicBlock *CleanupExitBB;
|
||||
|
||||
public:
|
||||
CleanupScope(CodeGenFunction &cgf)
|
||||
: CGF(cgf), CurBB(CGF.Builder.GetInsertBlock()) {
|
||||
CleanupBB = CGF.createBasicBlock("cleanup");
|
||||
CGF.Builder.SetInsertPoint(CleanupBB);
|
||||
: CGF(cgf), CurBB(CGF.Builder.GetInsertBlock()),
|
||||
CleanupEntryBB(CGF.createBasicBlock("cleanup")), CleanupExitBB(0) {
|
||||
CGF.Builder.SetInsertPoint(CleanupEntryBB);
|
||||
}
|
||||
|
||||
llvm::BasicBlock *getCleanupExitBlock() {
|
||||
if (!CleanupExitBB)
|
||||
CleanupExitBB = CGF.createBasicBlock("cleanup.exit");
|
||||
return CleanupExitBB;
|
||||
}
|
||||
|
||||
~CleanupScope() {
|
||||
CGF.PushCleanupBlock(CleanupBB);
|
||||
CGF.PushCleanupBlock(CleanupEntryBB, CleanupExitBB);
|
||||
// FIXME: This is silly, move this into the builder.
|
||||
if (CurBB)
|
||||
CGF.Builder.SetInsertPoint(CurBB);
|
||||
|
@ -250,9 +258,12 @@ private:
|
|||
bool DidCallStackSave;
|
||||
|
||||
struct CleanupEntry {
|
||||
/// CleanupBlock - The block of code that does the actual cleanup.
|
||||
llvm::BasicBlock *CleanupBlock;
|
||||
/// CleanupEntryBlock - The block of code that does the actual cleanup.
|
||||
llvm::BasicBlock *CleanupEntryBlock;
|
||||
|
||||
/// CleanupExitBlock - The cleanup exit block.
|
||||
llvm::BasicBlock *CleanupExitBlock;
|
||||
|
||||
/// Blocks - Basic blocks that were emitted in the current cleanup scope.
|
||||
std::vector<llvm::BasicBlock *> Blocks;
|
||||
|
||||
|
@ -260,8 +271,10 @@ private:
|
|||
/// inserted into the current function yet.
|
||||
std::vector<llvm::BranchInst *> BranchFixups;
|
||||
|
||||
explicit CleanupEntry(llvm::BasicBlock *cb)
|
||||
: CleanupBlock(cb) {}
|
||||
explicit CleanupEntry(llvm::BasicBlock *CleanupEntryBlock,
|
||||
llvm::BasicBlock *CleanupExitBlock)
|
||||
: CleanupEntryBlock(CleanupEntryBlock),
|
||||
CleanupExitBlock(CleanupExitBlock) {}
|
||||
};
|
||||
|
||||
/// CleanupEntries - Stack of cleanup entries.
|
||||
|
|
|
@ -17,12 +17,9 @@ public:
|
|||
int i;
|
||||
float f;
|
||||
|
||||
/**
|
||||
NYI
|
||||
~xpto() {
|
||||
printf("xpto::~xpto()\n");
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
|
Loading…
Reference in New Issue