Author: sbenza Date: Thu Oct 23 12:23:20 2014 New Revision: 220491 URL: http://llvm.org/viewvc/llvm-project?rev=220491&view=rev Log: 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 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/tool/ClangTidyMain.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=220491&r1=220490&r2=220491&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp Thu Oct 23 12:23:20 2014 @@ -216,8 +216,13 @@ ClangTidyASTConsumerFactory::CreateASTCo std::vector<std::unique_ptr<ClangTidyCheck>> Checks; CheckFactories->createChecks(&Context, Checks); + ast_matchers::MatchFinder::MatchFinderOptions FinderOptions; + if (auto *P = Context.getCheckProfileData()) + FinderOptions.CheckProfiling.emplace(P->Records); + std::unique_ptr<ast_matchers::MatchFinder> Finder( - new ast_matchers::MatchFinder); + new ast_matchers::MatchFinder(std::move(FinderOptions))); + for (auto &Check : Checks) { Check->registerMatchers(&*Finder); Check->registerPPCallbacks(Compiler); @@ -356,9 +361,12 @@ ClangTidyStats runClangTidy(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider, const tooling::CompilationDatabase &Compilations, ArrayRef<std::string> InputFiles, - std::vector<ClangTidyError> *Errors) { + std::vector<ClangTidyError> *Errors, ProfileData *Profile) { ClangTool Tool(Compilations, InputFiles); clang::tidy::ClangTidyContext Context(std::move(OptionsProvider)); + if (Profile) + Context.setCheckProfileData(Profile); + ClangTidyDiagnosticConsumer DiagConsumer(Context); Tool.setDiagnosticConsumer(&DiagConsumer); 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=220491&r1=220490&r2=220491&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidy.h (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidy.h Thu Oct 23 12:23:20 2014 @@ -152,6 +152,7 @@ public: private: void run(const ast_matchers::MatchFinder::MatchResult &Result) override; + StringRef getID() const override { return CheckName; } std::string CheckName; ClangTidyContext *Context; @@ -196,11 +197,15 @@ std::vector<std::string> getCheckNames(c ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options); /// \brief Run a set of clang-tidy checks on a set of files. +/// +/// \param Profile if provided, it enables check profile collection in +/// MatchFinder, and will contain the result of the profile. ClangTidyStats runClangTidy(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider, const tooling::CompilationDatabase &Compilations, ArrayRef<std::string> InputFiles, - std::vector<ClangTidyError> *Errors); + std::vector<ClangTidyError> *Errors, + ProfileData *Profile = nullptr); // 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=220491&r1=220490&r2=220491&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Thu Oct 23 12:23:20 2014 @@ -162,7 +162,8 @@ bool GlobList::contains(StringRef S, boo ClangTidyContext::ClangTidyContext( std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider) - : DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)) { + : DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)), + Profile(nullptr) { // Before the first translation unit we can get errors related to command-line // parsing, use empty string for the file name in this case. setCurrentFile(""); @@ -221,6 +222,10 @@ const ClangTidyOptions &ClangTidyContext return CurrentOptions; } +void ClangTidyContext::setCheckProfileData(ProfileData *P) { + Profile = P; +} + GlobList &ClangTidyContext::getChecksFilter() { assert(CheckFilter != nullptr); return *CheckFilter; 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=220491&r1=220490&r2=220491&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Thu Oct 23 12:23:20 2014 @@ -15,7 +15,9 @@ #include "clang/Basic/SourceManager.h" #include "clang/Tooling/Refactoring.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/Regex.h" +#include "llvm/Support/Timer.h" namespace clang { @@ -105,6 +107,11 @@ struct ClangTidyStats { } }; +/// \brief Container for clang-tidy profiling data. +struct ProfileData { + llvm::StringMap<llvm::TimeRecord> Records; +}; + /// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine /// provided by this context. /// @@ -162,6 +169,13 @@ public: /// \brief Clears collected errors. void clearErrors() { Errors.clear(); } + /// \brief Set the output struct for profile data. + /// + /// Setting a non-null pointer here will enable profile collection in + /// clang-tidy. + void setCheckProfileData(ProfileData* Profile); + ProfileData* getCheckProfileData() const { return Profile; } + private: // Calls setDiagnosticsEngine() and storeError(). friend class ClangTidyDiagnosticConsumer; @@ -184,6 +198,8 @@ private: ClangTidyStats Stats; llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID; + + ProfileData *Profile; }; /// \brief A diagnostic consumer that turns each \c Diagnostic into a 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=220491&r1=220490&r2=220491&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp Thu Oct 23 12:23:20 2014 @@ -98,6 +98,11 @@ DumpConfig("dump-config", 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 printStats(const ClangTidySt } } +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 @@ int clangTidyMain(int argc, const char * 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 @@ int clangTidyMain(int argc, const char * } printStats(Stats); + if (EnableCheckProfile) + printProfileData(Profile, llvm::errs()); + return 0; } _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
