r361972 - [analyzer] print() JSONify: Store implementation
Csaba Dabis via cfe-commits
cfe-commits at lists.llvm.org
Wed May 29 08:25:20 PDT 2019
Author: charusso
Date: Wed May 29 08:25:19 2019
New Revision: 361972
URL: http://llvm.org/viewvc/llvm-project?rev=361972&view=rev
Log:
[analyzer] print() JSONify: Store implementation
Summary: -
Reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus
Reviewed By: NoQ
Subscribers: szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy,
dkrupp
Tags: #clang
Differential Revision: https://reviews.llvm.org/D61912
Added:
cfe/trunk/include/clang/Basic/JsonSupport.h
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
cfe/trunk/test/Analysis/expr-inspection.c
Added: cfe/trunk/include/clang/Basic/JsonSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/JsonSupport.h?rev=361972&view=auto
==============================================================================
--- cfe/trunk/include/clang/Basic/JsonSupport.h (added)
+++ cfe/trunk/include/clang/Basic/JsonSupport.h Wed May 29 08:25:19 2019
@@ -0,0 +1,27 @@
+//===- JsonSupport.h - JSON Output Utilities --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_JSONSUPPORT_H
+#define LLVM_CLANG_BASIC_JSONSUPPORT_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/raw_ostream.h"
+
+
+namespace clang {
+
+inline raw_ostream &Indent(raw_ostream &Out, const unsigned int Space,
+ bool IsDot) {
+ for (unsigned int I = 0; I < Space * 2; ++I)
+ Out << (IsDot ? " " : " ");
+ return Out;
+}
+
+} // namespace clang
+
+#endif // LLVM_CLANG_BASIC_JSONSUPPORT_H
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=361972&r1=361971&r2=361972&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Wed May 29 08:25:19 2019
@@ -424,10 +424,12 @@ public:
}
// Pretty-printing.
- 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 printJson(raw_ostream &Out, const LocationContext *LCtx = nullptr,
+ const char *NL = "\n", const char *Sep = "",
+ unsigned int Space = 0, bool IsDot = false) const;
+
+ void printDOT(raw_ostream &Out, const LocationContext *LCtx = nullptr,
+ unsigned int Space = 0) const;
void dump() const;
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h?rev=361972&r1=361971&r2=361972&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Wed May 29 08:25:19 2019
@@ -253,7 +253,8 @@ public:
virtual bool scanReachableSymbols(Store S, const MemRegion *R,
ScanReachableSymbols &Visitor) = 0;
- virtual void print(Store store, raw_ostream &Out, const char* nl) = 0;
+ virtual void printJson(raw_ostream &Out, Store S, const char *NL,
+ unsigned int Space, bool IsDot) const = 0;
class BindingsHandler {
public:
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=361972&r1=361971&r2=361972&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Wed May 29 08:25:19 2019
@@ -440,16 +440,16 @@ void ProgramState::setStore(const StoreR
// State pretty-printing.
//===----------------------------------------------------------------------===//
-void ProgramState::print(raw_ostream &Out,
- const char *NL, const char *Sep,
- const LocationContext *LC) const {
+void ProgramState::printJson(raw_ostream &Out, const LocationContext *LCtx,
+ const char *NL, const char *Sep,
+ unsigned int Space, bool IsDot) const {
// Print the store.
ProgramStateManager &Mgr = getStateManager();
const ASTContext &Context = getStateManager().getContext();
- Mgr.getStoreManager().print(getStore(), Out, NL);
+ Mgr.getStoreManager().printJson(Out, getStore(), NL, Space, IsDot);
// Print out the environment.
- Env.print(Out, NL, Sep, Context, LC);
+ Env.print(Out, NL, Sep, Context, LCtx);
// Print out the constraints.
Mgr.getConstraintManager().print(this, Out, NL, Sep);
@@ -458,16 +458,16 @@ void ProgramState::print(raw_ostream &Ou
printDynamicTypeInfo(this, Out, NL, Sep);
// Print checker-specific data.
- Mgr.getOwningEngine().printState(Out, this, NL, Sep, LC);
+ Mgr.getOwningEngine().printState(Out, this, NL, Sep, LCtx);
}
-void ProgramState::printDOT(raw_ostream &Out,
- const LocationContext *LC) const {
- print(Out, "\\l", "\\|", LC);
+void ProgramState::printDOT(raw_ostream &Out, const LocationContext *LCtx,
+ unsigned int Space) const {
+ printJson(Out, LCtx, "\\l", "\\|", Space, /*IsDot=*/true);
}
LLVM_DUMP_METHOD void ProgramState::dump() const {
- print(llvm::errs());
+ printJson(llvm::errs());
}
AnalysisManager& ProgramState::getAnalysisManager() const {
Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=361972&r1=361971&r2=361972&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Wed May 29 08:25:19 2019
@@ -19,6 +19,7 @@
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Basic/JsonSupport.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
@@ -120,21 +121,21 @@ BindingKey BindingKey::Make(const MemReg
}
namespace llvm {
- static inline
- raw_ostream &operator<<(raw_ostream &os, BindingKey K) {
- os << '(' << K.getRegion();
- if (!K.hasSymbolicOffset())
- os << ',' << K.getOffset();
- os << ',' << (K.isDirect() ? "direct" : "default")
- << ')';
- return os;
- }
+static inline raw_ostream &operator<<(raw_ostream &Out, BindingKey K) {
+ Out << "\"kind\": \"" << (K.isDirect() ? "Direct" : "Default")
+ << "\", \"offset\": ";
+
+ if (!K.hasSymbolicOffset())
+ Out << K.getOffset();
+ else
+ Out << "null";
-} // end llvm namespace
+ return Out;
+}
+
+} // namespace llvm
-#ifndef NDEBUG
LLVM_DUMP_METHOD void BindingKey::dump() const { llvm::errs() << *this; }
-#endif
//===----------------------------------------------------------------------===//
// Actual Store type.
@@ -206,18 +207,31 @@ public:
return asImmutableMap().getRootWithoutRetain();
}
- void dump(raw_ostream &OS, const char *nl) const {
- for (iterator I = begin(), E = end(); I != E; ++I) {
- const ClusterBindings &Cluster = I.getData();
- for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
- CI != CE; ++CI) {
- OS << ' ' << CI.getKey() << " : " << CI.getData() << nl;
- }
- OS << nl;
- }
+ void printJson(raw_ostream &Out, const char *NL = "\n",
+ unsigned int Space = 0, bool IsDot = false) const {
+ for (iterator I = begin(); I != end(); ++I) {
+ Indent(Out, Space, IsDot)
+ << "{ \"cluster\": \"" << I.getKey() << "\", \"items\": [" << NL;
+
+ ++Space;
+ const ClusterBindings &CB = I.getData();
+ for (ClusterBindings::iterator CI = CB.begin(); CI != CB.end(); ++CI) {
+ Indent(Out, Space, IsDot) << "{ " << CI.getKey() << ", \"value\": \""
+ << CI.getData() << "\" }";
+ if (std::next(CI) != CB.end())
+ Out << ',';
+ Out << NL;
+ }
+
+ --Space;
+ Indent(Out, Space, IsDot) << "]}";
+ if (std::next(I) != end())
+ Out << ',';
+ Out << NL;
+ }
}
- LLVM_DUMP_METHOD void dump() const { dump(llvm::errs(), "\n"); }
+ LLVM_DUMP_METHOD void dump() const { printJson(llvm::errs()); }
};
} // end anonymous namespace
@@ -594,7 +608,8 @@ public: // Part of public interface to c
RBFactory.getTreeFactory());
}
- void print(Store store, raw_ostream &Out, const char* nl) override;
+ void printJson(raw_ostream &Out, Store S, const char *NL = "\n",
+ unsigned int Space = 0, bool IsDot = false) const override;
void iterBindings(Store store, BindingsHandler& f) override {
RegionBindingsRef B = getRegionBindings(store);
@@ -2611,11 +2626,18 @@ StoreRef RegionStoreManager::removeDeadB
// Utility methods.
//===----------------------------------------------------------------------===//
-void RegionStoreManager::print(Store store, raw_ostream &OS,
- const char* nl) {
- RegionBindingsRef B = getRegionBindings(store);
- OS << "Store (direct and default bindings), "
- << B.asStore()
- << " :" << nl;
- B.dump(OS, nl);
+void RegionStoreManager::printJson(raw_ostream &Out, Store S, const char *NL,
+ unsigned int Space, bool IsDot) const {
+ RegionBindingsRef Bindings = getRegionBindings(S);
+
+ Indent(Out, Space, IsDot) << "\"store\": ";
+
+ if (Bindings.isEmpty()) {
+ Out << "null," << NL;
+ return;
+ }
+
+ Out << '[' << NL;
+ Bindings.printJson(Out, NL, ++Space, IsDot);
+ Indent(Out, --Space, IsDot) << "]," << NL;
}
Modified: cfe/trunk/test/Analysis/expr-inspection.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/expr-inspection.c?rev=361972&r1=361971&r2=361972&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/expr-inspection.c (original)
+++ cfe/trunk/test/Analysis/expr-inspection.c Wed May 29 08:25:19 2019
@@ -1,4 +1,6 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -verify %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 \
+// RUN: -analyzer-checker=debug.ExprInspection \
+// RUN: -verify %s 2>&1 | FileCheck %s
// Self-tests for the debug.ExprInspection checker.
@@ -10,16 +12,26 @@ void foo(int x) {
clang_analyzer_dump(x); // expected-warning{{reg_$0<int x>}}
clang_analyzer_dump(x + (-1)); // expected-warning{{(reg_$0<int x>) + -1}}
int y = 1;
- clang_analyzer_printState();
- for (; y < 3; ++y)
+ for (; y < 3; ++y) {
clang_analyzer_numTimesReached(); // expected-warning{{2}}
+
+ if (y == 2) {
+ int z = x > 13;
+ if (!z)
+ clang_analyzer_printState();
+ }
+ }
}
-// CHECK: Store (direct and default bindings)
-// CHECK-NEXT: (y,0,direct) : 1 S32b
+// CHECK: "store": [
+// CHECK-NEXT: { "cluster": "y", "items": [
+// CHECK-NEXT: { "kind": "Direct", "offset": 0, "value": "2 S32b" }
+// CHECK-NEXT: ]}
+// CHECK-NEXT: ]
-// CHECK: Expressions by stack frame:
+// CHECK: Expressions by stack frame:
// CHECK-NEXT: #0 Calling foo
-// CHECK-NEXT: clang_analyzer_printState : &code{clang_analyzer_printState}
+// CHECK-NEXT: (LC1, S847) clang_analyzer_printState : &code{clang_analyzer_printState}
-// CHECK: {{(Ranges are empty.)|(Constraints:[[:space:]]*$)}}
+// CHECK: Ranges of symbol values:
+// CHECK-NEXT: reg_$0<int x> : { [-2147483648, 13] }
More information about the cfe-commits
mailing list