Replace ProgramPoint llvm::cast support to be well-defined.

See r175462 for another example/more details.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175812 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 322f0cb..27d4ff1 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -19,6 +19,7 @@
 #include "clang/Analysis/CFG.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
@@ -71,9 +72,8 @@
 
   llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
 
-  ProgramPoint();
-  
 protected:
+  ProgramPoint() {}
   ProgramPoint(const void *P,
                Kind k,
                const LocationContext *l,
@@ -110,6 +110,29 @@
                         getLocationContext(), tag);
   }
 
+  /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
+  /// is of the desired type.
+  template<typename T>
+  T castAs() const {
+    assert(T::isKind(*this));
+    T t;
+    ProgramPoint& PP = t;
+    PP = *this;
+    return t;
+  }
+
+  /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
+  /// this TypeLoc is not of the desired type.
+  template<typename T>
+  Optional<T> getAs() const {
+    if (!T::isKind(*this))
+      return None;
+    T t;
+    ProgramPoint& PP = t;
+    PP = *this;
+    return t;
+  }
+
   Kind getKind() const {
     unsigned x = Tag.getInt();
     x <<= 2;
@@ -184,8 +207,11 @@
     return B->empty() ? CFGElement() : B->front();
   }
   
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == BlockEntranceKind;
+private:
+  friend class ProgramPoint;
+  BlockEntrance() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == BlockEntranceKind;
   }
 };
 
@@ -202,8 +228,11 @@
     return getBlock()->getTerminator();
   }
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == BlockExitKind;
+private:
+  friend class ProgramPoint;
+  BlockExit() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == BlockExitKind;
   }
 };
 
@@ -220,8 +249,12 @@
   template <typename T>
   const T* getStmtAs() const { return dyn_cast<T>(getStmt()); }
 
-  static bool classof(const ProgramPoint* Location) {
-    unsigned k = Location->getKind();
+protected:
+  StmtPoint() {}
+private:
+  friend class ProgramPoint;
+  static bool isKind(const ProgramPoint &Location) {
+    unsigned k = Location.getKind();
     return k >= PreStmtKind && k <= MaxPostStmtKind;
   }
 };
@@ -235,13 +268,17 @@
 
   const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == PreStmtKind;
+private:
+  friend class ProgramPoint;
+  PreStmt() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PreStmtKind;
   }
 };
 
 class PostStmt : public StmtPoint {
 protected:
+  PostStmt() {}
   PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
            const ProgramPointTag *tag = 0)
     : StmtPoint(S, data, k, L, tag) {}
@@ -255,8 +292,10 @@
                     const ProgramPointTag *tag = 0)
     : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
 
-  static bool classof(const ProgramPoint* Location) {
-    unsigned k = Location->getKind();
+private:
+  friend class ProgramPoint;
+  static bool isKind(const ProgramPoint &Location) {
+    unsigned k = Location.getKind();
     return k >= MinPostStmtKind && k <= MaxPostStmtKind;
   }
 };
@@ -268,19 +307,25 @@
                 const ProgramPointTag *tag = 0)
     : PostStmt(S, PostConditionKind, L, tag) {}
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == PostConditionKind;
+private:
+  friend class ProgramPoint;
+  PostCondition() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostConditionKind;
   }
 };
 
 class LocationCheck : public StmtPoint {
 protected:
+  LocationCheck() {}
   LocationCheck(const Stmt *S, const LocationContext *L,
                 ProgramPoint::Kind K, const ProgramPointTag *tag)
     : StmtPoint(S, NULL, K, L, tag) {}
     
-  static bool classof(const ProgramPoint *location) {
-    unsigned k = location->getKind();
+private:
+  friend class ProgramPoint;
+  static bool isKind(const ProgramPoint &location) {
+    unsigned k = location.getKind();
     return k == PreLoadKind || k == PreStoreKind;
   }
 };
@@ -291,8 +336,11 @@
           const ProgramPointTag *tag = 0)
     : LocationCheck(S, L, PreLoadKind, tag) {}
   
-  static bool classof(const ProgramPoint *location) {
-    return location->getKind() == PreLoadKind;
+private:
+  friend class ProgramPoint;
+  PreLoad() {}
+  static bool isKind(const ProgramPoint &location) {
+    return location.getKind() == PreLoadKind;
   }
 };
 
@@ -302,8 +350,11 @@
            const ProgramPointTag *tag = 0)
   : LocationCheck(S, L, PreStoreKind, tag) {}
   
-  static bool classof(const ProgramPoint *location) {
-    return location->getKind() == PreStoreKind;
+private:
+  friend class ProgramPoint;
+  PreStore() {}
+  static bool isKind(const ProgramPoint &location) {
+    return location.getKind() == PreStoreKind;
   }
 };
 
@@ -313,8 +364,11 @@
            const ProgramPointTag *tag = 0)
     : PostStmt(S, PostLoadKind, L, tag) {}
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == PostLoadKind;
+private:
+  friend class ProgramPoint;
+  PostLoad() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostLoadKind;
   }
 };
 
@@ -331,16 +385,18 @@
     setData2(Loc);
   }
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == PostStoreKind;
-  }
-  
   /// \brief Returns the information about the location used in the store,
   /// how it was uttered in the code.
   const void *getLocationValue() const {
     return getData2();
   }
 
+private:
+  friend class ProgramPoint;
+  PostStore() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostStoreKind;
+  }
 };
 
 class PostLValue : public PostStmt {
@@ -349,8 +405,11 @@
              const ProgramPointTag *tag = 0)
     : PostStmt(S, PostLValueKind, L, tag) {}
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == PostLValueKind;
+private:
+  friend class ProgramPoint;
+  PostLValue() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostLValueKind;
   }
 };
 
@@ -362,8 +421,11 @@
                        const ProgramPointTag *tag = 0)
     : StmtPoint(S, 0, PreStmtPurgeDeadSymbolsKind, L, tag) { }
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == PreStmtPurgeDeadSymbolsKind;
+private:
+  friend class ProgramPoint;
+  PreStmtPurgeDeadSymbols() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PreStmtPurgeDeadSymbolsKind;
   }
 };
 
@@ -375,8 +437,11 @@
                        const ProgramPointTag *tag = 0)
     : StmtPoint(S, 0, PostStmtPurgeDeadSymbolsKind, L, tag) { }
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == PostStmtPurgeDeadSymbolsKind;
+private:
+  friend class ProgramPoint;
+  PostStmtPurgeDeadSymbols() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostStmtPurgeDeadSymbolsKind;
   }
 };
 
@@ -396,8 +461,11 @@
     return static_cast<const CFGBlock*>(getData2());
   }
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == BlockEdgeKind;
+private:
+  friend class ProgramPoint;
+  BlockEdge() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == BlockEdgeKind;
   }
 };
 
@@ -407,8 +475,11 @@
                   const LocationContext *L)
     : ProgramPoint(I, PostInitializerKind, L) {}
 
-  static bool classof(const ProgramPoint *Location) {
-    return Location->getKind() == PostInitializerKind;
+private:
+  friend class ProgramPoint;
+  PostInitializer() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostInitializerKind;
   }
 };
 
@@ -426,9 +497,13 @@
     return SourceLocation::getFromPtrEncoding(getData1());
   }
 
-  static bool classof(const ProgramPoint *Location) {
-    return Location->getKind() >= MinImplicitCallKind &&
-           Location->getKind() <= MaxImplicitCallKind;
+protected:
+  ImplicitCallPoint() {}
+private:
+  friend class ProgramPoint;
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() >= MinImplicitCallKind &&
+           Location.getKind() <= MaxImplicitCallKind;
   }
 };
 
@@ -441,8 +516,11 @@
                   const LocationContext *L, const ProgramPointTag *Tag = 0)
     : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
 
-  static bool classof(const ProgramPoint *Location) {
-    return Location->getKind() == PreImplicitCallKind;
+private:
+  friend class ProgramPoint;
+  PreImplicitCall() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PreImplicitCallKind;
   }
 };
 
@@ -455,8 +533,11 @@
                    const LocationContext *L, const ProgramPointTag *Tag = 0)
     : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
 
-  static bool classof(const ProgramPoint *Location) {
-    return Location->getKind() == PostImplicitCallKind;
+private:
+  friend class ProgramPoint;
+  PostImplicitCall() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == PostImplicitCallKind;
   }
 };
 
@@ -476,8 +557,11 @@
     return static_cast<const StackFrameContext *>(getData2());
   }
 
-  static bool classof(const ProgramPoint *Location) {
-    return Location->getKind() == CallEnterKind;
+private:
+  friend class ProgramPoint;
+  CallEnter() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == CallEnterKind;
   }
 };
 
@@ -496,8 +580,11 @@
   CallExitBegin(const StackFrameContext *L)
     : ProgramPoint(0, CallExitBeginKind, L, 0) {}
 
-  static bool classof(const ProgramPoint *Location) {
-    return Location->getKind() == CallExitBeginKind;
+private:
+  friend class ProgramPoint;
+  CallExitBegin() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == CallExitBeginKind;
   }
 };
 
@@ -514,8 +601,11 @@
     return static_cast<const StackFrameContext *>(getData1());
   }
 
-  static bool classof(const ProgramPoint *Location) {
-    return Location->getKind() == CallExitEndKind;
+private:
+  friend class ProgramPoint;
+  CallExitEnd() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == CallExitEndKind;
   }
 };
 
@@ -529,8 +619,11 @@
 
   const void *getData() const { return getData1(); }
 
-  static bool classof(const ProgramPoint* Location) {
-    return Location->getKind() == EpsilonKind;
+private:
+  friend class ProgramPoint;
+  EpsilonPoint() {}
+  static bool isKind(const ProgramPoint &Location) {
+    return Location.getKind() == EpsilonKind;
   }
 };
 
@@ -544,7 +637,7 @@
   virtual StringRef getTagDescription() const = 0;    
 
 protected:
-  /// Used to implement 'classof' in subclasses.
+  /// Used to implement 'isKind' in subclasses.
   const void *getTagKind() { return TagKind; }
   
 private:
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index ce495c9..cda1366 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -185,7 +185,7 @@
   /// example, for finding variables that the given symbol was assigned to.
   static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
     ProgramPoint L = N->getLocation();
-    if (const PostStore *PSL = dyn_cast<PostStore>(&L))
+    if (Optional<PostStore> PSL = L.getAs<PostStore>())
       return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
     return 0;
   }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 519924d..82ac3d9 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -155,15 +155,10 @@
   const ProgramStateRef &getState() const { return State; }
 
   template <typename T>
-  const T* getLocationAs() const LLVM_LVALUE_FUNCTION {
-    return dyn_cast<T>(&Location);
+  Optional<T> getLocationAs() const LLVM_LVALUE_FUNCTION {
+    return Location.getAs<T>();
   }
 
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
-  template <typename T>
-  void getLocationAs() && LLVM_DELETED_FUNCTION;
-#endif
-
   static void Profile(llvm::FoldingSetNodeID &ID,
                       const ProgramPoint &Loc,
                       const ProgramStateRef &state,
diff --git a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
index 0a12854..217d467 100644
--- a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
@@ -60,7 +60,7 @@
     if (D != P.getLocationContext()->getDecl())
       continue;
 
-    if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
+    if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) {
       const CFGBlock *CB = BE->getBlock();
       reachable.insert(CB);
     }
diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
index 051d60a..312bc74 100644
--- a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
@@ -44,7 +44,7 @@
     return;
 
   // Get the index of the accessed element.
-  DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+  DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
 
   // Zero index is always in bound, this also passes ElementRegions created for
   // pointer casts.
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index d0c4322..cc55e9f 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -281,7 +281,7 @@
   DefinedOrUnknownSVal Size = Extent.castAs<DefinedOrUnknownSVal>();
 
   // Get the index of the accessed element.
-  DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+  DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
 
   ProgramStateRef StInBound = state->assumeInBound(Idx, Size, true);
   ProgramStateRef StOutBound = state->assumeInBound(Idx, Size, false);
diff --git a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
index 54c32f8..579ba9c 100644
--- a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
@@ -332,9 +332,9 @@
   // Add the ExplodedNode we just visited
   BinaryOperatorData &Data = hash[B];
 
-  const Stmt *predStmt 
-    = cast<StmtPoint>(C.getPredecessor()->getLocation()).getStmt();
-  
+  const Stmt *predStmt =
+      C.getPredecessor()->getLocation().castAs<StmtPoint>().getStmt();
+
   // Ignore implicit calls to setters.
   if (!isa<BinaryOperator>(predStmt))
     return;
@@ -582,16 +582,13 @@
     virtual bool visit(const WorkListUnit &U) {
       ProgramPoint P = U.getNode()->getLocation();
       const CFGBlock *B = 0;
-      if (StmtPoint *SP = dyn_cast<StmtPoint>(&P)) {
+      if (Optional<StmtPoint> SP = P.getAs<StmtPoint>()) {
         B = CBM->getBlock(SP->getStmt());
-      }
-      else if (BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+      } else if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
         B = BE->getDst();
-      }
-      else if (BlockEntrance *BEnt = dyn_cast<BlockEntrance>(&P)) {
+      } else if (Optional<BlockEntrance> BEnt = P.getAs<BlockEntrance>()) {
         B = BEnt->getBlock();
-      }
-      else if (BlockExit *BExit = dyn_cast<BlockExit>(&P)) {
+      } else if (Optional<BlockExit> BExit = P.getAs<BlockExit>()) {
         B = BExit->getBlock();
       }
       if (!B)
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index 84cad82..2cd4afe 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -526,9 +526,9 @@
   const ExplodedNode *AllocNode = getAllocationNode(N, AP.first, C);
   const Stmt *AllocStmt = 0;
   ProgramPoint P = AllocNode->getLocation();
-  if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+  if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
     AllocStmt = Exit->getCalleeContext()->getCallSite();
-  else if (clang::PostStmt *PS = dyn_cast<clang::PostStmt>(&P))
+  else if (Optional<clang::PostStmt> PS = P.getAs<clang::PostStmt>())
     AllocStmt = PS->getStmt();
 
   if (AllocStmt)
@@ -602,8 +602,8 @@
 
   // (!ASPrev && AS) ~ We started tracking symbol in node N, it must be the
   // allocation site.
-  const CallExpr *CE = cast<CallExpr>(cast<StmtPoint>(N->getLocation())
-                                                            .getStmt());
+  const CallExpr *CE =
+      cast<CallExpr>(N->getLocation().castAs<StmtPoint>().getStmt());
   const FunctionDecl *funDecl = CE->getDirectCallee();
   assert(funDecl && "We do not support indirect function calls as of now.");
   StringRef funName = funDecl->getName();
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 38722a2..f412c04 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1117,9 +1117,9 @@
   
   ProgramPoint P = AllocNode->getLocation();
   const Stmt *AllocationStmt = 0;
-  if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+  if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
     AllocationStmt = Exit->getCalleeContext()->getCallSite();
-  else if (StmtPoint *SP = dyn_cast<StmtPoint>(&P))
+  else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
     AllocationStmt = SP->getStmt();
   if (AllocationStmt)
     LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
@@ -1559,11 +1559,11 @@
 
   // Retrieve the associated statement.
   ProgramPoint ProgLoc = N->getLocation();
-  if (StmtPoint *SP = dyn_cast<StmtPoint>(&ProgLoc)) {
+  if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) {
     S = SP->getStmt();
-  } else if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&ProgLoc)) {
+  } else if (Optional<CallExitEnd> Exit = ProgLoc.getAs<CallExitEnd>()) {
     S = Exit->getCalleeContext()->getCallSite();
-  } else if (BlockEdge *Edge = dyn_cast<BlockEdge>(&ProgLoc)) {
+  } else if (Optional<BlockEdge> Edge = ProgLoc.getAs<BlockEdge>()) {
     // If an assumption was made on a branch, it should be caught
     // here by looking at the state transition.
     S = Edge->getSrc()->getTerminator();
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 69191de..65bd033 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1866,7 +1866,7 @@
                                                    BugReport &BR) {
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).
-  if (!isa<StmtPoint>(N->getLocation()))
+  if (!N->getLocation().getAs<StmtPoint>())
     return NULL;
 
   // Check if the type state has changed.
@@ -1888,7 +1888,7 @@
   // This is the allocation site since the previous node had no bindings
   // for this symbol.
   if (!PrevT) {
-    const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
+    const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
 
     if (isa<ObjCArrayLiteral>(S)) {
       os << "NSArray literal is an object with a +0 retain count";
@@ -1978,7 +1978,7 @@
   if (const RetainSummary *Summ = SummaryLog.lookup(OrigNode)) {
     // We only have summaries attached to nodes after evaluating CallExpr and
     // ObjCMessageExprs.
-    const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
+    const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
 
     if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
       // Iterate through the parameter expressions and see if the symbol
@@ -2027,7 +2027,7 @@
     // Specially handle CFMakeCollectable and friends.
     if (contains(AEffects, MakeCollectable)) {
       // Get the name of the function.
-      const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
+      const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
       SVal X =
         CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee(), LCtx);
       const FunctionDecl *FD = X.getAsFunctionDecl();
@@ -2135,7 +2135,7 @@
   if (os.str().empty())
     return 0; // We have nothing to say!
 
-  const Stmt *S = cast<StmtPoint>(N->getLocation()).getStmt();
+  const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
                                 N->getLocationContext());
   PathDiagnosticPiece *P = new PathDiagnosticEventPiece(Pos, os.str());
@@ -2312,10 +2312,10 @@
   // implicit call. (Currently there are no such allocations in Cocoa, though.)
   const Stmt *AllocStmt;
   ProgramPoint P = AllocNode->getLocation();
-  if (CallExitEnd *Exit = dyn_cast<CallExitEnd>(&P))
+  if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
     AllocStmt = Exit->getCalleeContext()->getCallSite();
   else
-    AllocStmt = cast<PostStmt>(P).getStmt();
+    AllocStmt = P.castAs<PostStmt>().getStmt();
   assert(AllocStmt && "All allocations must come from explicit calls");
   Location = PathDiagnosticLocation::createBegin(AllocStmt, SMgr,
                                                   n->getLocationContext());
diff --git a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
index 59df516..fe253b7 100644
--- a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
@@ -46,7 +46,7 @@
   if (!ER)
     return;
 
-  DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
+  DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
   // Zero index is always in bound, this also passes ElementRegions created for
   // pointer casts.
   if (Idx.isZeroConstant())
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 54e4016..8235e68 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -90,7 +90,7 @@
       ProgramPoint P = PrevN->getLocation();
       ProgramStateRef St = N->getState();
 
-      if (PostStmt *PS = dyn_cast<PostStmt>(&P))
+      if (Optional<PostStmt> PS = P.getAs<PostStmt>())
         if (PS->getStmt() == Ex)
           St = PrevN->getState();
 
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index c939d05..3b4aa23 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -76,7 +76,7 @@
     if (!PM)
       PM = &LC->getParentMap();
 
-    if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
+    if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) {
       const CFGBlock *CB = BE->getBlock();
       reachable.insert(CB->getBlockID());
     }
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index d43d525..8556089 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -44,13 +44,13 @@
 //===----------------------------------------------------------------------===//
 
 static inline const Stmt *GetStmt(const ProgramPoint &P) {
-  if (const StmtPoint* SP = dyn_cast<StmtPoint>(&P))
+  if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
     return SP->getStmt();
-  else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
+  if (Optional<BlockEdge> BE = P.getAs<BlockEdge>())
     return BE->getSrc()->getTerminator();
-  else if (const CallEnter *CE = dyn_cast<CallEnter>(&P))
+  if (Optional<CallEnter> CE = P.getAs<CallEnter>())
     return CE->getCallExpr();
-  else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&P))
+  if (Optional<CallExitEnd> CEE = P.getAs<CallExitEnd>())
     return CEE->getCalleeContext()->getCallSite();
 
   return 0;
@@ -579,7 +579,7 @@
     ProgramPoint P = N->getLocation();
 
     do {
-      if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
+      if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
         PathDiagnosticCallPiece *C =
             PathDiagnosticCallPiece::construct(N, *CE, SMgr);
         GRBugReporter& BR = PDB.getBugReporter();
@@ -590,7 +590,7 @@
         break;
       }
 
-      if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
+      if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
         // Flush all locations, and pop the active path.
         bool VisitedEntireCall = PD.isWithinCall();
         PD.popActivePath();
@@ -618,7 +618,7 @@
         break;
       }
 
-      if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+      if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
         const CFGBlock *Src = BE->getSrc();
         const CFGBlock *Dst = BE->getDst();
         const Stmt *T = Src->getTerminator();
@@ -1334,14 +1334,14 @@
     ProgramPoint P = N->getLocation();
 
     do {
-      if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
+      if (Optional<PostStmt> PS = P.getAs<PostStmt>()) {
         if (const Expr *Ex = PS->getStmtAs<Expr>())
           reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
                                               N->getState().getPtr(), Ex,
                                               N->getLocationContext());
       }
       
-      if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
+      if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
         const Stmt *S = CE->getCalleeContext()->getCallSite();
         if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
             reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
@@ -1365,7 +1365,7 @@
       
       // Pop the call hierarchy if we are done walking the contents
       // of a function call.
-      if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
+      if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
         // Add an edge to the start of the function.
         const Decl *D = CE->getCalleeContext()->getDecl();
         PathDiagnosticLocation pos =
@@ -1410,7 +1410,7 @@
       PDB.LC = N->getLocationContext();
 
       // Block edges.
-      if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+      if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
         // Does this represent entering a call?  If so, look at propagating
         // interesting symbols across call boundaries.
         if (NextNode) {
@@ -1457,7 +1457,7 @@
         if (const Stmt *Term = BE->getSrc()->getTerminator()) {
           // Are we jumping past the loop body without ever executing the
           // loop (because the condition was false)?
-          if (isLoopJumpPastBody(Term, BE) &&
+          if (isLoopJumpPastBody(Term, &*BE) &&
               !PD.getActivePath().empty() &&
               PD.getActivePath().front() != LastLoopDiagnostic.second &&
               Term != LastLoopDiagnostic.first)
@@ -1480,7 +1480,7 @@
         break;
       }
 
-      if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
+      if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) {
         CFGElement First = BE->getFirstElement();
         if (CFGStmt S = First.getAs<CFGStmt>()) {
           const Stmt *stmt = S.getStmt();
@@ -1700,7 +1700,7 @@
   ProgramPoint ProgP = ErrorNode->getLocation();
   const Stmt *S = NULL;
 
-  if (BlockEntrance *BE = dyn_cast<BlockEntrance>(&ProgP)) {
+  if (Optional<BlockEntrance> BE = ProgP.getAs<BlockEntrance>()) {
     CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit();
     if (BE->getBlock() == &Exit)
       S = GetPreviousStmt(ErrorNode);
@@ -1744,7 +1744,7 @@
       if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
         return PathDiagnosticLocation::createOperatorLoc(B, SM);
 
-      if (isa<PostStmtPurgeDeadSymbols>(ErrorNode->getLocation()))
+      if (ErrorNode->getLocation().getAs<PostStmtPurgeDeadSymbols>())
         return PathDiagnosticLocation::createEnd(S, SM, LC);
 
       return PathDiagnosticLocation::createBegin(S, SM, LC);
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 05d187e..5dc8dfc 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -164,10 +164,10 @@
     
     // First, find when we processed the statement.
     do {
-      if (const CallExitEnd *CEE = Node->getLocationAs<CallExitEnd>())
+      if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>())
         if (CEE->getCalleeContext()->getCallSite() == S)
           break;
-      if (const StmtPoint *SP = Node->getLocationAs<StmtPoint>())
+      if (Optional<StmtPoint> SP = Node->getLocationAs<StmtPoint>())
         if (SP->getStmt() == S)
           break;
 
@@ -175,12 +175,12 @@
     } while (Node);
 
     // Next, step over any post-statement checks.
-    while (Node && isa<PostStmt>(Node->getLocation()))
+    while (Node && Node->getLocation().getAs<PostStmt>())
       Node = Node->getFirstPred();
 
     // Finally, see if we inlined the call.
     if (Node) {
-      if (const CallExitEnd *CEE = Node->getLocationAs<CallExitEnd>()) {
+      if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>()) {
         const StackFrameContext *CalleeContext = CEE->getCalleeContext();
         if (CalleeContext->getCallSite() == S) {
           BR.markInteresting(CalleeContext);
@@ -204,7 +204,7 @@
     if (N->getLocationContext() != StackFrame)
       return 0;
 
-    const StmtPoint *SP = N->getLocationAs<StmtPoint>();
+    Optional<StmtPoint> SP = N->getLocationAs<StmtPoint>();
     if (!SP)
       return 0;
 
@@ -276,7 +276,7 @@
                                               BugReporterContext &BRC,
                                               BugReport &BR) {
     // Are we at the entry node for this call?
-    const CallEnter *CE = N->getLocationAs<CallEnter>();
+    Optional<CallEnter> CE = N->getLocationAs<CallEnter>();
     if (!CE)
       return 0;
 
@@ -363,7 +363,7 @@
 
   // First see if we reached the declaration of the region.
   if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
-    if (const PostStmt *P = Pred->getLocationAs<PostStmt>()) {
+    if (Optional<PostStmt> P = Pred->getLocationAs<PostStmt>()) {
       if (const DeclStmt *DS = P->getStmtAs<DeclStmt>()) {
         if (DS->getSingleDecl() == VR->getDecl()) {
           StoreSite = Pred;
@@ -385,7 +385,7 @@
 
     // If this is an assignment expression, we can track the value
     // being assigned.
-    if (const PostStmt *P = Succ->getLocationAs<PostStmt>())
+    if (Optional<PostStmt> P = Succ->getLocationAs<PostStmt>())
       if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>())
         if (BO->isAssignmentOp())
           InitE = BO->getRHS();
@@ -394,7 +394,7 @@
     // FIXME: Handle CXXThisRegion as well. (This is not a priority because
     // 'this' should never be NULL, but this visitor isn't just for NULL and
     // UndefinedVal.)
-    if (const CallEnter *CE = Succ->getLocationAs<CallEnter>()) {
+    if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
       const VarRegion *VR = cast<VarRegion>(R);
       const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
       
@@ -432,7 +432,7 @@
   SmallString<256> sbuf;
   llvm::raw_svector_ostream os(sbuf);
 
-  if (const PostStmt *PS = StoreSite->getLocationAs<PostStmt>()) {
+  if (Optional<PostStmt> PS = StoreSite->getLocationAs<PostStmt>()) {
     const Stmt *S = PS->getStmt();
     const char *action = 0;
     const DeclStmt *DS = dyn_cast<DeclStmt>(S);
@@ -494,7 +494,7 @@
         }
       }
     }
-  } else if (isa<CallEnter>(StoreSite->getLocation())) {
+  } else if (StoreSite->getLocation().getAs<CallEnter>()) {
     const ParmVarDecl *Param = cast<ParmVarDecl>(cast<VarRegion>(R)->getDecl());
 
     os << "Passing ";
@@ -553,7 +553,7 @@
   // Construct a new PathDiagnosticPiece.
   ProgramPoint P = StoreSite->getLocation();
   PathDiagnosticLocation L;
-  if (isa<CallEnter>(P))
+  if (P.getAs<CallEnter>())
     L = PathDiagnosticLocation(InitE, BRC.getSourceManager(),
                                P.getLocationContext());
   else
@@ -633,15 +633,15 @@
     S = OVE->getSourceExpr();
 
   if (IsArg) {
-    assert(isa<CallEnter>(N->getLocation()) && "Tracking arg but not at call");
+    assert(N->getLocation().getAs<CallEnter>() && "Tracking arg but not at call");
   } else {
     // Walk through nodes until we get one that matches the statement exactly.
     do {
       const ProgramPoint &pp = N->getLocation();
-      if (const PostStmt *ps = dyn_cast<PostStmt>(&pp)) {
+      if (Optional<PostStmt> ps = pp.getAs<PostStmt>()) {
         if (ps->getStmt() == S)
           break;
-      } else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&pp)) {
+      } else if (Optional<CallExitEnd> CEE = pp.getAs<CallExitEnd>()) {
         if (CEE->getCalleeContext()->getCallSite() == S)
           break;
       }
@@ -755,7 +755,7 @@
                                                      const ExplodedNode *PrevN,
                                                      BugReporterContext &BRC,
                                                      BugReport &BR) {
-  const PostStmt *P = N->getLocationAs<PostStmt>();
+  Optional<PostStmt> P = N->getLocationAs<PostStmt>();
   if (!P)
     return 0;
   const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
@@ -860,14 +860,14 @@
   
   // If an assumption was made on a branch, it should be caught
   // here by looking at the state transition.
-  if (const BlockEdge *BE = dyn_cast<BlockEdge>(&progPoint)) {
+  if (Optional<BlockEdge> BE = progPoint.getAs<BlockEdge>()) {
     const CFGBlock *srcBlk = BE->getSrc();    
     if (const Stmt *term = srcBlk->getTerminator())
       return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
     return 0;
   }
   
-  if (const PostStmt *PS = dyn_cast<PostStmt>(&progPoint)) {
+  if (Optional<PostStmt> PS = progPoint.getAs<PostStmt>()) {
     // FIXME: Assuming that BugReporter is a GRBugReporter is a layering
     // violation.
     const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =      
@@ -1216,7 +1216,7 @@
   ProgramPoint ProgLoc = N->getLocation();
 
   // We are only interested in visiting CallEnter nodes.
-  CallEnter *CEnter = dyn_cast<CallEnter>(&ProgLoc);
+  Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
   if (!CEnter)
     return 0;
 
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 5d819ba..894365c 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -114,7 +114,7 @@
     }
 
     virtual void enqueue(const WorkListUnit& U) {
-      if (isa<BlockEntrance>(U.getNode()->getLocation()))
+      if (U.getNode()->getLocation().getAs<BlockEntrance>())
         Queue.push_front(U);
       else
         Stack.push_back(U);
@@ -230,11 +230,11 @@
   // Dispatch on the location type.
   switch (Loc.getKind()) {
     case ProgramPoint::BlockEdgeKind:
-      HandleBlockEdge(cast<BlockEdge>(Loc), Pred);
+      HandleBlockEdge(Loc.castAs<BlockEdge>(), Pred);
       break;
 
     case ProgramPoint::BlockEntranceKind:
-      HandleBlockEntrance(cast<BlockEntrance>(Loc), Pred);
+      HandleBlockEntrance(Loc.castAs<BlockEntrance>(), Pred);
       break;
 
     case ProgramPoint::BlockExitKind:
@@ -242,7 +242,7 @@
       break;
 
     case ProgramPoint::CallEnterKind: {
-      CallEnter CEnter = cast<CallEnter>(Loc);
+      CallEnter CEnter = Loc.castAs<CallEnter>();
       SubEng.processCallEnter(CEnter, Pred);
       break;
     }
@@ -259,10 +259,10 @@
       break;
     }
     default:
-      assert(isa<PostStmt>(Loc) ||
-             isa<PostInitializer>(Loc) ||
-             isa<PostImplicitCall>(Loc) ||
-             isa<CallExitEnd>(Loc));
+      assert(Loc.getAs<PostStmt>() ||
+             Loc.getAs<PostInitializer>() ||
+             Loc.getAs<PostImplicitCall>() ||
+             Loc.getAs<CallExitEnd>());
       HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred);
       break;
   }
@@ -495,7 +495,7 @@
   assert (!N->isSink());
 
   // Check if this node entered a callee.
-  if (isa<CallEnter>(N->getLocation())) {
+  if (N->getLocation().getAs<CallEnter>()) {
     // Still use the index of the CallExpr. It's needed to create the callee
     // StackFrameContext.
     WList->enqueue(N, Block, Idx);
@@ -503,13 +503,13 @@
   }
 
   // Do not create extra nodes. Move to the next CFG element.
-  if (isa<PostInitializer>(N->getLocation()) ||
-      isa<PostImplicitCall>(N->getLocation())) {
+  if (N->getLocation().getAs<PostInitializer>() ||
+      N->getLocation().getAs<PostImplicitCall>()) {
     WList->enqueue(N, Block, Idx+1);
     return;
   }
 
-  if (isa<EpsilonPoint>(N->getLocation())) {
+  if (N->getLocation().getAs<EpsilonPoint>()) {
     WList->enqueue(N, Block, Idx);
     return;
   }
diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
index d64078f..a72f49d 100644
--- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -85,11 +85,11 @@
 
   // Condition 3.
   ProgramPoint progPoint = node->getLocation();
-  if (!isa<PostStmt>(progPoint) || isa<PostStore>(progPoint))
+  if (!progPoint.getAs<PostStmt>() || progPoint.getAs<PostStore>())
     return false;
 
   // Condition 4.
-  PostStmt ps = cast<PostStmt>(progPoint);
+  PostStmt ps = progPoint.castAs<PostStmt>();
   if (ps.getTag())
     return false;
 
@@ -114,7 +114,7 @@
   
   // Condition 9.
   const ProgramPoint SuccLoc = succ->getLocation();
-  if (const StmtPoint *SP = dyn_cast<StmtPoint>(&SuccLoc))
+  if (Optional<StmtPoint> SP = SuccLoc.getAs<StmtPoint>())
     if (CallEvent::isCallStmt(SP->getStmt()))
       return false;
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 3e5fd06..06b1db5 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -250,7 +250,7 @@
     return false;
 
   // Is this the beginning of a basic block?
-  if (isa<BlockEntrance>(Pred->getLocation()))
+  if (Pred->getLocation().getAs<BlockEntrance>())
     return true;
 
   // Is this on a non-expression?
@@ -1056,11 +1056,11 @@
     // processing the call.
     if (L.isPurgeKind())
       continue;
-    if (isa<PreImplicitCall>(&L))
+    if (L.getAs<PreImplicitCall>())
       continue;
-    if (isa<CallEnter>(&L))
+    if (L.getAs<CallEnter>())
       continue;
-    if (const StmtPoint *SP = dyn_cast<StmtPoint>(&L))
+    if (Optional<StmtPoint> SP = L.getAs<StmtPoint>())
       if (SP->getStmt() == CE)
         continue;
     break;
@@ -1953,7 +1953,7 @@
     // when the expression fails to evaluate to anything meaningful and
     // (as an optimization) we don't generate a node.
     ProgramPoint P = Pred->getLocation();
-    if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
+    if (!P.getAs<PostStmt>() || P.castAs<PostStmt>().getStmt() != Ex) {
       continue;
     }
 
@@ -2073,7 +2073,7 @@
     switch (Loc.getKind()) {
       case ProgramPoint::BlockEntranceKind: {
         Out << "Block Entrance: B"
-            << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
+            << Loc.castAs<BlockEntrance>().getBlock()->getBlockID();
         if (const NamedDecl *ND =
                     dyn_cast<NamedDecl>(Loc.getLocationContext()->getDecl())) {
           Out << " (";
@@ -2112,27 +2112,27 @@
         break;
 
       case ProgramPoint::PreImplicitCallKind: {
-        ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc);
+        ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>();
         Out << "PreCall: ";
 
         // FIXME: Get proper printing options.
-        PC->getDecl()->print(Out, LangOptions());
-        printLocation(Out, PC->getLocation());
+        PC.getDecl()->print(Out, LangOptions());
+        printLocation(Out, PC.getLocation());
         break;
       }
 
       case ProgramPoint::PostImplicitCallKind: {
-        ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc);
+        ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>();
         Out << "PostCall: ";
 
         // FIXME: Get proper printing options.
-        PC->getDecl()->print(Out, LangOptions());
-        printLocation(Out, PC->getLocation());
+        PC.getDecl()->print(Out, LangOptions());
+        printLocation(Out, PC.getLocation());
         break;
       }
 
       default: {
-        if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) {
+        if (Optional<StmtPoint> L = Loc.getAs<StmtPoint>()) {
           const Stmt *S = L->getStmt();
 
           Out << S->getStmtClassName() << ' ' << (const void*) S << ' ';
@@ -2140,13 +2140,13 @@
           S->printPretty(Out, 0, PrintingPolicy(LO));
           printLocation(Out, S->getLocStart());
 
-          if (isa<PreStmt>(Loc))
+          if (Loc.getAs<PreStmt>())
             Out << "\\lPreStmt\\l;";
-          else if (isa<PostLoad>(Loc))
+          else if (Loc.getAs<PostLoad>())
             Out << "\\lPostLoad\\l;";
-          else if (isa<PostStore>(Loc))
+          else if (Loc.getAs<PostStore>())
             Out << "\\lPostStore\\l";
-          else if (isa<PostLValue>(Loc))
+          else if (Loc.getAs<PostLValue>())
             Out << "\\lPostLValue\\l";
 
 #if 0
@@ -2173,7 +2173,7 @@
           break;
         }
 
-        const BlockEdge &E = cast<BlockEdge>(Loc);
+        const BlockEdge &E = Loc.castAs<BlockEdge>();
         Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
             << E.getDst()->getBlockID()  << ')';
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 5b3a518..b656bbd 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -523,16 +523,16 @@
   ProgramStateRef state = Pred->getState();
 
   ExplodedNode *N = Pred;
-  while (!isa<BlockEntrance>(N->getLocation())) {
+  while (!N->getLocation().getAs<BlockEntrance>()) {
     ProgramPoint P = N->getLocation();
-    assert(isa<PreStmt>(P)|| isa<PreStmtPurgeDeadSymbols>(P));
+    assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
     (void) P;
     assert(N->pred_size() == 1);
     N = *N->pred_begin();
   }
   assert(N->pred_size() == 1);
   N = *N->pred_begin();
-  BlockEdge BE = cast<BlockEdge>(N->getLocation());
+  BlockEdge BE = N->getLocation().castAs<BlockEdge>();
   SVal X;
 
   // Determine the value of the expression by introspecting how we
@@ -643,11 +643,11 @@
 
   for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
     ProgramPoint PP = N->getLocation();
-    if (isa<PreStmtPurgeDeadSymbols>(PP) || isa<BlockEntrance>(PP)) {
+    if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
       assert(N->pred_size() == 1);
       continue;
     }
-    SrcBlock = cast<BlockEdge>(&PP)->getSrc();
+    SrcBlock = PP.castAs<BlockEdge>().getSrc();
     break;
   }
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 0d4673c..a4d33ee 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -77,10 +77,10 @@
     const ProgramPoint &PP = Node->getLocation();
 
     if (PP.getLocationContext()->getCurrentStackFrame() == SF) {
-      if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP)) {
+      if (Optional<StmtPoint> SP = PP.getAs<StmtPoint>()) {
         S = SP->getStmt();
         break;
-      } else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&PP)) {
+      } else if (Optional<CallExitEnd> CEE = PP.getAs<CallExitEnd>()) {
         S = CEE->getCalleeContext()->getCallSite();
         if (S)
           break;
@@ -88,17 +88,17 @@
         // If there is no statement, this is an implicitly-generated call.
         // We'll walk backwards over it and then continue the loop to find
         // an actual statement.
-        const CallEnter *CE;
+        Optional<CallEnter> CE;
         do {
           Node = Node->getFirstPred();
           CE = Node->getLocationAs<CallEnter>();
         } while (!CE || CE->getCalleeContext() != CEE->getCalleeContext());
 
         // Continue searching the graph.
-      } else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&PP)) {
+      } else if (Optional<BlockEdge> BE = PP.getAs<BlockEdge>()) {
         Blk = BE->getSrc();
       }
-    } else if (const CallEnter *CE = dyn_cast<CallEnter>(&PP)) {
+    } else if (Optional<CallEnter> CE = PP.getAs<CallEnter>()) {
       // If we reached the CallEnter for this function, it has no statements.
       if (CE->getCalleeContext() == SF)
         break;
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 12d85db..b27a80f 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -583,29 +583,24 @@
                                  const SourceManager &SMng) {
 
   const Stmt* S = 0;
-  if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+  if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
     const CFGBlock *BSrc = BE->getSrc();
     S = BSrc->getTerminatorCondition();
-  }
-  else if (const StmtPoint *SP = dyn_cast<StmtPoint>(&P)) {
+  } else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>()) {
     S = SP->getStmt();
-    if (isa<PostStmtPurgeDeadSymbols>(P))
+    if (P.getAs<PostStmtPurgeDeadSymbols>())
       return PathDiagnosticLocation::createEnd(S, SMng, P.getLocationContext());
-  }
-  else if (const PostImplicitCall *PIE = dyn_cast<PostImplicitCall>(&P)) {
+  } else if (Optional<PostImplicitCall> PIE = P.getAs<PostImplicitCall>()) {
     return PathDiagnosticLocation(PIE->getLocation(), SMng);
-  }
-  else if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
+  } else if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
     return getLocationForCaller(CE->getCalleeContext(),
                                 CE->getLocationContext(),
                                 SMng);
-  }
-  else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&P)) {
+  } else if (Optional<CallExitEnd> CEE = P.getAs<CallExitEnd>()) {
     return getLocationForCaller(CEE->getCalleeContext(),
                                 CEE->getLocationContext(),
                                 SMng);
-  }
-  else {
+  } else {
     llvm_unreachable("Unexpected ProgramPoint");
   }
 
@@ -622,13 +617,13 @@
 
   while (NI) {
     ProgramPoint P = NI->getLocation();
-    if (const StmtPoint *PS = dyn_cast<StmtPoint>(&P)) {
+    if (Optional<StmtPoint> PS = P.getAs<StmtPoint>()) {
       S = PS->getStmt();
-      if (isa<PostStmtPurgeDeadSymbols>(P))
+      if (P.getAs<PostStmtPurgeDeadSymbols>())
         return PathDiagnosticLocation::createEnd(S, SM,
                                                  NI->getLocationContext());
       break;
-    } else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
+    } else if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
       S = BE->getSrc()->getTerminator();
       break;
     }
@@ -998,7 +993,7 @@
 
 std::string StackHintGeneratorForSymbol::getMessage(const ExplodedNode *N){
   ProgramPoint P = N->getLocation();
-  const CallExitEnd *CExit = dyn_cast<CallExitEnd>(&P);
+  Optional<CallExitEnd> CExit = P.getAs<CallExitEnd>();
   assert(CExit && "Stack Hints should be constructed at CallExitEnd points.");
 
   // FIXME: Use CallEvent to abstract this over all calls.