summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-11-05 17:18:09 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-11-05 17:18:09 +0000
commitb3a51061b1b9c4add078237850649f7c9efb13ab (patch)
tree8b316eca843681b024034db1125707173b9adb4a /lib/CodeGen
parentb6d5e15aae202f157c6cd63da8fa4b089e7b31e9 (diff)
downloadFreeBSD-src-b3a51061b1b9c4add078237850649f7c9efb13ab.zip
FreeBSD-src-b3a51061b1b9c4add078237850649f7c9efb13ab.tar.gz
Update clang to r86140.
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGCXX.cpp30
-rw-r--r--lib/CodeGen/CGDecl.cpp10
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp16
-rw-r--r--lib/CodeGen/CodeGenFunction.h37
4 files changed, 69 insertions, 24 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 3e854ca..cf172b1 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -291,7 +291,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E) {
const FunctionProtoType *FPT =
MPT->getPointeeType()->getAs<FunctionProtoType>();
const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(cast<RecordType>(MPT->getClass())->getDecl());
+ cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
const llvm::FunctionType *FTy =
CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),
@@ -810,8 +810,32 @@ llvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
Callee, CallArgs, MD);
if (nv_r || v_r) {
+ bool CanBeZero = !(ResultType->isReferenceType()
+ // FIXME: attr nonnull can't be zero either
+ /* || ResultType->hasAttr<NonNullAttr>() */ );
// Do the return result adjustment.
- RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r));
+ if (CanBeZero) {
+ llvm::BasicBlock *NonZeroBlock = createBasicBlock();
+ llvm::BasicBlock *ZeroBlock = createBasicBlock();
+ llvm::BasicBlock *ContBlock = createBasicBlock();
+
+ const llvm::Type *Ty = RV.getScalarVal()->getType();
+ llvm::Value *Zero = llvm::Constant::getNullValue(Ty);
+ Builder.CreateCondBr(Builder.CreateICmpNE(RV.getScalarVal(), Zero),
+ NonZeroBlock, ZeroBlock);
+ EmitBlock(NonZeroBlock);
+ llvm::Value *NZ = DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r);
+ EmitBranch(ContBlock);
+ EmitBlock(ZeroBlock);
+ llvm::Value *Z = RV.getScalarVal();
+ EmitBlock(ContBlock);
+ llvm::PHINode *RVOrZero = Builder.CreatePHI(Ty);
+ RVOrZero->reserveOperandSpace(2);
+ RVOrZero->addIncoming(NZ, NonZeroBlock);
+ RVOrZero->addIncoming(Z, ZeroBlock);
+ RV = RValue::get(RVOrZero);
+ } else
+ RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r));
}
if (!ResultType->isVoidType())
@@ -1421,6 +1445,8 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
if (FieldType->isReferenceType())
RHS = EmitReferenceBindingToExpr(RhsExpr, FieldType,
/*IsInitializer=*/true);
+ else if (FieldType->isMemberFunctionPointerType())
+ RHS = RValue::get(CGM.EmitConstantExpr(RhsExpr, FieldType, this));
else
RHS = RValue::get(EmitScalarExpr(RhsExpr, true));
EmitStoreThroughLValue(RHS, LHS, FieldType);
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index b1ceb46..2021ced 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -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);
+ }
}
}
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 88beadf..4be3413 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -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() {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 9bb2196..fe8113e 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -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.
OpenPOWER on IntegriCloud