From 16e3f0e03f390e5f8230e1f035168968810dbab2 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Thu, 27 Nov 2008 01:55:08 +0000 Subject: Add support for pluggable components of static analyzer. - Creator function pointers are saved in ManagerRegistry. - The Register* class is used to notify ManagerRegistry new module is available. - AnalysisManager queries ManagerRegistry for configurable module. Then it passes them to GRExprEngine, in turn to GRStateManager. llvm-svn: 60143 --- clang/Driver/AnalysisConsumer.cpp | 58 +++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) (limited to 'clang/Driver/AnalysisConsumer.cpp') diff --git a/clang/Driver/AnalysisConsumer.cpp b/clang/Driver/AnalysisConsumer.cpp index df46322b5e6..14b4440695f 100644 --- a/clang/Driver/AnalysisConsumer.cpp +++ b/clang/Driver/AnalysisConsumer.cpp @@ -13,6 +13,7 @@ #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" @@ -129,12 +130,20 @@ namespace { llvm::OwningPtr liveness; llvm::OwningPtr 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); @@ -151,14 +160,13 @@ namespace { 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())); @@ -215,7 +223,7 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break; bool shouldVisualizeGraphviz() const { return C.VisGraphviz; } - + bool shouldVisualizeUbigraph() const { return C.VisUbigraph; } @@ -249,8 +257,33 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break; << 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 { @@ -370,7 +403,8 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf, if (!L) return; GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L, - mgr.getStoreManagerCreator()); + mgr.getStoreManagerCreator(), + mgr.getConstraintManagerCreator()); Eng.setTransferFunctions(tf); -- cgit v1.2.3