diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-26 17:45:31 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-26 17:45:31 +0000 |
commit | 49e860b248add5ef49fc967a1b503da74b0c3f95 (patch) | |
tree | ac41883087d1bc0ef22cf4afbdb76799df67b58c /clang/lib/AST/Expr.cpp | |
parent | f08ebab2ea6fae426aafa42bb5ffb7c5e625e4f7 (diff) | |
download | bcm5719-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.cpp | 31 |
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 |