[llvm-cov] Read in function names for filtering from a text file.

Summary: Add a -name-whitelist option, which behaves in the same way as -name, but it reads in multiple function names from the given input file(s).

Reviewers: vsk

Reviewed By: vsk

Subscribers: llvm-commits

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

llvm-svn: 312227
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index e5878df..f75fcb8 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -150,6 +150,9 @@
   std::mutex LoadedSourceFilesLock;
   std::vector<std::pair<std::string, std::unique_ptr<MemoryBuffer>>>
       LoadedSourceFiles;
+
+  /// Whitelist from -name-whitelist to be used for filtering.
+  std::unique_ptr<SpecialCaseList> NameWhitelist;
 };
 }
 
@@ -561,6 +564,12 @@
       cl::desc("Show code coverage only for functions with the given name"),
       cl::ZeroOrMore, cl::cat(FilteringCategory));
 
+  cl::list<std::string> NameFilterFiles(
+      "name-whitelist", cl::Optional,
+      cl::desc("Show code coverage only for functions listed in the given "
+               "file"),
+      cl::ZeroOrMore, cl::cat(FilteringCategory));
+
   cl::list<std::string> NameRegexFilters(
       "name-regex", cl::Optional,
       cl::desc("Show code coverage only for functions that match the given "
@@ -643,11 +652,23 @@
       ViewOpts.DemanglerOpts.swap(DemanglerOpts);
     }
 
+    // Read in -name-whitelist files.
+    if (!NameFilterFiles.empty()) {
+      std::string SpecialCaseListErr;
+      NameWhitelist =
+          SpecialCaseList::create(NameFilterFiles, SpecialCaseListErr);
+      if (!NameWhitelist)
+        error(SpecialCaseListErr);
+    }
+
     // Create the function filters
-    if (!NameFilters.empty() || !NameRegexFilters.empty()) {
+    if (!NameFilters.empty() || NameWhitelist || !NameRegexFilters.empty()) {
       auto NameFilterer = llvm::make_unique<CoverageFilters>();
       for (const auto &Name : NameFilters)
         NameFilterer->push_back(llvm::make_unique<NameCoverageFilter>(Name));
+      if (NameWhitelist)
+        NameFilterer->push_back(
+            llvm::make_unique<NameWhitelistCoverageFilter>(*NameWhitelist));
       for (const auto &Regex : NameRegexFilters)
         NameFilterer->push_back(
             llvm::make_unique<NameRegexCoverageFilter>(Regex));