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 | a1dee5300b3a0ad0c6e763d83d528ab0e6fc9c78 (patch) | |
tree | 2bce21ec67c8ff401bc950847fa406094f814865 /clang/lib/CodeGen/CGExprScalar.cpp | |
parent | 131d97d80923ab4a068ee8a5fc3dbed5c97bd15e (diff) | |
download | bcm5719-llvm-a1dee5300b3a0ad0c6e763d83d528ab0e6fc9c78.tar.gz bcm5719-llvm-a1dee5300b3a0ad0c6e763d83d528ab0e6fc9c78.zip |
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.
llvm-svn: 111776
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index d65c22a723a..38a49ee138d 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/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()); |