aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-08-22 10:59:02 +0000
committerJohn McCall <rjmccall@apple.com>2010-08-22 10:59:02 +0000
commitd608cdb7c044365cf4e8764ade1e11e99c176078 (patch)
tree64048b57b20b73f88b0d6dc576241554929236cf /lib/CodeGen/CGExprScalar.cpp
parente9fd7eb6c67676dc27e84eac429aec4f3be51f26 (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.cpp29
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());