#include "ASTConsumers.h"
#include "clang/Driver/PathDiagnosticClients.h"
+#include "clang/Driver/ManagerRegistry.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
llvm::OwningPtr<LiveVariables> liveness;
llvm::OwningPtr<ParentMap> PM;
+ // Configurable components creators.
+ StoreManagerCreator CreateStoreMgr;
+ ConstraintManagerCreator CreateConstraintMgr;
+
public:
AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b)
- : D(d), Body(b), TU(0), AScope(ScopeDecl), C(c), DisplayedFunction(false) {}
+ : D(d), Body(b), TU(0), AScope(ScopeDecl), C(c), DisplayedFunction(false) {
+ setManagerCreators();
+ }
AnalysisManager(AnalysisConsumer& c, TranslationUnit* tu)
- : D(0), Body(0), TU(tu), AScope(ScopeTU), C(c), DisplayedFunction(false) {}
+ : D(0), Body(0), TU(tu), AScope(ScopeTU), C(c), DisplayedFunction(false) {
+ setManagerCreators();
+ }
Decl* getCodeDecl() const {
assert (AScope == ScopeDecl);
return TU;
}
- GRStateManager::StoreManagerCreator getStoreManagerCreator() {
- switch (C.SM) {
- default:
-#define ANALYSIS_STORE(NAME, CMDFLAG, DESC)\
-case NAME##Model: return Create##NAME##Manager;
-#include "Analyses.def"
- }
+ StoreManagerCreator getStoreManagerCreator() {
+ return CreateStoreMgr;
};
+
+ ConstraintManagerCreator getConstraintManagerCreator() {
+ return CreateConstraintMgr;
+ }
virtual CFG* getCFG() {
if (!cfg) cfg.reset(CFG::buildCFG(getBody()));
bool shouldVisualizeGraphviz() const {
return C.VisGraphviz;
}
-\v
+
bool shouldVisualizeUbigraph() const {
return C.VisUbigraph;
}
<< MD->getSelector().getAsString() << "'\n";
}
}
+
+ private:
+ /// Set configurable analyzer components creators. First check if there are
+ /// components registered at runtime. Otherwise fall back to builtin
+ /// components.
+ void setManagerCreators() {
+ if (ManagerRegistry::StoreMgrCreator != 0) {
+ CreateStoreMgr = ManagerRegistry::StoreMgrCreator;
+ }
+ else {
+ switch (C.SM) {
+ default:
+ assert(0 && "Unknown store manager.");
+#define ANALYSIS_STORE(NAME, CMDFLAG, DESC) \
+ case NAME##Model: CreateStoreMgr = Create##NAME##Manager; break;
+#include "Analyses.def"
+ }
+ }
+
+ if (ManagerRegistry::ConstraintMgrCreator != 0)
+ CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator;
+ else
+ CreateConstraintMgr = CreateBasicConstraintManager;
+ }
+
};
-
+
} // end anonymous namespace
namespace llvm {
if (!L) return;
GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L,
- mgr.getStoreManagerCreator());
+ mgr.getStoreManagerCreator(),
+ mgr.getConstraintManagerCreator());
Eng.setTransferFunctions(tf);
public:
GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx, LiveVariables& L,
- GRStateManager::StoreManagerCreator SMC =
- CreateBasicStoreManager);
+ StoreManagerCreator SMC = CreateBasicStoreManager,
+ ConstraintManagerCreator CMC = CreateBasicConstraintManager);
~GRExprEngine();
class GRStateManager;
class GRTransferFuncs;
+typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&);
+typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
+
//===----------------------------------------------------------------------===//
// GRStateTrait - Traits used by the Generic Data Map of a GRState.
//===----------------------------------------------------------------------===//
public:
- typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&);
- typedef StoreManager* (*StoreManagerCreator)(GRStateManager&);
-
GRStateManager(ASTContext& Ctx,
StoreManagerCreator CreateStoreManager,
ConstraintManagerCreator CreateConstraintManager,
--- /dev/null
+#ifndef LLVM_CLANG_MANAGER_REGISTRY_H
+#define LLVM_CLANG_MANAGER_REGISTRY_H
+
+#include "clang/Analysis/PathSensitive/GRState.h"
+
+namespace clang {
+
+/// ManagerRegistry - This class records manager creators registered at
+/// runtime. The information is communicated to AnalysisManager through static
+/// members. Better design is expected.
+
+class ManagerRegistry {
+public:
+ static StoreManagerCreator StoreMgrCreator;
+ static ConstraintManagerCreator ConstraintMgrCreator;
+};
+
+/// RegisterConstraintManager - This class is used to setup the constraint
+/// manager of the static analyzer. The constructor takes a creator function
+/// pointer for creating the constraint manager.
+///
+/// It is used like this:
+///
+/// class MyConstraintManager {};
+/// ConstraintManager* CreateMyConstraintManager(GRStateManager& statemgr) {
+/// return new MyConstraintManager(statemgr);
+/// }
+/// RegisterConstraintManager X(CreateMyConstraintManager);
+
+class RegisterConstraintManager {
+public:
+ RegisterConstraintManager(ConstraintManagerCreator CMC) {
+ assert(ManagerRegistry::ConstraintMgrCreator == 0
+ && "ConstraintMgrCreator already set!");
+ ManagerRegistry::ConstraintMgrCreator = CMC;
+ }
+};
+
+}
+#endif
GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx,
LiveVariables& L,
- GRStateManager::StoreManagerCreator SMC)
+ StoreManagerCreator SMC,
+ ConstraintManagerCreator CMC)
: CoreEngine(cfg, CD, Ctx, *this),
G(CoreEngine.getGraph()),
Liveness(L),
Builder(NULL),
- StateMgr(G.getContext(), SMC,
- CreateBasicConstraintManager, G.getAllocator(), cfg, CD, L),
+ StateMgr(G.getContext(), SMC, CMC, G.getAllocator(), cfg, CD, L),
SymMgr(StateMgr.getSymbolManager()),
CurrentStmt(NULL),
NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
--- /dev/null
+#include "clang/Driver/ManagerRegistry.h"
+
+using namespace clang;
+
+StoreManagerCreator ManagerRegistry::StoreMgrCreator = 0;
+
+ConstraintManagerCreator ManagerRegistry::ConstraintMgrCreator = 0;