aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-06-28 01:56:38 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-06-28 01:56:38 +0000
commit632fbaa22fbed7c090eb83775731bfff786c2198 (patch)
treee02eebca83c243b7b6dcb3be7a12807ea22cdb43 /lib/AST/Expr.cpp
parentd558b5238df74ef3cb76d7125375a5c28fe0eaa9 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159326 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r--lib/AST/Expr.cpp38
1 files changed, 22 insertions, 16 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 15cf6602b7..b68f864711 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -34,21 +34,7 @@
using namespace clang;
const CXXRecordDecl *Expr::getBestDynamicClassType() const {
- const Expr *E = this;
-
- while (true) {
- E = E->IgnoreParens();
- if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
- if (CE->getCastKind() == CK_DerivedToBase ||
- CE->getCastKind() == CK_UncheckedDerivedToBase ||
- CE->getCastKind() == CK_NoOp) {
- E = CE->getSubExpr();
- continue;
- }
- }
-
- break;
- }
+ const Expr *E = ignoreParenBaseCasts();
QualType DerivedType = E->getType();
if (const PointerType *PTy = DerivedType->getAs<PointerType>())
@@ -2231,7 +2217,27 @@ Expr *Expr::IgnoreParenLValueCasts() {
}
return E;
}
-
+
+Expr *Expr::ignoreParenBaseCasts() {
+ Expr *E = this;
+ while (true) {
+ if (ParenExpr *P = dyn_cast<ParenExpr>(E)) {
+ E = P->getSubExpr();
+ continue;
+ }
+ if (CastExpr *CE = dyn_cast<CastExpr>(E)) {
+ if (CE->getCastKind() == CK_DerivedToBase ||
+ CE->getCastKind() == CK_UncheckedDerivedToBase ||
+ CE->getCastKind() == CK_NoOp) {
+ E = CE->getSubExpr();
+ continue;
+ }
+ }
+
+ return E;
+ }
+}
+
Expr *Expr::IgnoreParenImpCasts() {
Expr *E = this;
while (true) {