]> granicus.if.org Git - clang/commitdiff
[analyzer] Have CheckerManager::registerChecker return a pointer to the checker objec...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 28 Feb 2011 01:26:28 +0000 (01:26 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 28 Feb 2011 01:26:28 +0000 (01:26 +0000)
only allow a checker to be registered once.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126605 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/CheckerManager.h

index 276819549d1a887643305812d3f174e2a70b5143..1ad85d2e425592810dd25018f223c6d666ba846e 100644 (file)
@@ -99,6 +99,7 @@ public:
   const LangOptions &getLangOptions() const { return LangOpts; }
 
   typedef void *CheckerRef;
+  typedef void *CheckerTag;
   typedef CheckerFn<> CheckerDtor;
 
 //===----------------------------------------------------------------------===//
@@ -106,11 +107,20 @@ public:
 //===----------------------------------------------------------------------===//
 
   /// \brief Used to register checkers.
+  ///
+  /// \returns a pointer to the checker object.
   template <typename CHECKER>
-  void registerChecker() {
+  CHECKER *registerChecker() {
+    CheckerTag tag = getCheckerTag<CHECKER>();
+    CheckerRef &ref = CheckerTags[tag];
+    if (ref)
+      return static_cast<CHECKER *>(ref); // already registered.
+
     CHECKER *checker = new CHECKER();
     CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
     CHECKER::_register(checker, *this);
+    ref = checker;
+    return checker;
   }
 
 //===----------------------------------------------------------------------===//
@@ -309,6 +319,11 @@ private:
   template <typename CHECKER>
   static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
 
+  template <typename CHECKER>
+  static CheckerTag getCheckerTag() { static int tag; return &tag; }
+
+  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
+
   std::vector<CheckerDtor> CheckerDtors;
 
   struct DeclCheckerInfo {