aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--lib/CodeGen/CGExprCXX.cpp25
1 files changed, 16 insertions, 9 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 30324b97ef..a39e82408d 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -172,11 +172,21 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
}
// Compute the object pointer.
+ const Expr *Base = ME->getBase();
+ bool CanUseVirtualCall = MD->isVirtual() && !ME->hasQualifier();
+ bool Devirtualize = CanUseVirtualCall &&
+ canDevirtualizeMemberFunctionCalls(getContext(), Base, MD);
+
+ const Expr *Inner = Base;
+ if (Devirtualize)
+ Inner = Base->ignoreParenBaseCasts();
+
llvm::Value *This;
if (ME->isArrow())
- This = EmitScalarExpr(ME->getBase());
+ This = EmitScalarExpr(Inner);
else
- This = EmitLValue(ME->getBase()).getAddress();
+ This = EmitLValue(Inner).getAddress();
+
if (MD->isTrivial()) {
if (isa<CXXDestructorDecl>(MD)) return RValue::get(0);
@@ -223,11 +233,8 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
//
// We also don't emit a virtual call if the base expression has a record type
// because then we know what the type is.
- const Expr *Base = ME->getBase();
- bool UseVirtualCall = MD->isVirtual() && !ME->hasQualifier()
- && !canDevirtualizeMemberFunctionCalls(getContext(),
- Base, MD);
- const CXXRecordDecl *MostDerivedClassDecl = Base->getBestDynamicClassType();
+ bool UseVirtualCall = CanUseVirtualCall && !Devirtualize;
+ const CXXRecordDecl *MostDerivedClassDecl = Inner->getBestDynamicClassType();
llvm::Value *Callee;
if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) {
@@ -238,7 +245,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
MD->isVirtual() &&
ME->hasQualifier())
Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty);
- else if (ME->hasQualifier())
+ else if (!Devirtualize)
Callee = CGM.GetAddrOfFunction(GlobalDecl(Dtor, Dtor_Complete), Ty);
else {
const CXXMethodDecl *DM =
@@ -258,7 +265,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
MD->isVirtual() &&
ME->hasQualifier())
Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty);
- else if (ME->hasQualifier())
+ else if (!Devirtualize)
Callee = CGM.GetAddrOfFunction(MD, Ty);
else {
const CXXMethodDecl *DerivedMethod =