[cfe-commits] r127702 - in /cfe/trunk: lib/CodeGen/CGExprConstant.cpp test/CodeGenCXX/member-function-pointers.cpp
John McCall
rjmccall at apple.com
Wed Mar 16 14:40:22 PDT 2011
On Mar 16, 2011, at 2:33 PM, Matt Beaumont-Gay wrote:
> Hi John,
> '
> On Tue, Mar 15, 2011 at 14:17, John McCall <rjmccall at apple.com> wrote:
>> Author: rjmccall
>> Date: Tue Mar 15 16:17:48 2011
>> New Revision: 127702
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=127702&view=rev
>> Log:
>> Reorganize the emission of (unfoldable) constant casts a bit, and
>> make sure that upcasts of member pointer types are covered as constants.
>> Fixed rdar://problem/9130221
>>
>>
>> Modified:
>> cfe/trunk/lib/CodeGen/CGExprConstant.cpp
>> cfe/trunk/test/CodeGenCXX/member-function-pointers.cpp
>>
>> Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=127702&r1=127701&r2=127702&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Mar 15 16:17:48 2011
>> @@ -483,18 +483,17 @@
>> }
>>
>> llvm::Constant *VisitCastExpr(CastExpr* E) {
>> + Expr *subExpr = E->getSubExpr();
>> + llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF);
>> + if (!C) return 0;
>> +
>> + const llvm::Type *destType = ConvertType(E->getType());
>> +
>> switch (E->getCastKind()) {
>> case CK_ToUnion: {
>> // GCC cast to union extension
>> assert(E->getType()->isUnionType() &&
>> "Destination type is not union type!");
>> - const llvm::Type *Ty = ConvertType(E->getType());
>> - Expr *SubExpr = E->getSubExpr();
>> -
>> - llvm::Constant *C =
>> - CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
>> - if (!C)
>> - return 0;
>>
>> // Build a struct with the union sub-element as the first member,
>> // and padded to the appropriate size
>> @@ -503,7 +502,7 @@
>> Elts.push_back(C);
>> Types.push_back(C->getType());
>> unsigned CurSize = CGM.getTargetData().getTypeAllocSize(C->getType());
>> - unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(Ty);
>> + unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(destType);
>>
>> assert(CurSize <= TotalSize && "Union size mismatch!");
>> if (unsigned NumPadBytes = TotalSize - CurSize) {
>> @@ -523,39 +522,101 @@
>> const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
>> return CGM.getCXXABI().EmitNullMemberPointer(MPT);
>> }
>> -
>> - case CK_BaseToDerivedMemberPointer: {
>> - Expr *SubExpr = E->getSubExpr();
>> - llvm::Constant *C =
>> - CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
>> - if (!C) return 0;
>>
>> + case CK_DerivedToBaseMemberPointer:
>> + case CK_BaseToDerivedMemberPointer:
>> return CGM.getCXXABI().EmitMemberPointerConversion(C, E);
>> - }
>>
>> - case CK_BitCast:
>> - // This must be a member function pointer cast.
>> - return Visit(E->getSubExpr());
>> -
>> - default: {
>> - // FIXME: This should be handled by the CK_NoOp cast kind.
>> - // Explicit and implicit no-op casts
>> - QualType Ty = E->getType(), SubTy = E->getSubExpr()->getType();
>> - if (CGM.getContext().hasSameUnqualifiedType(Ty, SubTy))
>> - return Visit(E->getSubExpr());
>> -
>> - // Handle integer->integer casts for address-of-label differences.
>> - if (Ty->isIntegerType() && SubTy->isIntegerType() &&
>> - CGF) {
>> - llvm::Value *Src = Visit(E->getSubExpr());
>> - if (Src == 0) return 0;
>> -
>> - // Use EmitScalarConversion to perform the conversion.
>> - return cast<llvm::Constant>(CGF->EmitScalarConversion(Src, SubTy, Ty));
>> - }
>> -
>> + case CK_LValueToRValue:
>> + case CK_NoOp:
>> + return C;
>> +
>> + case CK_AnyPointerToObjCPointerCast:
>> + case CK_AnyPointerToBlockPointerCast:
>> + case CK_LValueBitCast:
>> + case CK_BitCast:
>> + if (C->getType() == destType) return C;
>> + return llvm::ConstantExpr::getBitCast(C, destType);
>> +
>> + case CK_Dependent: llvm_unreachable("saw dependent cast!");
>> +
>> + // These will never be supported.
>> + case CK_ObjCObjectLValueCast:
>> + case CK_GetObjCProperty:
>> + case CK_ToVoid:
>> + case CK_Dynamic:
>> return 0;
>> +
>> + // These might need to be supported for constexpr.
>> + case CK_UserDefinedConversion:
>> + case CK_ConstructorConversion:
>> + return 0;
>> +
>> + // These should eventually be supported.
>> + case CK_ArrayToPointerDecay:
>> + case CK_FunctionToPointerDecay:
>> + case CK_BaseToDerived:
>> + case CK_DerivedToBase:
>> + case CK_UncheckedDerivedToBase:
>> + case CK_MemberPointerToBoolean:
>> + case CK_VectorSplat:
>> + case CK_FloatingRealToComplex:
>> + case CK_FloatingComplexToReal:
>> + case CK_FloatingComplexToBoolean:
>> + case CK_FloatingComplexCast:
>> + case CK_FloatingComplexToIntegralComplex:
>> + case CK_IntegralRealToComplex:
>> + case CK_IntegralComplexToReal:
>> + case CK_IntegralComplexToBoolean:
>> + case CK_IntegralComplexCast:
>> + case CK_IntegralComplexToFloatingComplex:
>> + return 0;
>> +
>> + case CK_PointerToIntegral:
>> + if (!E->getType()->isBooleanType())
>> + return llvm::ConstantExpr::getPtrToInt(C, destType);
>> + // fallthrough
>> +
>> + case CK_PointerToBoolean:
>> + return llvm::ConstantExpr::getICmp(llvm::CmpInst::ICMP_EQ, C,
>> + llvm::ConstantPointerNull::get(cast<llvm::PointerType>(C->getType())));
>> +
>> + case CK_NullToPointer:
>> + return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(destType));
>> +
>> + case CK_IntegralCast: {
>> + bool isSigned = subExpr->getType()->isSignedIntegerType();
>> + return llvm::ConstantExpr::getIntegerCast(C, destType, isSigned);
>> + }
>> +
>> + case CK_IntegralToPointer: {
>> + bool isSigned = subExpr->getType()->isSignedIntegerType();
>> + C = llvm::ConstantExpr::getIntegerCast(C, CGM.IntPtrTy, isSigned);
>> + return llvm::ConstantExpr::getIntToPtr(C, destType);
>> }
>> +
>> + case CK_IntegralToBoolean:
>> + return llvm::ConstantExpr::getICmp(llvm::CmpInst::ICMP_EQ, C,
>> + llvm::Constant::getNullValue(C->getType()));
>> +
>> + case CK_IntegralToFloating:
>> + if (subExpr->getType()->isSignedIntegerType())
>> + return llvm::ConstantExpr::getSIToFP(C, destType);
>> + else
>> + return llvm::ConstantExpr::getUIToFP(C, destType);
>> +
>> + case CK_FloatingToIntegral:
>> + if (E->getType()->isSignedIntegerType())
>> + return llvm::ConstantExpr::getFPToSI(C, destType);
>> + else
>> + return llvm::ConstantExpr::getFPToUI(C, destType);
>> +
>> + case CK_FloatingToBoolean:
>> + return llvm::ConstantExpr::getFCmp(llvm::CmpInst::FCMP_UNE, C,
>> + llvm::Constant::getNullValue(C->getType()));
>> +
>> + case CK_FloatingCast:
>> + return llvm::ConstantExpr::getFPCast(C, destType);
>> }
>> }
>
> Here's the latest salvo in my continuing feud with GCC's -Wreturn-type:
> tools/clang/lib/CodeGen/CGExprConstant.cpp: In member function
> 'llvm::Constant*<unnamed>::ConstExprEmitter::VisitCastExpr(clang::CastExpr*)':
> tools/clang/lib/CodeGen/CGExprConstant.cpp:621: error: control reaches
> end of non-void function
>
> Is the new llvm_unreachable the right tool here? E.g.:
Yes, that should work. The old llvm_unreachable would have worked fine, too.
John.
More information about the cfe-commits
mailing list