summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp121
1 files changed, 70 insertions, 51 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 96b58d8..e9bbf35 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -135,16 +135,8 @@ public:
}
Value *VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
-#ifndef USEINDIRECTBRANCH
- llvm::Value *V =
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGF.getLLVMContext()),
- CGF.GetIDForAddrOfLabel(E->getLabel()));
-
- return Builder.CreateIntToPtr(V, ConvertType(E->getType()));
-#else
llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
return Builder.CreateBitCast(V, ConvertType(E->getType()));
-#endif
}
// l-values.
@@ -356,6 +348,9 @@ public:
Value *VisitBinLOr (const BinaryOperator *E);
Value *VisitBinComma (const BinaryOperator *E);
+ Value *VisitBinPtrMemD(const Expr *E) { return EmitLoadOfLValue(E); }
+ Value *VisitBinPtrMemI(const Expr *E) { return EmitLoadOfLValue(E); }
+
// Other Operators.
Value *VisitBlockExpr(const BlockExpr *BE);
Value *VisitConditionalOperator(const ConditionalOperator *CO);
@@ -547,13 +542,6 @@ EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
//===----------------------------------------------------------------------===//
Value *ScalarExprEmitter::VisitExpr(Expr *E) {
- if (const BinaryOperator *BExpr = dyn_cast<BinaryOperator>(E))
- if (BExpr->getOpcode() == BinaryOperator::PtrMemD) {
- LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(BExpr);
- Value *InVal = CGF.EmitLoadOfLValue(LV, E->getType()).getScalarVal();
- return InVal;
- }
-
CGF.ErrorUnsupported(E, "scalar expression");
if (E->getType()->isVoidType())
return 0;
@@ -773,49 +761,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.
+ case CastExpr::CK_NoOp:
+ return Visit(const_cast<Expr*>(E));
- // 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");
- }
-
- // 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>();
@@ -841,6 +800,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));
@@ -860,7 +846,40 @@ Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) {
Value *Src = Visit(const_cast<Expr*>(E));
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.
OpenPOWER on IntegriCloud