[clang-tidy] Add a whitelist option in google-runtime-references.
authorHaojian Wu <hokein@google.com>
Mon, 10 Oct 2016 16:38:11 +0000 (16:38 +0000)
committerHaojian Wu <hokein@google.com>
Mon, 10 Oct 2016 16:38:11 +0000 (16:38 +0000)
Reviewers: aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D25244

llvm-svn: 283777

clang-tools-extra/clang-tidy/google/NonConstReferences.cpp
clang-tools-extra/clang-tidy/google/NonConstReferences.h
clang-tools-extra/docs/clang-tidy/checks/google-runtime-references.rst
clang-tools-extra/test/clang-tidy/google-runtime-references.cpp

index 5667bd1..d1bc153 100644 (file)
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "NonConstReferences.h"
+#include "../utils/OptionsUtils.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
@@ -19,7 +20,21 @@ namespace tidy {
 namespace google {
 namespace runtime {
 
+NonConstReferences::NonConstReferences(StringRef Name,
+                                       ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      WhiteListTypes(
+          utils::options::parseStringList(Options.get("WhiteListTypes", ""))) {}
+
+void NonConstReferences::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+   Options.store(Opts, "WhiteListTypes",
+                 utils::options::serializeStringList(WhiteListTypes));
+}
+
 void NonConstReferences::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
   Finder->addMatcher(
       parmVarDecl(
           unless(isInstantiated()),
@@ -52,6 +67,15 @@ void NonConstReferences::check(const MatchFinder::MatchResult &Result) {
   }
 
   auto ReferencedType = *Result.Nodes.getNodeAs<QualType>("referenced_type");
+
+  if (std::find_if(WhiteListTypes.begin(), WhiteListTypes.end(),
+                   [&](llvm::StringRef WhiteListType) {
+                     return ReferencedType.getCanonicalType().getAsString(
+                                Result.Context->getPrintingPolicy()) ==
+                            WhiteListType;
+                   }) != WhiteListTypes.end())
+    return;
+
   // Don't warn on function references, they shouldn't be constant.
   if (ReferencedType->isFunctionProtoType())
     return;
index 3adb1f9..a665813 100644 (file)
@@ -22,10 +22,13 @@ namespace runtime {
 /// https://google.github.io/styleguide/cppguide.html#Reference_Arguments
 class NonConstReferences : public ClangTidyCheck {
 public:
-  NonConstReferences(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
+  NonConstReferences(StringRef Name, ClangTidyContext *Context);
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+
+private:
+  const std::vector<std::string> WhiteListTypes;
 };
 
 } // namespace runtime
index e6e5700..d546aaf 100644 (file)
@@ -7,3 +7,11 @@ Checks the usage of non-constant references in function parameters.
 
 The corresponding style guide rule:
 https://google.github.io/styleguide/cppguide.html#Reference_Arguments
+
+
+Options
+-------
+
+.. option:: WhiteListTypes
+
+   A semicolon-separated list of names of whitelist types. Defualt is empty.
index c96f28f..b9f84b6 100644 (file)
@@ -1,4 +1,8 @@
-// RUN: %check_clang_tidy %s google-runtime-references %t
+// RUN: %check_clang_tidy %s google-runtime-references %t -- \
+// RUN:   -extra-arg="-std=c++11" \
+// RUN:   -config="{CheckOptions: \
+// RUN:             [{key: google-runtime-references.WhiteListTypes, \
+// RUN:               value: 'whitelist::A; whitelist::B'}]}" --
 
 int a;
 int &b = a;
@@ -137,3 +141,12 @@ A& operator>>=(A& a, const A& b) { return a; }
 A& operator|=(A& a, const A& b) { return a; }
 A& operator^=(A& a, const A& b) { return a; }
 A& operator&=(A& a, const A& b) { return a; }
+
+namespace whitelist {
+class A {};
+class B {};
+void f7(A &);
+void f8(B &);
+}
+void f9(whitelist::A &);
+void f10(whitelist::B &);