Force the MachO generated for Darwin to have VERSION_MIN load command
[oota-llvm.git] / tools / llvm-cov / CodeCoverage.cpp
index 515d2bdc8e69434d74aff878ff50a15ef62b33c5..8dc4d665f23ca62784c959895e7c3f93cbc63d94 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "RenderingSupport.h"
-#include "CoverageViewOptions.h"
 #include "CoverageFilters.h"
-#include "SourceCoverageView.h"
-#include "CoverageSummary.h"
 #include "CoverageReport.h"
-#include "llvm/ADT/StringRef.h"
+#include "CoverageViewOptions.h"
+#include "SourceCoverageView.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ProfileData/InstrProfReader.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/ProfileData/CoverageMapping.h"
-#include "llvm/ProfileData/CoverageMappingReader.h"
+#include "llvm/ProfileData/InstrProfReader.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
-#include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/Signals.h"
 #include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
 #include <functional>
 #include <system_error>
 
@@ -89,6 +89,7 @@ public:
       LoadedSourceFiles;
   bool CompareFilenamesOnly;
   StringMap<std::string> RemappedFilenames;
+  std::string CoverageArch;
 };
 }
 
@@ -115,8 +116,7 @@ CodeCoverageTool::getSourceFile(StringRef SourceFile) {
     error(EC.message(), SourceFile);
     return EC;
   }
-  LoadedSourceFiles.push_back(
-      std::make_pair(SourceFile, std::move(Buffer.get())));
+  LoadedSourceFiles.emplace_back(SourceFile, std::move(Buffer.get()));
   return *LoadedSourceFiles.back().second;
 }
 
@@ -194,8 +194,22 @@ CodeCoverageTool::createSourceFileView(StringRef SourceFile,
   return View;
 }
 
+static bool modifiedTimeGT(StringRef LHS, StringRef RHS) {
+  sys::fs::file_status Status;
+  if (sys::fs::status(LHS, Status))
+    return false;
+  auto LHSTime = Status.getLastModificationTime();
+  if (sys::fs::status(RHS, Status))
+    return false;
+  auto RHSTime = Status.getLastModificationTime();
+  return LHSTime > RHSTime;
+}
+
 std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
-  auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename);
+  if (modifiedTimeGT(ObjectFilename, PGOFilename))
+    errs() << "warning: profile data may be out of date - object is newer\n";
+  auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename,
+                                             CoverageArch);
   if (std::error_code EC = CoverageOrErr.getError()) {
     colored_ostream(errs(), raw_ostream::RED)
         << "error: Failed to load coverage: " << EC.message();
@@ -244,6 +258,9 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
       cl::desc(
           "File with the profile data obtained after an instrumented run"));
 
+  cl::opt<std::string> Arch(
+      "arch", cl::desc("architecture of the coverage mapping binary"));
+
   cl::opt<bool> DebugDump("dump", cl::Optional,
                           cl::desc("Show internal debug dump"));
 
@@ -289,11 +306,19 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
                "greater than the given threshold"),
       cl::cat(FilteringCategory));
 
+  cl::opt<cl::boolOrDefault> UseColor(
+      "use-color", cl::desc("Emit colored output (default=autodetect)"),
+      cl::init(cl::BOU_UNSET));
+
   auto commandLineParser = [&, this](int argc, const char **argv) -> int {
     cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
     ViewOpts.Debug = DebugDump;
     CompareFilenamesOnly = FilenameEquivalence;
 
+    ViewOpts.Colors = UseColor == cl::BOU_UNSET
+                          ? sys::Process::StandardOutHasColors()
+                          : UseColor == cl::BOU_TRUE;
+
     // Create the function filters
     if (!NameFilters.empty() || !NameRegexFilters.empty()) {
       auto NameFilterer = new CoverageFilters;
@@ -324,12 +349,20 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
       Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer));
     }
 
+    if (!Arch.empty() &&
+        Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) {
+      errs() << "error: Unknown architecture: " << Arch << "\n";
+      return 1;
+    }
+    CoverageArch = Arch;
+
     for (const auto &File : InputSourceFiles) {
       SmallString<128> Path(File);
-      if (std::error_code EC = sys::fs::make_absolute(Path)) {
-        errs() << "error: " << File << ": " << EC.message();
-        return 1;
-      }
+      if (!CompareFilenamesOnly)
+        if (std::error_code EC = sys::fs::make_absolute(Path)) {
+          errs() << "error: " << File << ": " << EC.message();
+          return 1;
+        }
       SourceFiles.push_back(Path.str());
     }
     return 0;
@@ -373,15 +406,10 @@ int CodeCoverageTool::show(int argc, const char **argv,
                                    cl::desc("Show function instantiations"),
                                    cl::cat(ViewCategory));
 
-  cl::opt<bool> NoColors("no-colors", cl::Optional,
-                         cl::desc("Don't show text colors"), cl::init(false),
-                         cl::cat(ViewCategory));
-
   auto Err = commandLineParser(argc, argv);
   if (Err)
     return Err;
 
-  ViewOpts.Colors = !NoColors;
   ViewOpts.ShowLineNumbers = true;
   ViewOpts.ShowLineStats = ShowLineExecutionCounts.getNumOccurrences() != 0 ||
                            !ShowRegions || ShowBestLineRegionsCounts;
@@ -447,28 +475,19 @@ int CodeCoverageTool::show(int argc, const char **argv,
 
 int CodeCoverageTool::report(int argc, const char **argv,
                              CommandLineParserType commandLineParser) {
-  cl::opt<bool> NoColors("no-colors", cl::Optional,
-                         cl::desc("Don't show text colors"), cl::init(false));
-
   auto Err = commandLineParser(argc, argv);
   if (Err)
     return Err;
 
-  ViewOpts.Colors = !NoColors;
-
   auto Coverage = load();
   if (!Coverage)
     return 1;
 
-  CoverageSummary Summarizer;
-  Summarizer.createSummaries(*Coverage);
-  CoverageReport Report(ViewOpts, Summarizer);
-  if (SourceFiles.empty() && Filters.empty()) {
+  CoverageReport Report(ViewOpts, std::move(Coverage));
+  if (SourceFiles.empty())
     Report.renderFileReports(llvm::outs());
-    return 0;
-  }
-
-  Report.renderFunctionReports(llvm::outs());
+  else
+    Report.renderFunctionReports(SourceFiles, llvm::outs());
   return 0;
 }