diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-11-16 21:33:53 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-11-16 21:33:53 +0000 |
commit | ad35a83102683b00a7e28707eee7f2d8c994b742 (patch) | |
tree | 08529642cdaa194fbb2faa52283f9eb65e3726dc /lib | |
parent | 81c2e60a56d4728c3f4a595f3ff511a1cfa6ed9c (diff) |
Clean up scalar cast kind handling; make cast kind handling explicitly handle
more cases. No intended visible change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88968 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 97 |
1 files changed, 61 insertions, 36 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index f81aae97aa..5d5cd739a6 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -765,49 +765,20 @@ Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) { switch (Kind) { default: - // FIXME: Assert here. - // assert(0 && "Unhandled cast kind!"); + //return CGF.ErrorUnsupported(E, "type of cast"); break; + case CastExpr::CK_Unknown: - // FIXME: We should really assert here - Unknown casts should never get - // as far as to codegen. + //assert(0 && "Unknown cast kind!"); break; + case CastExpr::CK_BitCast: { Value *Src = Visit(const_cast<Expr*>(E)); return Builder.CreateBitCast(Src, ConvertType(DestTy)); } - case CastExpr::CK_ArrayToPointerDecay: { - assert(E->getType()->isArrayType() && - "Array to pointer decay must have array source type!"); - - Value *V = EmitLValue(E).getAddress(); // Bitfields can't be arrays. - - // Note that VLA pointers are always decayed, so we don't need to do - // anything here. - if (!E->getType()->isVariableArrayType()) { - assert(isa<llvm::PointerType>(V->getType()) && "Expected pointer"); - assert(isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType()) - ->getElementType()) && - "Expected pointer to array"); - V = Builder.CreateStructGEP(V, 0, "arraydecay"); - } + case CastExpr::CK_NoOp: + return Visit(const_cast<Expr*>(E)); - // The resultant pointer type can be implicitly casted to other pointer - // types as well (e.g. void*) and can be implicitly converted to integer. - const llvm::Type *DestLTy = ConvertType(DestTy); - if (V->getType() != DestLTy) { - if (isa<llvm::PointerType>(DestLTy)) - V = Builder.CreateBitCast(V, DestLTy, "ptrconv"); - else { - assert(isa<llvm::IntegerType>(DestLTy) && "Unknown array decay"); - V = Builder.CreatePtrToInt(V, DestLTy, "ptrconv"); - } - } - return V; - } - case CastExpr::CK_NullToMemberPointer: - return CGF.CGM.EmitNullConstant(DestTy); - case CastExpr::CK_DerivedToBase: { const RecordType *DerivedClassTy = E->getType()->getAs<PointerType>()->getPointeeType()->getAs<RecordType>(); @@ -833,6 +804,33 @@ Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) { return CGF.GetAddressCXXOfBaseClass(Src, DerivedClassDecl, BaseClassDecl, NullCheckValue); } + case CastExpr::CK_ToUnion: { + assert(0 && "Should be unreachable!"); + break; + } + case CastExpr::CK_ArrayToPointerDecay: { + assert(E->getType()->isArrayType() && + "Array to pointer decay must have array source type!"); + + Value *V = EmitLValue(E).getAddress(); // Bitfields can't be arrays. + + // Note that VLA pointers are always decayed, so we don't need to do + // anything here. + if (!E->getType()->isVariableArrayType()) { + assert(isa<llvm::PointerType>(V->getType()) && "Expected pointer"); + assert(isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType()) + ->getElementType()) && + "Expected pointer to array"); + V = Builder.CreateStructGEP(V, 0, "arraydecay"); + } + + return V; + } + case CastExpr::CK_FunctionToPointerDecay: + return EmitLValue(E).getAddress(); + + case CastExpr::CK_NullToMemberPointer: + return CGF.CGM.EmitNullConstant(DestTy); case CastExpr::CK_IntegralToPointer: { Value *Src = Visit(const_cast<Expr*>(E)); @@ -853,12 +851,39 @@ Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) { return Builder.CreatePtrToInt(Src, ConvertType(DestTy)); } + case CastExpr::CK_ToVoid: { + CGF.EmitAnyExpr(E, 0, false, true); + return 0; + } + case CastExpr::CK_Dynamic: { Value *V = Visit(const_cast<Expr*>(E)); const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(CE); return CGF.EmitDynamicCast(V, DCE); } - + + case CastExpr::CK_VectorSplat: { + const llvm::Type *DstTy = ConvertType(DestTy); + Value *Elt = Visit(const_cast<Expr*>(E)); + + // Insert the element in element zero of an undef vector + llvm::Value *UnV = llvm::UndefValue::get(DstTy); + llvm::Value *Idx = + llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0); + UnV = Builder.CreateInsertElement(UnV, Elt, Idx, "tmp"); + + // Splat the element across to all elements + llvm::SmallVector<llvm::Constant*, 16> Args; + unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements(); + for (unsigned i = 0; i < NumElements; i++) + Args.push_back(llvm::ConstantInt::get( + llvm::Type::getInt32Ty(VMContext), 0)); + + llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements); + llvm::Value *Yay = Builder.CreateShuffleVector(UnV, UnV, Mask, "splat"); + return Yay; + } + } // Handle cases where the source is an non-complex type. |