In preparation for fixing PR 6884, rework CFGElement to have getAs<> return pointers instead of fresh CFGElements.

- Also, consoldiate getDtorKind() and getKind() into one "kind".
- Add empty getDestructorDecl() method to CFGImplicitDtor.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126738 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index 3d8327f..905a99e 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -112,8 +112,8 @@
     // such as llvm_unreachable.
     if (!CB->empty()) {
       CFGElement First = CB->front();
-      if (CFGStmt S = First.getAs<CFGStmt>()) {
-        if (const CallExpr *CE = dyn_cast<CallExpr>(S.getStmt())) {
+      if (const CFGStmt *S = First.getAs<CFGStmt>()) {
+        if (const CallExpr *CE = dyn_cast<CallExpr>(S->getStmt())) {
           if (CE->isBuiltinCall(Ctx) == Builtin::BI__builtin_unreachable)
             continue;
         }
@@ -164,8 +164,8 @@
 // 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 (CFGStmt S = I->getAs<CFGStmt>())
-      return S;
+    if (const CFGStmt *S = I->getAs<CFGStmt>())
+      return S->getStmt();
   }
   if (const Stmt *S = CB->getTerminator())
     return S;
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 672982a..74cd359 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1170,13 +1170,14 @@
       }
 
       if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
-        if (CFGStmt S = BE->getFirstElement().getAs<CFGStmt>()) {
-          if (IsControlFlowExpr(S)) {
+        if (const CFGStmt *S = BE->getFirstElement().getAs<CFGStmt>()) {
+          const Stmt *stmt = S->getStmt();
+          if (IsControlFlowExpr(stmt)) {
             // Add the proper context for '&&', '||', and '?'.
-            EB.addContext(S);
+            EB.addContext(stmt);
           }
           else
-            EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
+            EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt());
         }
         
         break;
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index cb777ae..615c216 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -191,18 +191,20 @@
 void ExprEngine::processCFGElement(const CFGElement E, 
                                   StmtNodeBuilder& builder) {
   switch (E.getKind()) {
-  case CFGElement::Statement:
-    ProcessStmt(E.getAs<CFGStmt>(), builder);
-    break;
-  case CFGElement::Initializer:
-    ProcessInitializer(E.getAs<CFGInitializer>(), builder);
-    break;
-  case CFGElement::ImplicitDtor:
-    ProcessImplicitDtor(E.getAs<CFGImplicitDtor>(), builder);
-    break;
-  default:
-    // Suppress compiler warning.
-    llvm_unreachable("Unexpected CFGElement kind.");
+    case CFGElement::Invalid:
+      llvm_unreachable("Unexpected CFGElement kind.");
+    case CFGElement::Statement:
+      ProcessStmt(E.getAs<CFGStmt>()->getStmt(), builder);
+      return;
+    case CFGElement::Initializer:
+      ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), builder);
+      return;
+    case CFGElement::AutomaticObjectDtor:
+    case CFGElement::BaseDtor:
+    case CFGElement::MemberDtor:
+    case CFGElement::TemporaryDtor:
+      ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), builder);
+      return;
   }
 }
 
@@ -345,7 +347,7 @@
                                        StmtNodeBuilder &builder) {
   Builder = &builder;
 
-  switch (D.getDtorKind()) {
+  switch (D.getKind()) {
   case CFGElement::AutomaticObjectDtor:
     ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), builder);
     break;