diff options
author | John McCall <rjmccall@apple.com> | 2010-08-22 10:59:02 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-08-22 10:59:02 +0000 |
commit | d608cdb7c044365cf4e8764ade1e11e99c176078 (patch) | |
tree | 64048b57b20b73f88b0d6dc576241554929236cf /lib/CodeGen/CGExprScalar.cpp | |
parent | e9fd7eb6c67676dc27e84eac429aec4f3be51f26 (diff) |
Experiment with using first-class aggregates to represent member function
pointers. I find the resulting code to be substantially cleaner, and it
makes it very easy to use the same APIs for data member pointers (which I have
conscientiously avoided here), and it avoids a plethora of potential
inefficiencies due to excessive memory copying, but we'll have to see if it
actually works.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111776 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index d65c22a723..38a49ee138 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -238,6 +238,9 @@ public: Value *VisitUnaryAddrOf(const UnaryOperator *E) { + // If the sub-expression is an instance member reference, + // EmitDeclRefLValue will magically emit it with the appropriate + // value as the "address". return EmitLValue(E->getSubExpr()).getAddress(); } Value *VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } @@ -995,11 +998,31 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { return EmitLValue(E).getAddress(); case CastExpr::CK_NullToMemberPointer: + // If the subexpression's type is the C++0x nullptr_t, emit the + // subexpression, which may have side effects. + if (E->getType()->isNullPtrType()) + (void) Visit(E); + + if (CE->getType()->isMemberFunctionPointerType()) + return CGF.CGM.getCXXABI().EmitNullMemberFunctionPointer( + CE->getType()->getAs<MemberPointerType>()); + return CGF.CGM.EmitNullConstant(DestTy); case CastExpr::CK_BaseToDerivedMemberPointer: case CastExpr::CK_DerivedToBaseMemberPointer: { Value *Src = Visit(E); + + // Note that the AST doesn't distinguish between checked and + // unchecked member pointer conversions, so we always have to + // implement checked conversions here. This is inefficient when + // actual control flow may be required in order to perform the + // check, which it is for data member pointers (but not member + // function pointers on Itanium and ARM). + + if (CE->getType()->isMemberFunctionPointerType()) + return CGF.CGM.getCXXABI().EmitMemberFunctionPointerConversion(CGF, CE, + Src); // See if we need to adjust the pointer. const CXXRecordDecl *BaseDecl = @@ -1804,10 +1827,10 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc, if (LHSTy->isMemberFunctionPointerType()) { assert(E->getOpcode() == BinaryOperator::EQ || E->getOpcode() == BinaryOperator::NE); - Value *LHSPtr = CGF.EmitAnyExprToTemp(E->getLHS()).getAggregateAddr(); - Value *RHSPtr = CGF.EmitAnyExprToTemp(E->getRHS()).getAggregateAddr(); + Value *LHS = CGF.EmitScalarExpr(E->getLHS()); + Value *RHS = CGF.EmitScalarExpr(E->getRHS()); Result = CGF.CGM.getCXXABI().EmitMemberFunctionPointerComparison( - CGF, LHSPtr, RHSPtr, LHSTy->getAs<MemberPointerType>(), + CGF, LHS, RHS, LHSTy->getAs<MemberPointerType>(), E->getOpcode() == BinaryOperator::NE); } else if (!LHSTy->isAnyComplexType()) { Value *LHS = Visit(E->getLHS()); |