diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-11-03 18:55:18 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-11-03 18:55:18 +0000 |
commit | 018ac39f942585a32d4809bb5b014af4c3c60dea (patch) | |
tree | fab0332b9c58d1cba86f98081f94edf04d77613c /clang/lib/AST/Expr.cpp | |
parent | f9fb2abb01ea82a43b5938e3a24de9d8c6790e46 (diff) | |
download | bcm5719-llvm-018ac39f942585a32d4809bb5b014af4c3c60dea.tar.gz bcm5719-llvm-018ac39f942585a32d4809bb5b014af4c3c60dea.zip |
Improve obvious-most-derived-type devirtualization:
* if the base is produced by a series of derived-to-base conversions, check
the expression inside them when looking for an expression with a known
dynamic type
* step past MaterializeTemporaryExprs when checking for a known dynamic type
* when checking for a known dynamic type, treat all class prvalues as having
a known dynamic type after skipping all relevant rvalue subobject
adjustments
* treat callees formed by pointer-to-member access for a non-reference member
type like callees formed by member access.
llvm-svn: 285954
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 9cf9e86c4f4..53ab5cfd58b 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -35,9 +35,33 @@ #include <cstring> using namespace clang; -const CXXRecordDecl *Expr::getBestDynamicClassType() const { - const Expr *E = ignoreParenBaseCasts(); +const Expr *Expr::getBestDynamicClassTypeExpr() const { + const Expr *E = this; + while (true) { + E = E->ignoreParenBaseCasts(); + + // Follow the RHS of a comma operator. + if (auto *BO = dyn_cast<BinaryOperator>(E)) { + if (BO->getOpcode() == BO_Comma) { + E = BO->getRHS(); + continue; + } + } + // Step into initializer for materialized temporaries. + if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) { + E = MTE->GetTemporaryExpr(); + continue; + } + + break; + } + + return E; +} + +const CXXRecordDecl *Expr::getBestDynamicClassType() const { + const Expr *E = getBestDynamicClassTypeExpr(); QualType DerivedType = E->getType(); if (const PointerType *PTy = DerivedType->getAs<PointerType>()) DerivedType = PTy->getPointeeType(); |