Add CXXDynamicCastExpr::isAlwaysNull() which will be replacing the cast kind I added.

llvm-svn: 129263
This commit is contained in:
Anders Carlsson 2011-04-11 01:43:55 +00:00
parent 882d790f72
commit 267c0c930e
2 changed files with 32 additions and 0 deletions

View File

@ -253,6 +253,8 @@ public:
static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context,
unsigned pathSize);
bool isAlwaysNull() const;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDynamicCastExprClass;
}

View File

@ -482,6 +482,36 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C,
return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
}
/// isAlwaysNull - Return whether the result of the dynamic_cast is proven
/// to always be null. For example:
///
/// struct A { };
/// struct B final : A { };
/// struct C { };
///
/// C *f(B* b) { return dynamic_cast<C*>(b); }
bool CXXDynamicCastExpr::isAlwaysNull() const
{
QualType SrcType = getSubExpr()->getType();
QualType DestType = getType();
if (const PointerType *SrcPTy = SrcType->getAs<PointerType>()) {
SrcType = SrcPTy->getPointeeType();
DestType = DestType->castAs<PointerType>()->getPointeeType();
}
const CXXRecordDecl *SrcRD =
cast<CXXRecordDecl>(SrcType->castAs<RecordType>()->getDecl());
if (!SrcRD->hasAttr<FinalAttr>())
return false;
const CXXRecordDecl *DestRD =
cast<CXXRecordDecl>(DestType->castAs<RecordType>()->getDecl());
return !DestRD->isDerivedFrom(SrcRD);
}
CXXReinterpretCastExpr *
CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
CastKind K, Expr *Op,