diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-11-05 17:18:09 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-11-05 17:18:09 +0000 |
commit | b3a51061b1b9c4add078237850649f7c9efb13ab (patch) | |
tree | 8b316eca843681b024034db1125707173b9adb4a /lib/CodeGen | |
parent | b6d5e15aae202f157c6cd63da8fa4b089e7b31e9 (diff) | |
download | FreeBSD-src-b3a51061b1b9c4add078237850649f7c9efb13ab.zip FreeBSD-src-b3a51061b1b9c4add078237850649f7c9efb13ab.tar.gz |
Update clang to r86140.
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 30 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 10 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 37 |
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. |