summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-06-26 17:45:31 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-06-26 17:45:31 +0000
commit49e860b248add5ef49fc967a1b503da74b0c3f95 (patch)
treeac41883087d1bc0ef22cf4afbdb76799df67b58c /clang/lib/AST/Expr.cpp
parentf08ebab2ea6fae426aafa42bb5ffb7c5e625e4f7 (diff)
downloadbcm5719-llvm-49e860b248add5ef49fc967a1b503da74b0c3f95.tar.gz
bcm5719-llvm-49e860b248add5ef49fc967a1b503da74b0c3f95.zip
During codegen of a virtual call we would extract any casts in the expression
to see if we had an underlying final class or method, but we would then use the cast type to do the call, resulting in a direct call to the wrong method. llvm-svn: 159212
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r--clang/lib/AST/Expr.cpp31
1 files changed, 31 insertions, 0 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 3de4b5771a2..22d15be6a87 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -33,6 +33,37 @@
#include <cstring>
using namespace clang;
+const CXXRecordDecl *Expr::getMostDerivedClassDeclForType() 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;
+ }
+
+ QualType DerivedType = E->getType();
+ if (DerivedType->isDependentType())
+ return NULL;
+ if (const PointerType *PTy = DerivedType->getAs<PointerType>())
+ DerivedType = PTy->getPointeeType();
+
+ const RecordType *Ty = DerivedType->castAs<RecordType>();
+ if (!Ty)
+ return NULL;
+
+ Decl *D = Ty->getDecl();
+ return cast<CXXRecordDecl>(D);
+}
+
/// isKnownToHaveBooleanValue - Return true if this is an integer expression
/// that is known to return 0 or 1. This happens for _Bool/bool expressions
/// but also int expressions which are produced by things like comparisons in
OpenPOWER on IntegriCloud