1 //===- AnalysisOrderChecker - Print callbacks called ------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This checker prints callbacks that are called during analysis.
11 // This is required to ensure that callbacks are fired in order
12 // and do not duplicate or get lost.
13 // Feel free to extend this checker with any callback you need to check.
15 //===----------------------------------------------------------------------===//
17 #include "ClangSACheckers.h"
18 #include "clang/StaticAnalyzer/Core/Checker.h"
19 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
20 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
22 using namespace clang;
27 class AnalysisOrderChecker
28 : public Checker<check::PreStmt<CastExpr>,
29 check::PostStmt<CastExpr>,
30 check::PreStmt<ArraySubscriptExpr>,
31 check::PostStmt<ArraySubscriptExpr>,
33 check::RegionChanges> {
34 bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const {
35 return Opts.getBooleanOption("*", false, this) ||
36 Opts.getBooleanOption(CallbackName, false, this);
39 bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
40 AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions();
41 return isCallbackEnabled(Opts, CallbackName);
44 bool isCallbackEnabled(ProgramStateRef State, StringRef CallbackName) const {
45 AnalyzerOptions &Opts = State->getStateManager().getOwningEngine()
46 ->getAnalysisManager().getAnalyzerOptions();
47 return isCallbackEnabled(Opts, CallbackName);
51 void checkPreStmt(const CastExpr *CE, CheckerContext &C) const {
52 if (isCallbackEnabled(C, "PreStmtCastExpr"))
53 llvm::errs() << "PreStmt<CastExpr> (Kind : " << CE->getCastKindName()
57 void checkPostStmt(const CastExpr *CE, CheckerContext &C) const {
58 if (isCallbackEnabled(C, "PostStmtCastExpr"))
59 llvm::errs() << "PostStmt<CastExpr> (Kind : " << CE->getCastKindName()
63 void checkPreStmt(const ArraySubscriptExpr *SubExpr,
64 CheckerContext &C) const {
65 if (isCallbackEnabled(C, "PreStmtArraySubscriptExpr"))
66 llvm::errs() << "PreStmt<ArraySubscriptExpr>\n";
69 void checkPostStmt(const ArraySubscriptExpr *SubExpr,
70 CheckerContext &C) const {
71 if (isCallbackEnabled(C, "PostStmtArraySubscriptExpr"))
72 llvm::errs() << "PostStmt<ArraySubscriptExpr>\n";
75 void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const {
76 if (isCallbackEnabled(C, "Bind"))
77 llvm::errs() << "Bind\n";
81 checkRegionChanges(ProgramStateRef State,
82 const InvalidatedSymbols *Invalidated,
83 ArrayRef<const MemRegion *> ExplicitRegions,
84 ArrayRef<const MemRegion *> Regions,
85 const LocationContext *LCtx, const CallEvent *Call) const {
86 if (isCallbackEnabled(State, "RegionChanges"))
87 llvm::errs() << "RegionChanges\n";
91 } // end anonymous namespace
93 //===----------------------------------------------------------------------===//
95 //===----------------------------------------------------------------------===//
97 void ento::registerAnalysisOrderChecker(CheckerManager &mgr) {
98 mgr.registerChecker<AnalysisOrderChecker>();