diff options
author | Csaba Dabis <dabis.csaba98@gmail.com> | 2019-05-29 15:58:26 +0000 |
---|---|---|
committer | Csaba Dabis <dabis.csaba98@gmail.com> | 2019-05-29 15:58:26 +0000 |
commit | 35e54eb31ef2280e1ac3c122d619d10c51379bc3 (patch) | |
tree | 123d3890880bc42b354b15ef3e1ca783249af113 /clang/lib/StaticAnalyzer/Core | |
parent | 32981637ce6c025ca0695f768a110c6c98c03e94 (diff) | |
download | bcm5719-llvm-35e54eb31ef2280e1ac3c122d619d10c51379bc3.tar.gz bcm5719-llvm-35e54eb31ef2280e1ac3c122d619d10c51379bc3.zip |
[analyzer] print() JSONify: Constructing objects 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/D62085
llvm-svn: 361980
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 127 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ProgramState.cpp | 2 |
2 files changed, 96 insertions, 33 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index a57546b8909..07fc6f7643a 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -33,6 +33,7 @@ #include "clang/Analysis/ConstructionContext.h" #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/JsonSupport.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/PrettyStackTrace.h" @@ -141,21 +142,47 @@ public: return getLocationContext()->getDecl()->getASTContext(); } - void print(llvm::raw_ostream &OS, PrinterHelper *Helper, PrintingPolicy &PP) { - OS << "(LC" << getLocationContext()->getID() << ','; - if (const Stmt *S = getItem().getStmtOrNull()) - OS << 'S' << S->getID(getASTContext()); + void printJson(llvm::raw_ostream &Out, PrinterHelper *Helper, + PrintingPolicy &PP) const { + const Stmt *S = getItem().getStmtOrNull(); + const CXXCtorInitializer *I = nullptr; + if (!S) + I = getItem().getCXXCtorInitializer(); + + // IDs + Out << "\"lctx_id\": " << getLocationContext()->getID() << ", "; + + if (S) + Out << "\"stmt_id\": " << S->getID(getASTContext()); else - OS << 'I' << getItem().getCXXCtorInitializer()->getID(getASTContext()); - OS << ',' << getItem().getKindAsString(); + Out << "\"init_id\": " << I->getID(getASTContext()); + + // Kind + Out << ", \"kind\": \"" << getItem().getKindAsString() + << "\", \"argument_index\": "; + if (getItem().getKind() == ConstructionContextItem::ArgumentKind) - OS << " #" << getItem().getIndex(); - OS << ") "; - if (const Stmt *S = getItem().getStmtOrNull()) { - S->printPretty(OS, Helper, PP); + Out << getItem().getIndex() << '\"'; + else + Out << "null"; + + // Pretty-print + Out << ", \"pretty\": \""; + + if (S) { + llvm::SmallString<256> TempBuf; + llvm::raw_svector_ostream TempOut(TempBuf); + + // See whether the current statement is pretty-printable. + S->printPretty(TempOut, Helper, PP); + if (!TempBuf.empty()) { + Out << TempBuf.str().trim() << '\"'; + TempBuf.clear(); + } else { + Out << "null"; + } } else { - const CXXCtorInitializer *I = getItem().getCXXCtorInitializer(); - OS << I->getAnyMember()->getNameAsString(); + Out << I->getAnyMember()->getNameAsString() << '\"'; } } @@ -541,33 +568,69 @@ ExprEngine::processRegionChanges(ProgramStateRef state, LCtx, Call); } -static void printObjectsUnderConstructionForContext(raw_ostream &Out, - ProgramStateRef State, - const char *NL, - const LocationContext *LC) { +static void +printObjectsUnderConstructionJson(raw_ostream &Out, ProgramStateRef State, + const char *NL, const LocationContext *LCtx, + unsigned int Space = 0, bool IsDot = false) { PrintingPolicy PP = - LC->getAnalysisDeclContext()->getASTContext().getPrintingPolicy(); - for (auto I : State->get<ObjectsUnderConstruction>()) { - ConstructedObjectKey Key = I.first; + LCtx->getAnalysisDeclContext()->getASTContext().getPrintingPolicy(); + + ++Space; + bool HasItem = false; + + // Store the last key. + const ConstructedObjectKey *LastKey = nullptr; + for (const auto &I : State->get<ObjectsUnderConstruction>()) { + const ConstructedObjectKey &Key = I.first; + if (Key.getLocationContext() != LCtx) + continue; + + if (!HasItem) { + Out << "[" << NL; + HasItem = true; + } + + LastKey = &Key; + } + + for (const auto &I : State->get<ObjectsUnderConstruction>()) { + const ConstructedObjectKey &Key = I.first; SVal Value = I.second; - if (Key.getLocationContext() != LC) + if (Key.getLocationContext() != LCtx) continue; - Key.print(Out, nullptr, PP); - Out << " : " << Value << NL; + + Indent(Out, Space, IsDot) << "{ "; + Key.printJson(Out, nullptr, PP); + Out << ", \"value\": \"" << Value << "\" }"; + + if (&Key != LastKey) + Out << ','; + Out << NL; + } + + if (HasItem) + Indent(Out, --Space, IsDot) << ']'; // End of "location_context". + else { + Out << "null "; } } -void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State, - const LocationContext *LCtx, const char *NL, - unsigned int Space, bool IsDot) const { - if (LCtx) { - if (!State->get<ObjectsUnderConstruction>().isEmpty()) { - Out << "Objects under construction:" << NL; +void ExprEngine::printJson(raw_ostream &Out, ProgramStateRef State, + const LocationContext *LCtx, const char *NL, + unsigned int Space, bool IsDot) const { + Indent(Out, Space, IsDot) << "\"constructing_objects\": "; - LCtx->printJson(Out, NL, Space, IsDot, [&](const LocationContext *LC) { - printObjectsUnderConstructionForContext(Out, State, NL, LC); - }); - } + if (LCtx && !State->get<ObjectsUnderConstruction>().isEmpty()) { + ++Space; + Out << '[' << NL; + LCtx->printJson(Out, NL, Space, IsDot, [&](const LocationContext *LC) { + printObjectsUnderConstructionJson(Out, State, NL, LC, Space, IsDot); + }); + + --Space; + Indent(Out, Space, IsDot) << "]," << NL; // End of "constructing_objects". + } else { + Out << "null," << NL; } getCheckerManager().runCheckersForPrintState(Out, State, NL, ""); diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index b661dd1de08..2f5c33ee6c2 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -458,7 +458,7 @@ void ProgramState::printJson(raw_ostream &Out, const LocationContext *LCtx, printDynamicTypeInfoJson(Out, this, NL, Space, IsDot); // Print checker-specific data. - Mgr.getOwningEngine().printState(Out, this, LCtx, NL, Space, IsDot); + Mgr.getOwningEngine().printJson(Out, this, LCtx, NL, Space, IsDot); } void ProgramState::printDOT(raw_ostream &Out, const LocationContext *LCtx, |