diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 24 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 4 |
3 files changed, 32 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 047fecdc207..d8fc3146894 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -773,7 +773,27 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E, } llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) { - // Always return an LLVM null constant for now; this will change when we - // get support for IRGen of member pointers. + if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(T)) { + + QualType ElementTy = CAT->getElementType(); + + // FIXME: Handle arrays of structs that contain member pointers. + if (Context.getBaseElementType(ElementTy)->isMemberPointerType()) { + llvm::Constant *Element = EmitNullConstant(ElementTy); + uint64_t NumElements = CAT->getSize().getZExtValue(); + std::vector<llvm::Constant *> Array(NumElements); + for (uint64_t i = 0; i != NumElements; ++i) + Array[i] = Element; + + const llvm::ArrayType *ATy = + cast<llvm::ArrayType>(getTypes().ConvertTypeForMem(T)); + return llvm::ConstantArray::get(ATy, Array); + } + } + + // FIXME: Handle structs that contain member pointers. + if (T->isMemberPointerType()) + return llvm::Constant::getAllOnesValue(getTypes().ConvertTypeForMem(T)); + return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T)); } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 44f4c27927b..e761e9f3c7d 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -391,6 +391,14 @@ Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) { return Builder.CreateFCmpUNE(Src, Zero, "tobool"); } + if (SrcType->isMemberPointerType()) { + // FIXME: This is ABI specific. + + // Compare against -1. + llvm::Value *NegativeOne = llvm::Constant::getAllOnesValue(Src->getType()); + return Builder.CreateICmpNE(Src, NegativeOne, "tobool"); + } + assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) && "Unknown scalar type to convert"); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 0b012592e4f..6135f65513d 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -68,9 +68,9 @@ const llvm::Type *CodeGenFunction::ConvertType(QualType T) { bool CodeGenFunction::hasAggregateLLVMType(QualType T) { // FIXME: Use positive checks instead of negative ones to be more robust in // the face of extension. - return !T->hasPointerRepresentation() &&!T->isRealType() && + return !T->hasPointerRepresentation() && !T->isRealType() && !T->isVoidType() && !T->isVectorType() && !T->isFunctionType() && - !T->isBlockPointerType(); + !T->isBlockPointerType() && !T->isMemberPointerType(); } void CodeGenFunction::EmitReturnBlock() { |