blob: 38550798b812fcbdef73370dabbe6c69686f1cbf [file] [log] [blame]
//== AnalysisManager.h - Path sensitive analysis data manager ------*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the AnalysisManager class that manages the data and policy
// for path sensitive analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Checker/BugReporter/BugReporter.h"
#include "clang/Checker/BugReporter/PathDiagnostic.h"
namespace clang {
namespace idx {
class Indexer;
class TranslationUnit;
}
class AnalysisManager : public BugReporterData {
AnalysisContextManager AnaCtxMgr;
LocationContextManager LocCtxMgr;
ASTContext &Ctx;
Diagnostic &Diags;
const LangOptions &LangInfo;
llvm::OwningPtr<PathDiagnosticClient> PD;
// Configurable components creators.
StoreManagerCreator CreateStoreMgr;
ConstraintManagerCreator CreateConstraintMgr;
/// \brief Provide function definitions in other translation units. This is
/// NULL if we don't have multiple translation units. AnalysisManager does
/// not own the Indexer.
idx::Indexer *Idxer;
enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
// The maximum number of exploded nodes the analyzer will generate.
unsigned MaxNodes;
// The maximum number of times the analyzer will go through a loop.
unsigned MaxLoop;
bool VisualizeEGDot;
bool VisualizeEGUbi;
bool PurgeDead;
/// EargerlyAssume - A flag indicating how the engine should handle
// expressions such as: 'x = (y != 0)'. When this flag is true then
// the subexpression 'y != 0' will be eagerly assumed to be true or false,
// thus evaluating it to the integers 0 or 1 respectively. The upside
// is that this can increase analysis precision until we have a better way
// to lazily evaluate such logic. The downside is that it eagerly
// bifurcates paths.
bool EagerlyAssume;
bool TrimGraph;
bool InlineCall;
public:
AnalysisManager(ASTContext &ctx, Diagnostic &diags,
const LangOptions &lang, PathDiagnosticClient *pd,
StoreManagerCreator storemgr,
ConstraintManagerCreator constraintmgr,
idx::Indexer *idxer,
unsigned maxnodes, unsigned maxloop,
bool vizdot, bool vizubi, bool purge, bool eager, bool trim,
bool inlinecall, bool useUnoptimizedCFG)
: AnaCtxMgr(useUnoptimizedCFG), Ctx(ctx), Diags(diags), LangInfo(lang),
PD(pd),
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),Idxer(idxer),
AScope(ScopeDecl), MaxNodes(maxnodes), MaxLoop(maxloop),
VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {}
~AnalysisManager() { FlushDiagnostics(); }
void ClearContexts() {
LocCtxMgr.clear();
AnaCtxMgr.clear();
}
AnalysisContextManager& getAnalysisContextManager() {
return AnaCtxMgr;
}
StoreManagerCreator getStoreManagerCreator() {
return CreateStoreMgr;
}
ConstraintManagerCreator getConstraintManagerCreator() {
return CreateConstraintMgr;
}
idx::Indexer *getIndexer() const { return Idxer; }
virtual ASTContext &getASTContext() {
return Ctx;
}
virtual SourceManager &getSourceManager() {
return getASTContext().getSourceManager();
}
virtual Diagnostic &getDiagnostic() {
return Diags;
}
const LangOptions &getLangOptions() const {
return LangInfo;
}
virtual PathDiagnosticClient *getPathDiagnosticClient() {
return PD.get();
}
void FlushDiagnostics() {
if (PD.get())
PD->FlushDiagnostics();
}
unsigned getMaxNodes() const { return MaxNodes; }
unsigned getMaxLoop() const { return MaxLoop; }
bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
bool shouldVisualize() const {
return VisualizeEGDot || VisualizeEGUbi;
}
bool shouldTrimGraph() const { return TrimGraph; }
bool shouldPurgeDead() const { return PurgeDead; }
bool shouldEagerlyAssume() const { return EagerlyAssume; }
bool shouldInlineCall() const { return InlineCall; }
bool hasIndexer() const { return Idxer != 0; }
const AnalysisContext *getAnalysisContextInAnotherTU(const Decl *D);
CFG *getCFG(Decl const *D) {
return AnaCtxMgr.getContext(D)->getCFG();
}
LiveVariables *getLiveVariables(Decl const *D) {
return AnaCtxMgr.getContext(D)->getLiveVariables();
}
ParentMap &getParentMap(Decl const *D) {
return AnaCtxMgr.getContext(D)->getParentMap();
}
AnalysisContext *getAnalysisContext(const Decl *D) {
return AnaCtxMgr.getContext(D);
}
AnalysisContext *getAnalysisContext(const Decl *D, idx::TranslationUnit *TU) {
return AnaCtxMgr.getContext(D, TU);
}
const StackFrameContext *getStackFrame(AnalysisContext *Ctx,
LocationContext const *Parent,
Stmt const *S, const CFGBlock *Blk,
unsigned Idx) {
return LocCtxMgr.getStackFrame(Ctx, Parent, S, Blk, Idx);
}
// Get the top level stack frame.
const StackFrameContext *getStackFrame(Decl const *D,
idx::TranslationUnit *TU) {
return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D, TU), 0, 0, 0, 0);
}
// Get a stack frame with parent.
StackFrameContext const *getStackFrame(Decl const *D,
LocationContext const *Parent,
Stmt const *S, const CFGBlock *Blk,
unsigned Idx) {
return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), Parent, S, Blk,Idx);
}
};
}
#endif