This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324660: [analyzer] Self-debug: Dump environment 
frame-by-frame. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.
Changed prior to commit:
  https://reviews.llvm.org/D42552?vs=131492&id=133488#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D42552

Files:
  cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
  cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
  cfe/trunk/test/Analysis/crash-trace.c
  cfe/trunk/test/Analysis/expr-inspection.c

Index: cfe/trunk/test/Analysis/expr-inspection.c
===================================================================
--- cfe/trunk/test/Analysis/expr-inspection.c
+++ cfe/trunk/test/Analysis/expr-inspection.c
@@ -18,6 +18,8 @@
 // CHECK: Store (direct and default bindings)
 // CHECK-NEXT: (y,0,direct) : 1 S32b
 
-// CHECK: Expressions:
+// CHECK: Expressions by stack frame:
+// CHECK-NEXT: #0 Calling foo
 // CHECK-NEXT: clang_analyzer_printState : &code{clang_analyzer_printState}
-// CHECK-NEXT: {{(Ranges are empty.)|(Constraints:[[:space:]]*$)}}
+
+// CHECK: {{(Ranges are empty.)|(Constraints:[[:space:]]*$)}}
Index: cfe/trunk/test/Analysis/crash-trace.c
===================================================================
--- cfe/trunk/test/Analysis/crash-trace.c
+++ cfe/trunk/test/Analysis/crash-trace.c
@@ -18,6 +18,6 @@
 // CHECK: 0.	Program arguments: {{.*}}clang
 // CHECK-NEXT: 1.	<eof> parser at end of file
 // CHECK-NEXT: 2. While analyzing stack: 
-// CHECK-NEXT:  #0 void inlined()
-// CHECK-NEXT:  #1 void test()
+// CHECK-NEXT:  #0 Calling inlined at line 15
+// CHECK-NEXT:  #1 Calling test
 // CHECK-NEXT: 3.	{{.*}}crash-trace.c:{{[0-9]+}}:3: Error evaluating statement
Index: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -437,24 +437,24 @@
 //  State pretty-printing.
 //===----------------------------------------------------------------------===//
 
-void ProgramState::print(raw_ostream &Out,
-                         const char *NL, const char *Sep) const {
+void ProgramState::print(raw_ostream &Out, const char *NL, const char *Sep,
+                         const LocationContext *LC) const {
   // Print the store.
   ProgramStateManager &Mgr = getStateManager();
   Mgr.getStoreManager().print(getStore(), Out, NL, Sep);
 
   // Print out the environment.
-  Env.print(Out, NL, Sep);
+  Env.print(Out, NL, Sep, LC);
 
   // Print out the constraints.
   Mgr.getConstraintManager().print(this, Out, NL, Sep);
 
   // Print checker-specific data.
   Mgr.getOwningEngine()->printState(Out, this, NL, Sep);
 }
 
-void ProgramState::printDOT(raw_ostream &Out) const {
-  print(Out, "\\l", "\\|");
+void ProgramState::printDOT(raw_ostream &Out, const LocationContext *LC) const {
+  print(Out, "\\l", "\\|", LC);
 }
 
 LLVM_DUMP_METHOD void ProgramState::dump() const {
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2768,12 +2768,6 @@
         << "\\l";
     }
   }
-  static void printLocation2(raw_ostream &Out, SourceLocation SLoc) {
-    if (SLoc.isFileID() && GraphPrintSourceManager->isInMainFile(SLoc))
-      Out << "line " << GraphPrintSourceManager->getExpansionLineNumber(SLoc);
-    else
-      SLoc.print(Out, *GraphPrintSourceManager);
-  }
 
   static std::string getNodeLabel(const ExplodedNode *N, void*){
 
@@ -2948,40 +2942,7 @@
     Out << "\\|StateID: " << (const void*) state.get()
         << " NodeID: " << (const void*) N << "\\|";
 
-    // Analysis stack backtrace.
-    Out << "Location context stack (from current to outer):\\l";
-    const LocationContext *LC = Loc.getLocationContext();
-    unsigned Idx = 0;
-    for (; LC; LC = LC->getParent(), ++Idx) {
-      Out << Idx << ". (" << (const void *)LC << ") ";
-      switch (LC->getKind()) {
-      case LocationContext::StackFrame:
-        if (const NamedDecl *D = dyn_cast<NamedDecl>(LC->getDecl()))
-          Out << "Calling " << D->getQualifiedNameAsString();
-        else
-          Out << "Calling anonymous code";
-        if (const Stmt *S = cast<StackFrameContext>(LC)->getCallSite()) {
-          Out << " at ";
-          printLocation2(Out, S->getLocStart());
-        }
-        break;
-      case LocationContext::Block:
-        Out << "Invoking block";
-        if (const Decl *D = cast<BlockInvocationContext>(LC)->getBlockDecl()) {
-          Out << " defined at ";
-          printLocation2(Out, D->getLocStart());
-        }
-        break;
-      case LocationContext::Scope:
-        Out << "Entering scope";
-        // FIXME: Add more info once ScopeContext is activated.
-        break;
-      }
-      Out << "\\l";
-    }
-    Out << "\\l";
-
-    state->printDOT(Out);
+    state->printDOT(Out, N->getLocationContext());
 
     Out << "\\l";
 
Index: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
@@ -186,28 +186,41 @@
 }
 
 void Environment::print(raw_ostream &Out, const char *NL,
-                        const char *Sep) const {
-  bool isFirst = true;
-
-  for (Environment::iterator I = begin(), E = end(); I != E; ++I) {
-    const EnvironmentEntry &En = I.getKey();
-
-    if (isFirst) {
-      Out << NL << NL
-          << "Expressions:"
-          << NL;
-      isFirst = false;
-    } else {
-      Out << NL;
+                        const char *Sep, const LocationContext *WithLC) const {
+  if (ExprBindings.isEmpty())
+    return;
+
+  if (!WithLC) {
+    // Find the freshest location context.
+    llvm::SmallPtrSet<const LocationContext *, 16> FoundContexts;
+    for (auto I : *this) {
+      const LocationContext *LC = I.first.getLocationContext();
+      if (FoundContexts.count(LC) == 0) {
+        // This context is fresher than all other contexts so far.
+        WithLC = LC;
+        for (const LocationContext *LCI = LC; LCI; LCI = LCI->getParent())
+          FoundContexts.insert(LCI);
+      }
     }
+  }
 
-    const Stmt *S = En.getStmt();
-    assert(S != nullptr && "Expected non-null Stmt");
+  assert(WithLC);
 
-    Out << " (" << (const void*) En.getLocationContext() << ','
-      << (const void*) S << ") ";
-    LangOptions LO; // FIXME.
-    S->printPretty(Out, nullptr, PrintingPolicy(LO));
-    Out << " : " << I.getData();
-  }
+  LangOptions LO; // FIXME.
+  PrintingPolicy PP(LO);
+
+  Out << NL << NL << "Expressions by stack frame:" << NL;
+  WithLC->dumpStack(Out, "", NL, Sep, [&](const LocationContext *LC) {
+    for (auto I : ExprBindings) {
+      if (I.first.getLocationContext() != LC)
+        continue;
+
+      const Stmt *S = I.first.getStmt();
+      assert(S != nullptr && "Expected non-null Stmt");
+
+      Out << "(" << (const void *)LC << ',' << (const void *)S << ") ";
+      S->printPretty(Out, nullptr, PP);
+      Out << " : " << I.second << NL;
+    }
+  });
 }
Index: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
===================================================================
--- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
+++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
@@ -463,28 +463,54 @@
   return false;
 }
 
-void LocationContext::dumpStack(raw_ostream &OS, StringRef Indent) const {
+static void printLocation(raw_ostream &OS, const SourceManager &SM,
+                          SourceLocation SLoc) {
+  if (SLoc.isFileID() && SM.isInMainFile(SLoc))
+    OS << "line " << SM.getExpansionLineNumber(SLoc);
+  else
+    SLoc.print(OS, SM);
+}
+
+void LocationContext::dumpStack(
+    raw_ostream &OS, StringRef Indent, const char *NL, const char *Sep,
+    std::function<void(const LocationContext *)> printMoreInfoPerContext) const {
   ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
   PrintingPolicy PP(Ctx.getLangOpts());
   PP.TerseOutput = 1;
 
+  const SourceManager &SM =
+      getAnalysisDeclContext()->getASTContext().getSourceManager();
+
   unsigned Frame = 0;
   for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
+
     switch (LCtx->getKind()) {
     case StackFrame:
-      OS << Indent << '#' << Frame++ << ' ';
-      cast<StackFrameContext>(LCtx)->getDecl()->print(OS, PP);
-      OS << '\n';
+      OS << Indent << '#' << Frame << ' ';
+      ++Frame;
+      if (const NamedDecl *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
+        OS << "Calling " << D->getQualifiedNameAsString();
+      else
+        OS << "Calling anonymous code";
+      if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
+        OS << " at ";
+        printLocation(OS, SM, S->getLocStart());
+      }
       break;
     case Scope:
-      OS << Indent << "    (scope)\n";
+      OS << "Entering scope";
       break;
     case Block:
-      OS << Indent << "    (block context: "
-                   << cast<BlockInvocationContext>(LCtx)->getContextData()
-                   << ")\n";
+      OS << "Invoking block";
+      if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
+        OS << " defined at ";
+        printLocation(OS, SM, D->getLocStart());
+      }
       break;
     }
+    OS << NL;
+
+    printMoreInfoPerContext(LCtx);
   }
 }
 
Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
===================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -435,9 +435,10 @@
   }
 
   // Pretty-printing.
-  void print(raw_ostream &Out, const char *nl = "\n",
-             const char *sep = "") const;
-  void printDOT(raw_ostream &Out) const;
+  void print(raw_ostream &Out, const char *nl = "\n", const char *sep = "",
+             const LocationContext *CurrentLC = nullptr) const;
+  void printDOT(raw_ostream &Out,
+                const LocationContext *CurrentLC = nullptr) const;
   void printTaint(raw_ostream &Out, const char *nl = "\n",
                   const char *sep = "") const;
 
Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
===================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -92,12 +92,9 @@
   bool operator==(const Environment& RHS) const {
     return ExprBindings == RHS.ExprBindings;
   }
-  
-  void print(raw_ostream &Out, const char *NL, const char *Sep) const;
-  
-private:
-  void printAux(raw_ostream &Out, bool printLocations,
-                const char *NL, const char *Sep) const;
+
+  void print(raw_ostream &Out, const char *NL, const char *Sep,
+             const LocationContext *WithLC = nullptr) const;
 };
 
 class EnvironmentManager {
Index: cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h
===================================================================
--- cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h
+++ cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h
@@ -265,7 +265,11 @@
 
   virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
 
-  void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
+  void dumpStack(
+      raw_ostream &OS, StringRef Indent = "", const char *NL = "\n",
+      const char *Sep = "",
+      std::function<void(const LocationContext *)> printMoreInfoPerContext =
+          [](const LocationContext *) {}) const;
   void dumpStack() const;
 
 public:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to