diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-28 01:56:38 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-28 01:56:38 +0000 |
commit | ecbe2e97954b6f6bb6093f3ce7e9bb7936cf7f9b (patch) | |
tree | 17c25f988b97475140499e7e5ac62d0371241e80 /clang/lib/CodeGen/CGExprCXX.cpp | |
parent | 0743f946710623cfb55d3ccdb2e89458adc60265 (diff) | |
download | bcm5719-llvm-ecbe2e97954b6f6bb6093f3ce7e9bb7936cf7f9b.tar.gz bcm5719-llvm-ecbe2e97954b6f6bb6093f3ce7e9bb7936cf7f9b.zip |
Fix another issue with devirtualizing calls to final methods by passing them
the correct this pointer. There is some potential for sharing a bit more
code with canDevirtualizeMemberFunctionCalls, but that can be done in an
independent patch.
llvm-svn: 159326
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 30324b97ef1..a39e82408d0 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/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 = |