From: David Blaikie Date: Thu, 21 Feb 2013 20:58:29 +0000 (+0000) Subject: Replace CFGElement llvm::cast support to be well-defined. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2a01f5d426c6bb0ef57c0a018942f6f6b179827a;p=platform%2Fupstream%2Fllvm.git Replace CFGElement llvm::cast support to be well-defined. See r175462 for another example/more details. llvm-svn: 175796 --- diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h index a065ef3..d6dc453 100644 --- a/clang/include/clang/Analysis/CFG.h +++ b/clang/include/clang/Analysis/CFG.h @@ -20,6 +20,7 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Allocator.h" @@ -72,6 +73,29 @@ protected: public: CFGElement() {} + /// \brief Convert to the specified CFGElement type, asserting that this + /// CFGElement is of the desired type. + template + T castAs() const { + assert(T::isKind(*this)); + T t; + CFGElement& e = t; + e = *this; + return t; + } + + /// \brief Convert to the specified CFGElement type, returning an invalid + /// CFGElement if this CFGElement is not of the desired type. + template + T getAs() const { + if (!T::isKind(*this)) + return T(); + T t; + CFGElement& e = t; + e = *this; + return t; + } + Kind getKind() const { unsigned x = Data2.getInt(); x <<= 2; @@ -82,14 +106,6 @@ public: bool isValid() const { return getKind() != Invalid; } operator bool() const { return isValid(); } - - template const ElemTy *getAs() const LLVM_LVALUE_FUNCTION { - return dyn_cast(this); - } - -#if LLVM_HAS_RVALUE_REFERENCE_THIS - template void getAs() && LLVM_DELETED_FUNCTION; -#endif }; class CFGStmt : public CFGElement { @@ -100,8 +116,11 @@ public: return static_cast(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == Statement; +private: + friend class CFGElement; + CFGStmt() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == Statement; } }; @@ -116,8 +135,11 @@ public: return static_cast(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == Initializer; +private: + friend class CFGElement; + CFGInitializer() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == Initializer; } }; @@ -125,6 +147,7 @@ public: /// by compiler on various occasions. class CFGImplicitDtor : public CFGElement { protected: + CFGImplicitDtor() {} CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0) : CFGElement(kind, data1, data2) { assert(kind >= DTOR_BEGIN && kind <= DTOR_END); @@ -134,8 +157,10 @@ public: const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const; bool isNoReturn(ASTContext &astContext) const; - static bool classof(const CFGElement *E) { - Kind kind = E->getKind(); +private: + friend class CFGElement; + static bool isKind(const CFGElement &E) { + Kind kind = E.getKind(); return kind >= DTOR_BEGIN && kind <= DTOR_END; } }; @@ -157,8 +182,11 @@ public: return static_cast(Data2.getPointer()); } - static bool classof(const CFGElement *elem) { - return elem->getKind() == AutomaticObjectDtor; +private: + friend class CFGElement; + CFGAutomaticObjDtor() {} + static bool isKind(const CFGElement &elem) { + return elem.getKind() == AutomaticObjectDtor; } }; @@ -173,8 +201,11 @@ public: return static_cast(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == BaseDtor; +private: + friend class CFGElement; + CFGBaseDtor() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == BaseDtor; } }; @@ -189,8 +220,11 @@ public: return static_cast(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == MemberDtor; +private: + friend class CFGElement; + CFGMemberDtor() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == MemberDtor; } }; @@ -205,8 +239,11 @@ public: return static_cast(Data1.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == TemporaryDtor; +private: + friend class CFGElement; + CFGTemporaryDtor() {} + static bool isKind(const CFGElement &E) { + return E.getKind() == TemporaryDtor; } }; @@ -720,8 +757,8 @@ public: for (const_iterator I=begin(), E=end(); I != E; ++I) for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end(); BI != BE; ++BI) { - if (const CFGStmt *stmt = BI->getAs()) - O(const_cast(stmt->getStmt())); + if (CFGStmt stmt = BI->getAs()) + O(const_cast(stmt.getStmt())); } } diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 01553b8..8754fe8 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -3338,7 +3338,7 @@ CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const { llvm_unreachable("getDestructorDecl should only be used with " "ImplicitDtors"); case CFGElement::AutomaticObjectDtor: { - const VarDecl *var = cast(this)->getVarDecl(); + const VarDecl *var = castAs().getVarDecl(); QualType ty = var->getType(); ty = ty.getNonReferenceType(); while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) { @@ -3351,7 +3351,7 @@ CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const { } case CFGElement::TemporaryDtor: { const CXXBindTemporaryExpr *bindExpr = - cast(this)->getBindTemporaryExpr(); + castAs().getBindTemporaryExpr(); const CXXTemporary *temp = bindExpr->getTemporary(); return temp->getDestructor(); } @@ -3406,8 +3406,8 @@ static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) { for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) - if (const CFGStmt *S = BI->getAs()) - FindSubExprAssignments(S->getStmt(), SubExprAssignments); + if (CFGStmt S = BI->getAs()) + FindSubExprAssignments(S.getStmt(), SubExprAssignments); for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) { @@ -3415,10 +3415,10 @@ static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) { // block-level that are block-level expressions. for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) { - const CFGStmt *CS = BI->getAs(); + CFGStmt CS = BI->getAs(); if (!CS) continue; - if (const Expr *Exp = dyn_cast(CS->getStmt())) { + if (const Expr *Exp = dyn_cast(CS.getStmt())) { assert((Exp->IgnoreParens() == Exp) && "No parens on block-level exps"); if (const BinaryOperator* B = dyn_cast(Exp)) { @@ -3531,8 +3531,8 @@ public: unsigned j = 1; for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ; BI != BEnd; ++BI, ++j ) { - if (const CFGStmt *SE = BI->getAs()) { - const Stmt *stmt= SE->getStmt(); + if (CFGStmt SE = BI->getAs()) { + const Stmt *stmt= SE.getStmt(); std::pair P((*I)->getBlockID(), j); StmtMap[stmt] = P; @@ -3721,8 +3721,8 @@ public: static void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper, const CFGElement &E) { - if (const CFGStmt *CS = E.getAs()) { - const Stmt *S = CS->getStmt(); + if (CFGStmt CS = E.getAs()) { + const Stmt *S = CS.getStmt(); if (Helper) { @@ -3769,8 +3769,8 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper, if (isa(S)) OS << '\n'; - } else if (const CFGInitializer *IE = E.getAs()) { - const CXXCtorInitializer *I = IE->getInitializer(); + } else if (CFGInitializer IE = E.getAs()) { + const CXXCtorInitializer *I = IE.getInitializer(); if (I->isBaseInitializer()) OS << I->getBaseClass()->getAsCXXRecordDecl()->getName(); else OS << I->getAnyMember()->getName(); @@ -3784,8 +3784,8 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper, OS << " (Base initializer)\n"; else OS << " (Member initializer)\n"; - } else if (const CFGAutomaticObjDtor *DE = E.getAs()){ - const VarDecl *VD = DE->getVarDecl(); + } else if (CFGAutomaticObjDtor DE = E.getAs()){ + const VarDecl *VD = DE.getVarDecl(); Helper->handleDecl(VD, OS); const Type* T = VD->getType().getTypePtr(); @@ -3796,20 +3796,20 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper, OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()"; OS << " (Implicit destructor)\n"; - } else if (const CFGBaseDtor *BE = E.getAs()) { - const CXXBaseSpecifier *BS = BE->getBaseSpecifier(); + } else if (CFGBaseDtor BE = E.getAs()) { + const CXXBaseSpecifier *BS = BE.getBaseSpecifier(); OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()"; OS << " (Base object destructor)\n"; - } else if (const CFGMemberDtor *ME = E.getAs()) { - const FieldDecl *FD = ME->getFieldDecl(); + } else if (CFGMemberDtor ME = E.getAs()) { + const FieldDecl *FD = ME.getFieldDecl(); const Type *T = FD->getType()->getBaseElementTypeUnsafe(); OS << "this->" << FD->getName(); OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()"; OS << " (Member object destructor)\n"; - } else if (const CFGTemporaryDtor *TE = E.getAs()) { - const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr(); + } else if (CFGTemporaryDtor TE = E.getAs()) { + const CXXBindTemporaryExpr *BT = TE.getBindTemporaryExpr(); OS << "~" << BT->getType()->getAsCXXRecordDecl()->getName() << "()"; OS << " (Temporary object destructor)\n"; } diff --git a/clang/lib/Analysis/CFGStmtMap.cpp b/clang/lib/Analysis/CFGStmtMap.cpp index 16df676..7daeef9 100644 --- a/clang/lib/Analysis/CFGStmtMap.cpp +++ b/clang/lib/Analysis/CFGStmtMap.cpp @@ -50,11 +50,11 @@ static void Accumulate(SMap &SM, CFGBlock *B) { // First walk the block-level expressions. for (CFGBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) { const CFGElement &CE = *I; - const CFGStmt *CS = CE.getAs(); + CFGStmt CS = CE.getAs(); if (!CS) continue; - CFGBlock *&Entry = SM[CS->getStmt()]; + CFGBlock *&Entry = SM[CS.getStmt()]; // If 'Entry' is already initialized (e.g., a terminator was already), // skip. if (Entry) diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index 1f616f7..519d528 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -474,15 +474,15 @@ LiveVariablesImpl::runOnBlock(const CFGBlock *block, ei = block->rend(); it != ei; ++it) { const CFGElement &elem = *it; - if (const CFGAutomaticObjDtor *Dtor = dyn_cast(&elem)){ - val.liveDecls = DSetFact.add(val.liveDecls, Dtor->getVarDecl()); + if (CFGAutomaticObjDtor Dtor = elem.getAs()){ + val.liveDecls = DSetFact.add(val.liveDecls, Dtor.getVarDecl()); continue; } - if (!isa(elem)) + if (!elem.getAs()) continue; - const Stmt *S = cast(elem).getStmt(); + const Stmt *S = elem.castAs().getStmt(); TF.Visit(const_cast(S)); stmtsToLiveness[S] = val; } @@ -534,8 +534,8 @@ LiveVariables::computeLiveness(AnalysisDeclContext &AC, if (killAtAssign) for (CFGBlock::const_iterator bi = block->begin(), be = block->end(); bi != be; ++bi) { - if (const CFGStmt *cs = bi->getAs()) { - if (const BinaryOperator *BO = dyn_cast(cs->getStmt())) { + if (CFGStmt cs = bi->getAs()) { + if (const BinaryOperator *BO = dyn_cast(cs.getStmt())) { if (BO->getOpcode() == BO_Assign) { if (const DeclRefExpr *DR = dyn_cast(BO->getLHS()->IgnoreParens())) { diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp index 7bf01bb..f85e2de 100644 --- a/clang/lib/Analysis/ReachableCode.cpp +++ b/clang/lib/Analysis/ReachableCode.cpp @@ -95,8 +95,8 @@ static bool isValidDeadStmt(const Stmt *S) { const Stmt *DeadCodeScan::findDeadCode(const clang::CFGBlock *Block) { for (CFGBlock::const_iterator I = Block->begin(), E = Block->end(); I!=E; ++I) - if (const CFGStmt *CS = I->getAs()) { - const Stmt *S = CS->getStmt(); + if (CFGStmt CS = I->getAs()) { + const Stmt *S = CS.getStmt(); if (isValidDeadStmt(S)) return S; } diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 20d8f97..2e3abc0 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1350,8 +1350,8 @@ void LocalVariableMap::traverseCFG(CFG *CFGraph, BE = CurrBlock->end(); BI != BE; ++BI) { switch (BI->getKind()) { case CFGElement::Statement: { - const CFGStmt *CS = cast(&*BI); - VMapBuilder.Visit(const_cast(CS->getStmt())); + CFGStmt CS = BI->castAs(); + VMapBuilder.Visit(const_cast(CS.getStmt())); break; } default: @@ -1397,8 +1397,8 @@ static void findBlockLocations(CFG *CFGraph, for (CFGBlock::const_reverse_iterator BI = CurrBlock->rbegin(), BE = CurrBlock->rend(); BI != BE; ++BI) { // FIXME: Handle other CFGElement kinds. - if (const CFGStmt *CS = dyn_cast(&*BI)) { - CurrBlockInfo->ExitLoc = CS->getStmt()->getLocStart(); + if (CFGStmt CS = BI->getAs()) { + CurrBlockInfo->ExitLoc = CS.getStmt()->getLocStart(); break; } } @@ -1410,8 +1410,8 @@ static void findBlockLocations(CFG *CFGraph, for (CFGBlock::const_iterator BI = CurrBlock->begin(), BE = CurrBlock->end(); BI != BE; ++BI) { // FIXME: Handle other CFGElement kinds. - if (const CFGStmt *CS = dyn_cast(&*BI)) { - CurrBlockInfo->EntryLoc = CS->getStmt()->getLocStart(); + if (CFGStmt CS = BI->getAs()) { + CurrBlockInfo->EntryLoc = CS.getStmt()->getLocStart(); break; } } @@ -2234,8 +2234,8 @@ inline bool neverReturns(const CFGBlock* B) { return false; CFGElement Last = B->back(); - if (CFGStmt* S = dyn_cast(&Last)) { - if (isa(S->getStmt())) + if (CFGStmt S = Last.getAs()) { + if (isa(S.getStmt())) return true; } return false; @@ -2444,22 +2444,22 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { BE = CurrBlock->end(); BI != BE; ++BI) { switch (BI->getKind()) { case CFGElement::Statement: { - const CFGStmt *CS = cast(&*BI); - LocksetBuilder.Visit(const_cast(CS->getStmt())); + CFGStmt CS = BI->castAs(); + LocksetBuilder.Visit(const_cast(CS.getStmt())); break; } // Ignore BaseDtor, MemberDtor, and TemporaryDtor for now. case CFGElement::AutomaticObjectDtor: { - const CFGAutomaticObjDtor *AD = cast(&*BI); - CXXDestructorDecl *DD = const_cast( - AD->getDestructorDecl(AC.getASTContext())); + CFGAutomaticObjDtor AD = BI->castAs(); + CXXDestructorDecl *DD = const_cast( + AD.getDestructorDecl(AC.getASTContext())); if (!DD->hasAttrs()) break; // Create a dummy expression, - VarDecl *VD = const_cast(AD->getVarDecl()); + VarDecl *VD = const_cast(AD.getVarDecl()); DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, - AD->getTriggerStmt()->getLocEnd()); + AD.getTriggerStmt()->getLocEnd()); LocksetBuilder.handleCall(&DRE, DD); break; } diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index 13af435..022bb7d 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -746,8 +746,8 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg, TransferFunctions tf(vals, cfg, block, ac, classification, handler); for (CFGBlock::const_iterator I = block->begin(), E = block->end(); I != E; ++I) { - if (const CFGStmt *cs = dyn_cast(&*I)) { - tf.Visit(const_cast(cs->getStmt())); + if (CFGStmt cs = I->getAs()) { + tf.Visit(const_cast(cs.getStmt())); } } return vals.updateValueVectorWithScratch(block); diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index e9cf7cc..9a67d49 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -158,7 +158,7 @@ static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) { CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend(); for ( ; ri != re ; ++ri) - if (isa(*ri)) + if (ri->getAs()) break; // No more CFGElements in the block? @@ -172,7 +172,7 @@ static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) { continue; } - CFGStmt CS = cast(*ri); + CFGStmt CS = ri->castAs(); const Stmt *S = CS.getStmt(); if (isa(S)) { HasLiveReturn = true; @@ -762,8 +762,8 @@ namespace { for (CFGBlock::const_reverse_iterator ElemIt = P->rbegin(), ElemEnd = P->rend(); ElemIt != ElemEnd; ++ElemIt) { - if (const CFGStmt *CS = ElemIt->getAs()) { - if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) { + if (CFGStmt CS = ElemIt->getAs()) { + if (const AttributedStmt *AS = asFallThroughAttr(CS.getStmt())) { S.Diag(AS->getLocStart(), diag::warn_fallthrough_attr_unreachable); markFallthroughVisited(AS); @@ -833,8 +833,8 @@ namespace { for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(), ElemEnd = B.rend(); ElemIt != ElemEnd; ++ElemIt) { - if (const CFGStmt *CS = ElemIt->getAs()) - return CS->getStmt(); + if (CFGStmt CS = ElemIt->getAs()) + return CS.getStmt(); } // Workaround to detect a statement thrown out by CFGBuilder: // case X: {} case Y: diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp index dffa85f..0a12854 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp @@ -123,13 +123,13 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G, const BlockEdge &BE = I->first; const CFGBlock *Exit = BE.getDst(); const CFGElement &CE = Exit->front(); - if (const CFGStmt *CS = dyn_cast(&CE)) { + if (CFGStmt CS = CE.getAs()) { SmallString<128> bufI; llvm::raw_svector_ostream outputI(bufI); outputI << "(" << NameOfRootFunction << ")" << ": The analyzer generated a sink at this point"; B.EmitBasicReport(D, "Sink Point", "Internal Statistics", outputI.str(), - PathDiagnosticLocation::createBegin(CS->getStmt(), + PathDiagnosticLocation::createBegin(CS.getStmt(), SM, LC)); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp index e8ad775..7b63d67 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp @@ -236,8 +236,8 @@ void MallocOverflowSecurityChecker::checkASTCodeBody(const Decl *D, CFGBlock *block = *it; for (CFGBlock::iterator bi = block->begin(), be = block->end(); bi != be; ++bi) { - if (const CFGStmt *CS = bi->getAs()) { - if (const CallExpr *TheCall = dyn_cast(CS->getStmt())) { + if (CFGStmt CS = bi->getAs()) { + if (const CallExpr *TheCall = dyn_cast(CS.getStmt())) { // Get the callee. const FunctionDecl *FD = TheCall->getDirectCallee(); diff --git a/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp index e2d14e1..c939d05 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp @@ -131,8 +131,8 @@ void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G, bool foundUnreachable = false; for (CFGBlock::const_iterator ci = CB->begin(), ce = CB->end(); ci != ce; ++ci) { - if (const CFGStmt *S = (*ci).getAs()) - if (const CallExpr *CE = dyn_cast(S->getStmt())) { + if (CFGStmt S = (*ci).getAs()) + if (const CallExpr *CE = dyn_cast(S.getStmt())) { if (CE->isBuiltinCall() == Builtin::BI__builtin_unreachable) { foundUnreachable = true; break; @@ -189,8 +189,8 @@ void UnreachableCodeChecker::FindUnreachableEntryPoints(const CFGBlock *CB, // Find the Stmt* in a CFGBlock for reporting a warning const Stmt *UnreachableCodeChecker::getUnreachableStmt(const CFGBlock *CB) { for (CFGBlock::const_iterator I = CB->begin(), E = CB->end(); I != E; ++I) { - if (const CFGStmt *S = I->getAs()) - return S->getStmt(); + if (CFGStmt S = I->getAs()) + return S.getStmt(); } if (const Stmt *S = CB->getTerminator()) return S; diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 6ae73b5..d43d525 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1482,8 +1482,8 @@ static bool GenerateExtensivePathDiagnostic(PathDiagnostic& PD, if (const BlockEntrance *BE = dyn_cast(&P)) { CFGElement First = BE->getFirstElement(); - if (const CFGStmt *S = First.getAs()) { - const Stmt *stmt = S->getStmt(); + if (CFGStmt S = First.getAs()) { + const Stmt *stmt = S.getStmt(); if (IsControlFlowExpr(stmt)) { // Add the proper context for '&&', '||', and '?'. EB.addContext(stmt); diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index c5e3c05..3293515 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -961,8 +961,9 @@ CallEventManager::getCaller(const StackFrameContext *CalleeCtx, // destructors, though this could change in the future. const CFGBlock *B = CalleeCtx->getCallSiteBlock(); CFGElement E = (*B)[CalleeCtx->getIndex()]; - assert(isa(E) && "All other CFG elements should have exprs"); - assert(!isa(E) && "We don't handle temporaries yet"); + assert(E.getAs() && + "All other CFG elements should have exprs"); + assert(!E.getAs() && "We don't handle temporaries yet"); SValBuilder &SVB = State->getStateManager().getSValBuilder(); const CXXDestructorDecl *Dtor = cast(CalleeCtx->getDecl()); @@ -970,11 +971,11 @@ CallEventManager::getCaller(const StackFrameContext *CalleeCtx, SVal ThisVal = State->getSVal(ThisPtr); const Stmt *Trigger; - if (const CFGAutomaticObjDtor *AutoDtor = dyn_cast(&E)) - Trigger = AutoDtor->getTriggerStmt(); + if (CFGAutomaticObjDtor AutoDtor = E.getAs()) + Trigger = AutoDtor.getTriggerStmt(); else Trigger = Dtor->getBody(); return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(), - isa(E), State, CallerCtx); + E.getAs(), State, CallerCtx); } diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index 297ad0d..5d819ba 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -515,7 +515,7 @@ void CoreEngine::enqueueStmtNode(ExplodedNode *N, } // At this point, we know we're processing a normal statement. - CFGStmt CS = cast((*Block)[Idx]); + CFGStmt CS = (*Block)[Idx].castAs(); PostStmt Loc(CS.getStmt(), N->getLocationContext()); if (Loc == N->getLocation()) { diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index d03f3bd..3e5fd06 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -225,16 +225,16 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, case CFGElement::Invalid: llvm_unreachable("Unexpected CFGElement kind."); case CFGElement::Statement: - ProcessStmt(const_cast(E.getAs()->getStmt()), Pred); + ProcessStmt(const_cast(E.castAs().getStmt()), Pred); return; case CFGElement::Initializer: - ProcessInitializer(E.getAs()->getInitializer(), Pred); + ProcessInitializer(E.castAs().getInitializer(), Pred); return; case CFGElement::AutomaticObjectDtor: case CFGElement::BaseDtor: case CFGElement::MemberDtor: case CFGElement::TemporaryDtor: - ProcessImplicitDtor(*E.getAs(), Pred); + ProcessImplicitDtor(E.castAs(), Pred); return; } currBldrCtx = 0; @@ -440,16 +440,16 @@ void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNodeSet Dst; switch (D.getKind()) { case CFGElement::AutomaticObjectDtor: - ProcessAutomaticObjDtor(cast(D), Pred, Dst); + ProcessAutomaticObjDtor(D.castAs(), Pred, Dst); break; case CFGElement::BaseDtor: - ProcessBaseDtor(cast(D), Pred, Dst); + ProcessBaseDtor(D.castAs(), Pred, Dst); break; case CFGElement::MemberDtor: - ProcessMemberDtor(cast(D), Pred, Dst); + ProcessMemberDtor(D.castAs(), Pred, Dst); break; case CFGElement::TemporaryDtor: - ProcessTemporaryDtor(cast(D), Pred, Dst); + ProcessTemporaryDtor(D.castAs(), Pred, Dst); break; default: llvm_unreachable("Unexpected dtor kind."); @@ -1200,10 +1200,10 @@ static const Stmt *ResolveCondition(const Stmt *Condition, CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend(); for (; I != E; ++I) { CFGElement Elem = *I; - CFGStmt *CS = dyn_cast(&Elem); + CFGStmt CS = Elem.getAs(); if (!CS) continue; - if (CS->getStmt() != Condition) + if (CS.getStmt() != Condition) break; return Condition; } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index b93dfe1..5b3a518 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -554,7 +554,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, // in SrcBlock is the value of the enclosing expression. // However, we still need to constrain that value to be 0 or 1. assert(!SrcBlock->empty()); - CFGStmt Elem = cast(*SrcBlock->rbegin()); + CFGStmt Elem = SrcBlock->rbegin()->castAs(); const Expr *RHS = cast(Elem.getStmt()); SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext()); @@ -659,8 +659,8 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex, for (CFGBlock::const_reverse_iterator I = SrcBlock->rbegin(), E = SrcBlock->rend(); I != E; ++I) { CFGElement CE = *I; - if (CFGStmt *CS = dyn_cast(&CE)) { - const Expr *ValEx = cast(CS->getStmt()); + if (CFGStmt CS = CE.getAs()) { + const Expr *ValEx = cast(CS.getStmt()); hasValue = true; V = state->getSVal(ValEx, LCtx); break; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index d7cb5d1..43184cf 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -96,8 +96,8 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, CFGElement Next = (*B)[currStmtIdx+1]; // Is this a constructor for a local variable? - if (const CFGStmt *StmtElem = dyn_cast(&Next)) { - if (const DeclStmt *DS = dyn_cast(StmtElem->getStmt())) { + if (CFGStmt StmtElem = Next.getAs()) { + if (const DeclStmt *DS = dyn_cast(StmtElem.getStmt())) { if (const VarDecl *Var = dyn_cast(DS->getSingleDecl())) { if (Var->getInit()->IgnoreImplicit() == CE) { QualType Ty = Var->getType(); @@ -119,8 +119,8 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, } // Is this a constructor for a member? - if (const CFGInitializer *InitElem = dyn_cast(&Next)) { - const CXXCtorInitializer *Init = InitElem->getInitializer(); + if (CFGInitializer InitElem = Next.getAs()) { + const CXXCtorInitializer *Init = InitElem.getInitializer(); assert(Init->isAnyMemberInitializer()); const CXXMethodDecl *CurCtor = cast(LCtx->getDecl()); diff --git a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index 69a4e27..12d85db 100644 --- a/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -479,15 +479,15 @@ getLocationForCaller(const StackFrameContext *SFC, case CFGElement::Invalid: llvm_unreachable("Invalid CFGElement"); case CFGElement::Statement: - return PathDiagnosticLocation(cast(Source).getStmt(), + return PathDiagnosticLocation(Source.castAs().getStmt(), SM, CallerCtx); case CFGElement::Initializer: { - const CFGInitializer &Init = cast(Source); + const CFGInitializer &Init = Source.castAs(); return PathDiagnosticLocation(Init.getInitializer()->getInit(), SM, CallerCtx); } case CFGElement::AutomaticObjectDtor: { - const CFGAutomaticObjDtor &Dtor = cast(Source); + const CFGAutomaticObjDtor &Dtor = Source.castAs(); return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(), SM, CallerCtx); }