Add flag --enable-check-profile to clang-tidy.
Summary:
Add flag --enable-check-profile to clang-tidy.
It turns on per-matcher profiles in MatchFinder and prints a report to
stderr at the end.
Reviewers: alexfh
Subscribers: curdeius, cfe-commits
Differential Revision: http://reviews.llvm.org/D5937
llvm-svn: 220491
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index 8f45eaa..72d841e 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -98,6 +98,11 @@
cl::desc("Dumps configuration in the YAML format to stdout."),
cl::init(false), cl::cat(ClangTidyCategory));
+static cl::opt<bool> EnableCheckProfile(
+ "enable-check-profile",
+ cl::desc("Enable per-check timing profiles, and print a report to stderr."),
+ cl::init(false), cl::cat(ClangTidyCategory));
+
static cl::opt<bool> AnalyzeTemporaryDtors(
"analyze-temporary-dtors",
cl::desc("Enable temporary destructor-aware analysis in\n"
@@ -143,6 +148,45 @@
}
}
+static void printProfileData(const ProfileData &Profile,
+ llvm::raw_ostream &OS) {
+ // Time is first to allow for sorting by it.
+ std::vector<std::pair<llvm::TimeRecord, StringRef>> Timers;
+ TimeRecord Total;
+
+ for (const auto& P : Profile.Records) {
+ Timers.emplace_back(P.getValue(), P.getKey());
+ Total += P.getValue();
+ }
+
+ std::sort(Timers.begin(), Timers.end());
+
+ 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';
+ }
+
+ Total.print(Total, OS);
+ OS << "Total\n";
+ OS << Line << "\n";
+ OS.flush();
+}
+
std::unique_ptr<ClangTidyOptionsProvider> createOptionsProvider() {
ClangTidyGlobalOptions GlobalOptions;
if (std::error_code Err = parseLineFilter(LineFilter, GlobalOptions)) {
@@ -220,10 +264,13 @@
return 1;
}
+ ProfileData Profile;
+
std::vector<ClangTidyError> Errors;
ClangTidyStats Stats =
runClangTidy(std::move(OptionsProvider), OptionsParser.getCompilations(),
- OptionsParser.getSourcePathList(), &Errors);
+ OptionsParser.getSourcePathList(), &Errors,
+ EnableCheckProfile ? &Profile : nullptr);
handleErrors(Errors, Fix);
if (!ExportFixes.empty() && !Errors.empty()) {
@@ -237,6 +284,9 @@
}
printStats(Stats);
+ if (EnableCheckProfile)
+ printProfileData(Profile, llvm::errs());
+
return 0;
}