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