--- /dev/null
+//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- 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 AnalysisContext, a class that manages the analysis context
+// data for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include <map>
+
+namespace clang {
+
+class Decl;
+class Stmt;
+class CFG;
+class LiveVariables;
+class ParentMap;
+
+/// AnalysisContext contains the context data for the function or method under
+/// analysis.
+class AnalysisContext {
+ Decl *D;
+ Stmt *Body;
+
+ // AnalysisContext owns the following data.
+ CFG *cfg;
+ LiveVariables *liveness;
+ ParentMap *PM;
+
+public:
+ AnalysisContext() : D(0), Body(0), cfg(0), liveness(0), PM(0) {}
+ ~AnalysisContext();
+
+ void setDecl(Decl* d) { D = d; }
+ Decl *getDecl() { return D; }
+ Stmt *getBody();
+ CFG *getCFG();
+ ParentMap &getParentMap();
+ LiveVariables *getLiveVariables();
+};
+
+class AnalysisContextManager {
+ std::map<Decl*, AnalysisContext> Contexts;
+
+public:
+ typedef std::map<Decl*, AnalysisContext>::iterator iterator;
+
+ AnalysisContext *getContext(Decl *D);
+};
+
+}
+
+#endif
--- /dev/null
+//== AnalysisContext.cpp - Analysis context for Path Sens analysis -*- 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 AnalysisContext, a class that manages the analysis context
+// data for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/AnalysisContext.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ParentMap.h"
+
+using namespace clang;
+
+AnalysisContext::~AnalysisContext() {
+ delete cfg;
+ delete liveness;
+ delete PM;
+}
+
+Stmt *AnalysisContext::getBody() {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ return FD->getBody();
+ else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ return MD->getBody();
+
+ assert(0 && "unknown code decl");
+}
+
+CFG *AnalysisContext::getCFG() {
+ if (!cfg)
+ cfg = CFG::buildCFG(getBody(), &D->getASTContext());
+ return cfg;
+}
+
+ParentMap &AnalysisContext::getParentMap() {
+ if (!PM)
+ PM = new ParentMap(getBody());
+ return *PM;
+}
+
+LiveVariables *AnalysisContext::getLiveVariables() {
+ if (!liveness) {
+ CFG *c = getCFG();
+ if (!c)
+ return 0;
+
+ liveness = new LiveVariables(D->getASTContext(), *c);
+ liveness->runOnCFG(*c);
+ liveness->runOnAllBlocks(*c, 0, true);
+ }
+
+ return liveness;
+}
+
+AnalysisContext *AnalysisContextManager::getContext(Decl *D) {
+ iterator I = Contexts.find(D);
+ if (I != Contexts.end())
+ return &(I->second);
+
+ AnalysisContext &Ctx = Contexts[D];
+ Ctx.setDecl(D);
+ return &Ctx;
+}
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/AST/ParentMap.h"
+#include "clang/Analysis/PathSensitive/AnalysisContext.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/LocalCheckers.h"
class VISIBILITY_HIDDEN AnalysisManager : public BugReporterData {
- Decl* D; Stmt* Body;
+ AnalysisContextManager ContextMgr;
+ AnalysisContext *CurrentContext;
enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
AnalysisConsumer& C;
bool DisplayedFunction;
- llvm::OwningPtr<CFG> cfg;
- llvm::OwningPtr<LiveVariables> liveness;
- llvm::OwningPtr<ParentMap> PM;
-
// Configurable components creators.
StoreManagerCreator CreateStoreMgr;
ConstraintManagerCreator CreateConstraintMgr;
public:
- AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b, bool displayProgress)
- : D(d), Body(b), AScope(ScopeDecl), C(c),
- DisplayedFunction(!displayProgress) {
+ AnalysisManager(AnalysisConsumer& c, Decl* d, bool displayProgress)
+ : AScope(ScopeDecl), C(c), DisplayedFunction(!displayProgress) {
setManagerCreators();
+ CurrentContext = ContextMgr.getContext(d);
}
AnalysisManager(AnalysisConsumer& c, bool displayProgress)
- : D(0), Body(0), AScope(ScopeTU), C(c),
- DisplayedFunction(!displayProgress) {
+ : AScope(ScopeTU), C(c), DisplayedFunction(!displayProgress) {
setManagerCreators();
+ CurrentContext = 0;
}
Decl* getCodeDecl() const {
assert (AScope == ScopeDecl);
- return D;
+ return CurrentContext->getDecl();
}
Stmt* getBody() const {
assert (AScope == ScopeDecl);
- return Body;
+ return CurrentContext->getBody();
}
StoreManagerCreator getStoreManagerCreator() {
}
virtual CFG* getCFG() {
- if (!cfg) cfg.reset(CFG::buildCFG(getBody(), &getContext()));
- return cfg.get();
+ return CurrentContext->getCFG();
}
virtual ParentMap& getParentMap() {
- if (!PM)
- PM.reset(new ParentMap(getBody()));
- return *PM.get();
+ return CurrentContext->getParentMap();
+ }
+
+ virtual LiveVariables* getLiveVariables() {
+ return CurrentContext->getLiveVariables();
}
virtual ASTContext& getContext() {
}
return C.PD.get();
}
-
- virtual LiveVariables* getLiveVariables() {
- if (!liveness) {
- CFG* c = getCFG();
- if (!c) return 0;
-
- liveness.reset(new LiveVariables(getContext(), *c));
- liveness->runOnCFG(*c);
- liveness->runOnAllBlocks(*c, 0, true);
- }
-
- return liveness.get();
- }
bool shouldVisualizeGraphviz() const { return C.Opts.VisualizeEGDot; }
// Create an AnalysisManager that will manage the state for analyzing
// this method/function.
- AnalysisManager mgr(*this, D, Body, Opts.AnalyzerDisplayProgress);
+ AnalysisManager mgr(*this, D, Opts.AnalyzerDisplayProgress);
// Dispatch on the actions.
for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)