[clang-tools-extra] r334101 - [clang-tidy] Store checks profiling info as JSON files

Roman Lebedev via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 6 08:07:51 PDT 2018


Author: lebedevri
Date: Wed Jun  6 08:07:51 2018
New Revision: 334101

URL: http://llvm.org/viewvc/llvm-project?rev=334101&view=rev
Log:
[clang-tidy] Store checks profiling info as JSON files

Summary:
Continuation of D46504.

Example output:
```
  $ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp
  $ # Note that there won't be timings table printed to the console.
  $ cat *.json
  {
  "file": "/path/to/source.cpp",
  "timestamp": "2018-05-16 16:13:18.717446360",
  "profile": {
    "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00,
    "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01,
    "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01
  }
  }
```

There are two arguments that control profile storage:

* `-store-check-profile=<prefix>`

  By default reports are printed in tabulated format to stderr. When this option
  is passed, these per-TU profiles are instead stored as JSON.
  If the prefix is not an absolute path, it is considered to be relative to the
  directory from where you have run :program:`clang-tidy`. All `.` and `..`
  patterns in the path are collapsed, and symlinks are resolved.

  Example:
  Let's suppose you have a source file named `example.cpp`, located in
  `/source` directory.

  * If you specify `-store-check-profile=/tmp`, then the profile will be saved
    to `/tmp/<timestamp>-example.cpp.json`

  * If you run :program:`clang-tidy` from within `/foo` directory, and specify
    `-store-check-profile=.`, then the profile will still be saved to
    `/foo/<timestamp>-example.cpp.json`

Reviewers: alexfh, sbenza, george.karpenkov, NoQ, aaron.ballman

Reviewed By: alexfh, george.karpenkov, aaron.ballman

Subscribers: Quuxplusone, JonasToth, aaron.ballman, llvm-commits, rja, Eugene.Zelenko, xazax.hun, mgrang, cfe-commits

Tags: #clang-tools-extra

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

Added:
    clang-tools-extra/trunk/test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
    clang-tools-extra/trunk/clang-tidy/ClangTidy.h
    clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
    clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
    clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.cpp
    clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.h
    clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
    clang-tools-extra/trunk/docs/ReleaseNotes.rst
    clang-tools-extra/trunk/docs/clang-tidy/index.rst
    clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp
    clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp Wed Jun  6 08:07:51 2018
@@ -363,7 +363,8 @@ ClangTidyASTConsumerFactory::CreateASTCo
 
   std::unique_ptr<ClangTidyProfiling> Profiling;
   if (Context.getEnableProfiling()) {
-    Profiling = llvm::make_unique<ClangTidyProfiling>();
+    Profiling = llvm::make_unique<ClangTidyProfiling>(
+        Context.getProfileStorageParams());
     FinderOptions.CheckProfiling.emplace(Profiling->Records);
   }
 
@@ -492,7 +493,7 @@ void runClangTidy(clang::tidy::ClangTidy
                   const CompilationDatabase &Compilations,
                   ArrayRef<std::string> InputFiles,
                   llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,
-                  bool EnableCheckProfile) {
+                  bool EnableCheckProfile, llvm::StringRef StoreCheckProfile) {
   ClangTool Tool(Compilations, InputFiles,
                  std::make_shared<PCHContainerOperations>(), BaseFS);
 
@@ -533,6 +534,7 @@ void runClangTidy(clang::tidy::ClangTidy
   Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter);
   Tool.appendArgumentsAdjuster(PluginArgumentsRemover);
   Context.setEnableProfiling(EnableCheckProfile);
+  Context.setProfileStoragePrefix(StoreCheckProfile);
 
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
 

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.h?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.h Wed Jun  6 08:07:51 2018
@@ -227,11 +227,15 @@ getCheckOptions(const ClangTidyOptions &
 ///
 /// \param EnableCheckProfile If provided, it enables check profile collection
 /// in MatchFinder, and will contain the result of the profile.
+/// \param StoreCheckProfile If provided, and EnableCheckProfile is true,
+/// the profile will not be output to stderr, but will instead be stored
+/// as a JSON file in the specified directory.
 void runClangTidy(clang::tidy::ClangTidyContext &Context,
                   const tooling::CompilationDatabase &Compilations,
                   ArrayRef<std::string> InputFiles,
                   llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,
-                  bool EnableCheckProfile = false);
+                  bool EnableCheckProfile = false,
+                  llvm::StringRef StoreCheckProfile = StringRef());
 
 // FIXME: This interface will need to be significantly extended to be useful.
 // FIXME: Implement confidence levels for displaying/fixing errors.

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Wed Jun  6 08:07:51 2018
@@ -237,6 +237,18 @@ ClangTidyOptions ClangTidyContext::getOp
 
 void ClangTidyContext::setEnableProfiling(bool P) { Profile = P; }
 
+void ClangTidyContext::setProfileStoragePrefix(StringRef Prefix) {
+  ProfilePrefix = Prefix;
+}
+
+llvm::Optional<ClangTidyProfiling::StorageParams>
+ClangTidyContext::getProfileStorageParams() const {
+  if (ProfilePrefix.empty())
+    return llvm::None;
+
+  return ClangTidyProfiling::StorageParams(ProfilePrefix, CurrentFile);
+}
+
 bool ClangTidyContext::isCheckEnabled(StringRef CheckName) const {
   assert(CheckFilter != nullptr);
   return CheckFilter->contains(CheckName);

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Wed Jun  6 08:07:51 2018
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
 
 #include "ClangTidyOptions.h"
+#include "ClangTidyProfiling.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Tooling/Core/Diagnostic.h"
@@ -169,6 +170,11 @@ public:
   void setEnableProfiling(bool Profile);
   bool getEnableProfiling() const { return Profile; }
 
+  /// \brief Control storage of profile date.
+  void setProfileStoragePrefix(StringRef ProfilePrefix);
+  llvm::Optional<ClangTidyProfiling::StorageParams>
+  getProfileStorageParams() const;
+
   /// \brief Should be called when starting to process new translation unit.
   void setCurrentBuildDirectory(StringRef BuildDirectory) {
     CurrentBuildDirectory = BuildDirectory;
@@ -216,6 +222,7 @@ private:
   llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
 
   bool Profile;
+  std::string ProfilePrefix;
 
   bool AllowEnablingAnalyzerAlphaCheckers;
 };

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.cpp?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.cpp Wed Jun  6 08:07:51 2018
@@ -9,56 +9,84 @@
 
 #include "ClangTidyProfiling.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include <system_error>
+#include <utility>
 
 #define DEBUG_TYPE "clang-tidy-profiling"
 
 namespace clang {
 namespace tidy {
 
-void ClangTidyProfiling::preprocess() {
-  // Convert from a insertion-friendly map to sort-friendly vector.
-  Timers.clear();
-  Timers.reserve(Records.size());
-  for (const auto &P : Records) {
-    Timers.emplace_back(P.getValue(), P.getKey());
-    Total += P.getValue();
-  }
-  assert(Timers.size() == Records.size() && "Size mismatch after processing");
+ClangTidyProfiling::StorageParams::StorageParams(llvm::StringRef ProfilePrefix,
+                                                 llvm::StringRef SourceFile)
+    : Timestamp(std::chrono::system_clock::now()), SourceFilename(SourceFile) {
+  llvm::SmallString<32> TimestampStr;
+  llvm::raw_svector_ostream OS(TimestampStr);
+  llvm::format_provider<decltype(Timestamp)>::format(Timestamp, OS,
+                                                     "%Y%m%d%H%M%S%N");
+
+  llvm::SmallString<256> FinalPrefix(ProfilePrefix);
+  llvm::sys::path::append(FinalPrefix, TimestampStr);
+
+  // So the full output name is: /ProfilePrefix/timestamp-inputfilename.json
+  StoreFilename = llvm::Twine(FinalPrefix + "-" +
+                              llvm::sys::path::filename(SourceFile) + ".json")
+                      .str();
+}
+
+void ClangTidyProfiling::printUserFriendlyTable(llvm::raw_ostream &OS) {
+  TG->print(OS);
+  OS.flush();
+}
 
-  // We want the measurements to be sorted by decreasing time spent.
-  llvm::sort(Timers.begin(), Timers.end());
+void ClangTidyProfiling::printAsJSON(llvm::raw_ostream &OS) {
+  OS << "{\n";
+  OS << "\"file\": \"" << Storage->SourceFilename << "\",\n";
+  OS << "\"timestamp\": \"" << Storage->Timestamp << "\",\n";
+  OS << "\"profile\": {\n";
+  TG->printJSONValues(OS, "");
+  OS << "\n}\n";
+  OS << "}\n";
+  OS.flush();
 }
 
-void ClangTidyProfiling::printProfileData(llvm::raw_ostream &OS) const {
-  std::string Line = "===" + std::string(73, '-') + "===\n";
-  OS << Line;
-
-  if (Total.getUserTime())
-    OS << "   ---User Time---";
-  if (Total.getSystemTime())
-    OS << "   --System Time--";
-  if (Total.getProcessTime())
-    OS << "   --User+System--";
-  OS << "   ---Wall Time---";
-  if (Total.getMemUsed())
-    OS << "  ---Mem---";
-  OS << "  --- Name ---\n";
-
-  // Loop through all of the timing data, printing it out.
-  for (auto I = Timers.rbegin(), E = Timers.rend(); I != E; ++I) {
-    I->first.print(Total, OS);
-    OS << I->second << '\n';
+void ClangTidyProfiling::storeProfileData() {
+  assert(Storage.hasValue() && "We should have a filename.");
+
+  llvm::SmallString<256> OutputDirectory(Storage->StoreFilename);
+  llvm::sys::path::remove_filename(OutputDirectory);
+  if (std::error_code EC = llvm::sys::fs::create_directories(OutputDirectory)) {
+    llvm::errs() << "Unable to create output directory '" << OutputDirectory
+                 << "': " << EC.message() << "\n";
+    return;
   }
 
-  Total.print(Total, OS);
-  OS << "Total\n";
-  OS << Line << "\n";
-  OS.flush();
+  std::error_code EC;
+  llvm::raw_fd_ostream OS(Storage->StoreFilename, EC, llvm::sys::fs::F_None);
+  if (EC) {
+    llvm::errs() << "Error opening output file '" << Storage->StoreFilename
+                 << "': " << EC.message() << "\n";
+    return;
+  }
+
+  printAsJSON(OS);
 }
 
+ClangTidyProfiling::ClangTidyProfiling(llvm::Optional<StorageParams> Storage)
+    : Storage(std::move(Storage)) {}
+
 ClangTidyProfiling::~ClangTidyProfiling() {
-  preprocess();
-  printProfileData(llvm::errs());
+  TG.emplace("clang-tidy", "clang-tidy checks profiling", Records);
+
+  if (!Storage.hasValue())
+    printUserFriendlyTable(llvm::errs());
+  else
+    storeProfileData();
 }
 
 } // namespace tidy

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.h?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyProfiling.h Wed Jun  6 08:07:51 2018
@@ -10,10 +10,12 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYPROFILING_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYPROFILING_H
 
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Chrono.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -21,17 +23,34 @@ namespace clang {
 namespace tidy {
 
 class ClangTidyProfiling {
-  // Time is first to allow for sorting by it.
-  std::vector<std::pair<llvm::TimeRecord, llvm::StringRef>> Timers;
-  llvm::TimeRecord Total;
+public:
+  struct StorageParams {
+    llvm::sys::TimePoint<> Timestamp;
+    std::string SourceFilename;
+    std::string StoreFilename;
+
+    StorageParams() = default;
+
+    StorageParams(llvm::StringRef ProfilePrefix, llvm::StringRef SourceFile);
+  };
+
+private:
+  llvm::Optional<llvm::TimerGroup> TG;
 
-  void preprocess();
+  llvm::Optional<StorageParams> Storage;
 
-  void printProfileData(llvm::raw_ostream &OS) const;
+  void printUserFriendlyTable(llvm::raw_ostream &OS);
+  void printAsJSON(llvm::raw_ostream &OS);
+
+  void storeProfileData();
 
 public:
   llvm::StringMap<llvm::TimeRecord> Records;
 
+  ClangTidyProfiling() = default;
+
+  ClangTidyProfiling(llvm::Optional<StorageParams> Storage);
+
   ~ClangTidyProfiling();
 };
 

Modified: clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp Wed Jun  6 08:07:51 2018
@@ -181,6 +181,15 @@ report to stderr.
                                         cl::init(false),
                                         cl::cat(ClangTidyCategory));
 
+static cl::opt<std::string> StoreCheckProfile("store-check-profile",
+                                              cl::desc(R"(
+By default reports are printed in tabulated
+format to stderr. When this option is passed,
+these per-TU profiles are instead stored as JSON.
+)"),
+                                              cl::value_desc("prefix"),
+                                              cl::cat(ClangTidyCategory));
+
 /// This option allows enabling the experimental alpha checkers from the static
 /// analyzer. This option is set to false and not visible in help, because it is
 /// highly not recommended for users.
@@ -331,17 +340,27 @@ static int clangTidyMain(int argc, const
   if (!OptionsProvider)
     return 1;
 
+  auto MakeAbsolute = [](const std::string &Input) -> SmallString<256> {
+    if (Input.empty())
+      return {};
+    SmallString<256> AbsolutePath(Input);
+    if (std::error_code EC = llvm::sys::fs::make_absolute(AbsolutePath)) {
+      llvm::errs() << "Can't make absolute path from " << Input << ": "
+                   << EC.message() << "\n";
+    }
+    return AbsolutePath;
+  };
+
+  SmallString<256> ProfilePrefix = MakeAbsolute(StoreCheckProfile);
+
   StringRef FileName("dummy");
   auto PathList = OptionsParser.getSourcePathList();
   if (!PathList.empty()) {
     FileName = PathList.front();
   }
 
-  SmallString<256> FilePath(FileName);
-  if (std::error_code EC = llvm::sys::fs::make_absolute(FilePath)) {
-    llvm::errs() << "Can't make absolute path from " << FileName << ": "
-                 << EC.message() << "\n";
-  }
+  SmallString<256> FilePath = MakeAbsolute(FileName);
+
   ClangTidyOptions EffectiveOptions = OptionsProvider->getOptions(FilePath);
   std::vector<std::string> EnabledChecks =
       getCheckNames(EffectiveOptions, AllowEnablingAnalyzerAlphaCheckers);
@@ -403,7 +422,7 @@ static int clangTidyMain(int argc, const
   ClangTidyContext Context(std::move(OwningOptionsProvider),
                            AllowEnablingAnalyzerAlphaCheckers);
   runClangTidy(Context, OptionsParser.getCompilations(), PathList, BaseFS,
-               EnableCheckProfile);
+               EnableCheckProfile, ProfilePrefix);
   ArrayRef<ClangTidyError> Errors = Context.getErrors();
   bool FoundErrors = llvm::find_if(Errors, [](const ClangTidyError &E) {
                        return E.DiagLevel == ClangTidyError::Error;

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Wed Jun  6 08:07:51 2018
@@ -57,6 +57,9 @@ The improvements are...
 Improvements to clang-tidy
 --------------------------
 
+- The checks profiling info can now be stored as JSON files for futher
+  post-processing and analysis.
+
 - New module `abseil` for checks related to the `Abseil <https://abseil.io>`_
   library.
 

Modified: clang-tools-extra/trunk/docs/clang-tidy/index.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/index.rst?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/index.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/index.rst Wed Jun  6 08:07:51 2018
@@ -99,114 +99,121 @@ An overview of all the command-line opti
 
 .. code-block:: console
 
-  $ clang-tidy -help
+  $ clang-tidy --help
   USAGE: clang-tidy [options] <source0> [... <sourceN>]
 
   OPTIONS:
 
   Generic Options:
 
-    -help                        - Display available options (-help-hidden for more)
-    -help-list                   - Display list of available options (-help-list-hidden for more)
-    -version                     - Display the version of this program
+    -help                         - Display available options (-help-hidden for more)
+    -help-list                    - Display list of available options (-help-list-hidden for more)
+    -version                      - Display the version of this program
 
   clang-tidy options:
 
-    -checks=<string>             -
-                                   Comma-separated list of globs with optional '-'
-                                   prefix. Globs are processed in order of
-                                   appearance in the list. Globs without '-'
-                                   prefix add checks with matching names to the
-                                   set, globs with the '-' prefix remove checks
-                                   with matching names from the set of enabled
-                                   checks. This option's value is appended to the
-                                   value of the 'Checks' option in .clang-tidy
-                                   file, if any.
-    -config=<string>             -
-                                   Specifies a configuration in YAML/JSON format:
-                                     -config="{Checks: '*',
-                                               CheckOptions: [{key: x,
-                                                               value: y}]}"
-                                   When the value is empty, clang-tidy will
-                                   attempt to find a file named .clang-tidy for
-                                   each source file in its parent directories.
-    -dump-config                 -
-                                   Dumps configuration in the YAML format to
-                                   stdout. This option can be used along with a
-                                   file name (and '--' if the file is outside of a
-                                   project with configured compilation database).
-                                   The configuration used for this file will be
-                                   printed.
-                                   Use along with -checks=* to include
-                                   configuration of all checks.
-    -enable-check-profile        -
-                                   Enable per-check timing profiles, and print a
-                                   report to stderr.
-    -explain-config              -
-                                   For each enabled check explains, where it is
-                                   enabled, i.e. in clang-tidy binary, command
-                                   line or a specific configuration file.
-    -export-fixes=<filename>     -
-                                   YAML file to store suggested fixes in. The
-                                   stored fixes can be applied to the input source
-                                   code with clang-apply-replacements.
-    -extra-arg=<string>          - Additional argument to append to the compiler command line
-    -extra-arg-before=<string>   - Additional argument to prepend to the compiler command line
-    -fix                         -
-                                   Apply suggested fixes. Without -fix-errors
-                                   clang-tidy will bail out if any compilation
-                                   errors were found.
-    -fix-errors                  -
-                                   Apply suggested fixes even if compilation
-                                   errors were found. If compiler errors have
-                                   attached fix-its, clang-tidy will apply them as
-                                   well.
-    -format-style=<string>       -
-                                   Style for formatting code around applied fixes:
-                                     - 'none' (default) turns off formatting
-                                     - 'file' (literally 'file', not a placeholder)
-                                       uses .clang-format file in the closest parent
-                                       directory
-                                     - '{ <json> }' specifies options inline, e.g.
-                                       -format-style='{BasedOnStyle: llvm, IndentWidth: 8}'
-                                     - 'llvm', 'google', 'webkit', 'mozilla'
-                                   See clang-format documentation for the up-to-date
-                                   information about formatting styles and options.
-                                   This option overrides the 'FormatStyle` option in
-                                   .clang-tidy file, if any.
-    -header-filter=<string>      -
-                                   Regular expression matching the names of the
-                                   headers to output diagnostics from. Diagnostics
-                                   from the main file of each translation unit are
-                                   always displayed.
-                                   Can be used together with -line-filter.
-                                   This option overrides the 'HeaderFilter' option
-                                   in .clang-tidy file, if any.
-    -line-filter=<string>        -
-                                   List of files with line ranges to filter the
-                                   warnings. Can be used together with
-                                   -header-filter. The format of the list is a
-                                   JSON array of objects:
-                                     [
-                                       {"name":"file1.cpp","lines":[[1,3],[5,7]]},
-                                       {"name":"file2.h"}
-                                     ]
-    -list-checks                 -
-                                   List all enabled checks and exit. Use with
-                                   -checks=* to list all available checks.
-    -p=<string>                  - Build path
-    -quiet                       -
-                                   Run clang-tidy in quiet mode. This suppresses
-                                   printing statistics about ignored warnings and
-                                   warnings treated as errors if the respective
-                                   options are specified.
-    -system-headers              - Display the errors from system headers.
-    -warnings-as-errors=<string> -
-                                   Upgrades warnings to errors. Same format as
-                                   '-checks'.
-                                   This option's value is appended to the value of
-                                   the 'WarningsAsErrors' option in .clang-tidy
-                                   file, if any.
+    -checks=<string>              -
+                                    Comma-separated list of globs with optional '-'
+                                    prefix. Globs are processed in order of
+                                    appearance in the list. Globs without '-'
+                                    prefix add checks with matching names to the
+                                    set, globs with the '-' prefix remove checks
+                                    with matching names from the set of enabled
+                                    checks. This option's value is appended to the
+                                    value of the 'Checks' option in .clang-tidy
+                                    file, if any.
+    -config=<string>              -
+                                    Specifies a configuration in YAML/JSON format:
+                                      -config="{Checks: '*',
+                                                CheckOptions: [{key: x,
+                                                                value: y}]}"
+                                    When the value is empty, clang-tidy will
+                                    attempt to find a file named .clang-tidy for
+                                    each source file in its parent directories.
+    -dump-config                  -
+                                    Dumps configuration in the YAML format to
+                                    stdout. This option can be used along with a
+                                    file name (and '--' if the file is outside of a
+                                    project with configured compilation database).
+                                    The configuration used for this file will be
+                                    printed.
+                                    Use along with -checks=* to include
+                                    configuration of all checks.
+    -enable-check-profile         -
+                                    Enable per-check timing profiles, and print a
+                                    report to stderr.
+    -explain-config               -
+                                    For each enabled check explains, where it is
+                                    enabled, i.e. in clang-tidy binary, command
+                                    line or a specific configuration file.
+    -export-fixes=<filename>      -
+                                    YAML file to store suggested fixes in. The
+                                    stored fixes can be applied to the input source
+                                    code with clang-apply-replacements.
+    -extra-arg=<string>           - Additional argument to append to the compiler command line
+    -extra-arg-before=<string>    - Additional argument to prepend to the compiler command line
+    -fix                          -
+                                    Apply suggested fixes. Without -fix-errors
+                                    clang-tidy will bail out if any compilation
+                                    errors were found.
+    -fix-errors                   -
+                                    Apply suggested fixes even if compilation
+                                    errors were found. If compiler errors have
+                                    attached fix-its, clang-tidy will apply them as
+                                    well.
+    -format-style=<string>        -
+                                    Style for formatting code around applied fixes:
+                                      - 'none' (default) turns off formatting
+                                      - 'file' (literally 'file', not a placeholder)
+                                        uses .clang-format file in the closest parent
+                                        directory
+                                      - '{ <json> }' specifies options inline, e.g.
+                                        -format-style='{BasedOnStyle: llvm, IndentWidth: 8}'
+                                      - 'llvm', 'google', 'webkit', 'mozilla'
+                                    See clang-format documentation for the up-to-date
+                                    information about formatting styles and options.
+                                    This option overrides the 'FormatStyle` option in
+                                    .clang-tidy file, if any.
+    -header-filter=<string>       -
+                                    Regular expression matching the names of the
+                                    headers to output diagnostics from. Diagnostics
+                                    from the main file of each translation unit are
+                                    always displayed.
+                                    Can be used together with -line-filter.
+                                    This option overrides the 'HeaderFilter' option
+                                    in .clang-tidy file, if any.
+    -line-filter=<string>         -
+                                    List of files with line ranges to filter the
+                                    warnings. Can be used together with
+                                    -header-filter. The format of the list is a
+                                    JSON array of objects:
+                                      [
+                                        {"name":"file1.cpp","lines":[[1,3],[5,7]]},
+                                        {"name":"file2.h"}
+                                      ]
+    -list-checks                  -
+                                    List all enabled checks and exit. Use with
+                                    -checks=* to list all available checks.
+    -p=<string>                   - Build path
+    -quiet                        -
+                                    Run clang-tidy in quiet mode. This suppresses
+                                    printing statistics about ignored warnings and
+                                    warnings treated as errors if the respective
+                                    options are specified.
+    -store-check-profile=<prefix> -
+                                    By default reports are printed in tabulated
+                                    format to stderr. When this option is passed,
+                                    these per-TU profiles are instead stored as JSON.
+    -system-headers               - Display the errors from system headers.
+    -vfsoverlay=<filename>        -
+                                    Overlay the virtual filesystem described by file
+                                    over the real file system.
+    -warnings-as-errors=<string>  -
+                                    Upgrades warnings to errors. Same format as
+                                    '-checks'.
+                                    This option's value is appended to the value of
+                                    the 'WarningsAsErrors' option in .clang-tidy
+                                    file, if any.
 
   -p <build-path> is used to read a compile command database.
 
@@ -739,3 +746,65 @@ The script provides multiple configurati
   all changes in a temporary directory and applies them. Passing ``-format``
   will run clang-format over changed lines.
 
+
+On checks profiling
+-------------------
+
+:program:`clang-tidy` can collect per-check profiling info, and output it
+for each processed source file (translation unit).
+
+To enable profiling info collection, use the ``-enable-check-profile`` argument.
+The timings will be output to ``stderr`` as a table. Example output:
+
+.. code-block:: console
+
+  $ clang-tidy -enable-check-profile -checks=-*,readability-function-size source.cpp
+  ===-------------------------------------------------------------------------===
+                            clang-tidy checks profiling
+  ===-------------------------------------------------------------------------===
+    Total Execution Time: 1.0282 seconds (1.0258 wall clock)
+
+     ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
+     0.9136 (100.0%)   0.1146 (100.0%)   1.0282 (100.0%)   1.0258 (100.0%)  readability-function-size
+     0.9136 (100.0%)   0.1146 (100.0%)   1.0282 (100.0%)   1.0258 (100.0%)  Total
+
+It can also store that data as JSON files for further processing. Example output:
+
+.. code-block:: console
+
+  $ clang-tidy -enable-check-profile -store-check-profile=.  -checks=-*,readability-function-size source.cpp
+  $ # Note that there won't be timings table printed to the console.
+  $ ls /tmp/out/
+  20180516161318717446360-source.cpp.json
+  $ cat 20180516161318717446360-source.cpp.json
+  {
+  "file": "/path/to/source.cpp",
+  "timestamp": "2018-05-16 16:13:18.717446360",
+  "profile": {
+    "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00,
+    "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01,
+    "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01
+  }
+  }
+
+There is only one argument that controls profile storage:
+
+* ``-store-check-profile=<prefix>``
+
+  By default reports are printed in tabulated format to stderr. When this option
+  is passed, these per-TU profiles are instead stored as JSON.
+  If the prefix is not an absolute path, it is considered to be relative to the
+  directory from where you have run :program:`clang-tidy`. All ``.`` and ``..``
+  patterns in the path are collapsed, and symlinks are resolved.
+
+  Example:
+  Let's suppose you have a source file named ``example.cpp``, located in the
+  ``/source`` directory. Only the input filename is used, not the full path
+  to the source file. Additionally, it is prefixed with the current timestamp.
+
+  * If you specify ``-store-check-profile=/tmp``, then the profile will be saved
+    to ``/tmp/<ISO8601-like timestamp>-example.cpp.json``
+
+  * If you run :program:`clang-tidy` from within ``/foo`` directory, and specify
+    ``-store-check-profile=.``, then the profile will still be saved to
+    ``/foo/<ISO8601-like timestamp>-example.cpp.json``

Modified: clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp Wed Jun  6 08:07:51 2018
@@ -1,16 +1,22 @@
 // RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' %s -- 2>&1 | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' %s
 
 // CHECK: ===-------------------------------------------------------------------------===
-// CHECK-NEXT: {{.*}}  --- Name ---
+// CHECK-NEXT:                          clang-tidy checks profiling
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
+// CHECK: {{.*}}  --- Name ---
 // CHECK-NEXT: {{.*}}  readability-function-size
 // CHECK-NEXT: {{.*}}  Total
-// CHECK-NEXT: ===-------------------------------------------------------------------------===
 
 // CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT:                          clang-tidy checks profiling
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
 // CHECK-NOT: {{.*}}  --- Name ---
 // CHECK-NOT: {{.*}}  readability-function-size
 // CHECK-NOT: {{.*}}  Total
-// CHECK-NOT: ===-------------------------------------------------------------------------===
 
 class A {
   A() {}

Modified: clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp?rev=334101&r1=334100&r2=334101&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp Wed Jun  6 08:07:51 2018
@@ -1,22 +1,31 @@
 // RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' %s %s -- 2>&1 | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' %s
 
 // CHECK: ===-------------------------------------------------------------------------===
-// CHECK-NEXT: {{.*}}  --- Name ---
+// CHECK-NEXT:                          clang-tidy checks profiling
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
+// CHECK: {{.*}}  --- Name ---
 // CHECK-NEXT: {{.*}}  readability-function-size
 // CHECK-NEXT: {{.*}}  Total
-// CHECK-NEXT: ===-------------------------------------------------------------------------===
 
 // CHECK: ===-------------------------------------------------------------------------===
-// CHECK-NEXT: {{.*}}  --- Name ---
+// CHECK-NEXT:                          clang-tidy checks profiling
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
+// CHECK: {{.*}}  --- Name ---
 // CHECK-NEXT: {{.*}}  readability-function-size
 // CHECK-NEXT: {{.*}}  Total
-// CHECK-NEXT: ===-------------------------------------------------------------------------===
 
 // CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT:                          clang-tidy checks profiling
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock)
+
 // CHECK-NOT: {{.*}}  --- Name ---
 // CHECK-NOT: {{.*}}  readability-function-size
 // CHECK-NOT: {{.*}}  Total
-// CHECK-NOT: ===-------------------------------------------------------------------------===
 
 class A {
   A() {}

Added: clang-tools-extra/trunk/test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp?rev=334101&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp Wed Jun  6 08:07:51 2018
@@ -0,0 +1,37 @@
+// RUN: rm -rf %T/out
+// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' -store-check-profile=%T/out %s -- 2>&1 | not FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-CONSOLE %s
+// RUN: cat %T/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-FILE %s
+// RUN: rm -rf %T/out
+// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' -store-check-profile=%T/out %s -- 2>&1
+// RUN: cat %T/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-FILE %s
+
+// CHECK-CONSOLE-NOT: ===-------------------------------------------------------------------------===
+// CHECK-CONSOLE-NOT: {{.*}}  --- Name ---
+// CHECK-CONSOLE-NOT: {{.*}}  readability-function-size
+// CHECK-CONSOLE-NOT: {{.*}}  Total
+// CHECK-CONSOLE-NOT: ===-------------------------------------------------------------------------===
+
+// CHECK-FILE: {
+// CHECK-FILE-NEXT:"file": "{{.*}}clang-tidy-store-check-profile-one-tu.cpp",
+// CHECK-FILE-NEXT:"timestamp": "{{[0-9]+}}-{{[0-9]+}}-{{[0-9]+}} {{[0-9]+}}:{{[0-9]+}}:{{[0-9]+}}.{{[0-9]+}}",
+// CHECK-FILE-NEXT:"profile": {
+// CHECK-FILE-NEXT:	"time.clang-tidy.readability-function-size.wall": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}},
+// CHECK-FILE-NEXT:	"time.clang-tidy.readability-function-size.user": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}},
+// CHECK-FILE-NEXT:	"time.clang-tidy.readability-function-size.sys": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}}
+// CHECK-FILE-NEXT: }
+// CHECK-FILE-NEXT: }
+
+// CHECK-FILE-NOT: {
+// CHECK-FILE-NOT: "file": {{.*}}clang-tidy-store-check-profile-one-tu.cpp{{.*}},
+// CHECK-FILE-NOT: "timestamp": "{{[0-9]+}}-{{[0-9]+}}-{{[0-9]+}} {{[0-9]+}}:{{[0-9]+}}:{{[0-9]+}}.{{[0-9]+}}",
+// CHECK-FILE-NOT: "profile": {
+// CHECK-FILE-NOT:	"time.clang-tidy.readability-function-size.wall": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}},
+// CHECK-FILE-NOT:	"time.clang-tidy.readability-function-size.user": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}},
+// CHECK-FILE-NOT:	"time.clang-tidy.readability-function-size.sys": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}}
+// CHECK-FILE-NOT: }
+// CHECK-FILE-NOT: }
+
+class A {
+  A() {}
+  ~A() {}
+};




More information about the cfe-commits mailing list