summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clang-tidy/CMakeLists.txt1
-rw-r--r--clang-tools-extra/clang-tidy/ClangTidy.cpp24
-rw-r--r--clang-tools-extra/clang-tidy/ClangTidy.h2
-rw-r--r--clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp4
-rw-r--r--clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h16
-rw-r--r--clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp65
-rw-r--r--clang-tools-extra/clang-tidy/ClangTidyProfiling.h41
-rw-r--r--clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp45
-rw-r--r--clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp18
-rw-r--r--clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp24
10 files changed, 174 insertions, 66 deletions
diff --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt
index 6738c310386..a872469429c 100644
--- a/clang-tools-extra/clang-tidy/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/CMakeLists.txt
@@ -7,6 +7,7 @@ add_clang_library(clangTidy
ClangTidyModule.cpp
ClangTidyDiagnosticConsumer.cpp
ClangTidyOptions.cpp
+ ClangTidyProfiling.cpp
DEPENDS
ClangSACheckers
diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp
index 59ee6046653..1493fbbd247 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -18,6 +18,7 @@
#include "ClangTidy.h"
#include "ClangTidyDiagnosticConsumer.h"
#include "ClangTidyModuleRegistry.h"
+#include "ClangTidyProfiling.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -267,12 +268,17 @@ private:
class ClangTidyASTConsumer : public MultiplexConsumer {
public:
ClangTidyASTConsumer(std::vector<std::unique_ptr<ASTConsumer>> Consumers,
+ std::unique_ptr<ClangTidyProfiling> Profiling,
std::unique_ptr<ast_matchers::MatchFinder> Finder,
std::vector<std::unique_ptr<ClangTidyCheck>> Checks)
- : MultiplexConsumer(std::move(Consumers)), Finder(std::move(Finder)),
+ : MultiplexConsumer(std::move(Consumers)),
+ Profiling(std::move(Profiling)), Finder(std::move(Finder)),
Checks(std::move(Checks)) {}
private:
+ // Destructor order matters! Profiling must be destructed last.
+ // Or at least after Finder.
+ std::unique_ptr<ClangTidyProfiling> Profiling;
std::unique_ptr<ast_matchers::MatchFinder> Finder;
std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
};
@@ -353,8 +359,12 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
CheckFactories->createChecks(&Context, Checks);
ast_matchers::MatchFinder::MatchFinderOptions FinderOptions;
- if (auto *P = Context.getCheckProfileData())
- FinderOptions.CheckProfiling.emplace(P->Records);
+
+ std::unique_ptr<ClangTidyProfiling> Profiling;
+ if (Context.getEnableProfiling()) {
+ Profiling = llvm::make_unique<ClangTidyProfiling>();
+ FinderOptions.CheckProfiling.emplace(Profiling->Records);
+ }
std::unique_ptr<ast_matchers::MatchFinder> Finder(
new ast_matchers::MatchFinder(std::move(FinderOptions)));
@@ -383,7 +393,8 @@ ClangTidyASTConsumerFactory::CreateASTConsumer(
Consumers.push_back(std::move(AnalysisConsumer));
}
return llvm::make_unique<ClangTidyASTConsumer>(
- std::move(Consumers), std::move(Finder), std::move(Checks));
+ std::move(Consumers), std::move(Profiling), std::move(Finder),
+ std::move(Checks));
}
std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
@@ -472,7 +483,7 @@ void runClangTidy(clang::tidy::ClangTidyContext &Context,
const CompilationDatabase &Compilations,
ArrayRef<std::string> InputFiles,
llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,
- ProfileData *Profile) {
+ bool EnableCheckProfile) {
ClangTool Tool(Compilations, InputFiles,
std::make_shared<PCHContainerOperations>(), BaseFS);
@@ -512,8 +523,7 @@ void runClangTidy(clang::tidy::ClangTidyContext &Context,
Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter);
Tool.appendArgumentsAdjuster(PluginArgumentsRemover);
- if (Profile)
- Context.setCheckProfileData(Profile);
+ Context.setEnableProfiling(EnableCheckProfile);
ClangTidyDiagnosticConsumer DiagConsumer(Context);
diff --git a/clang-tools-extra/clang-tidy/ClangTidy.h b/clang-tools-extra/clang-tidy/ClangTidy.h
index 7c9ef760fdc..c68f6ed3ae6 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.h
+++ b/clang-tools-extra/clang-tidy/ClangTidy.h
@@ -228,7 +228,7 @@ void runClangTidy(clang::tidy::ClangTidyContext &Context,
const tooling::CompilationDatabase &Compilations,
ArrayRef<std::string> InputFiles,
llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,
- ProfileData *Profile = nullptr);
+ bool EnableCheckProfile = false);
// FIXME: This interface will need to be significantly extended to be useful.
// FIXME: Implement confidence levels for displaying/fixing errors.
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index d3c1754fceb..dd4f6584e03 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -179,7 +179,7 @@ private:
ClangTidyContext::ClangTidyContext(
std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider)
: DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)),
- Profile(nullptr) {
+ Profile(false) {
// 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("");
@@ -233,7 +233,7 @@ ClangTidyOptions ClangTidyContext::getOptionsForFile(StringRef File) const {
OptionsProvider->getOptions(File));
}
-void ClangTidyContext::setCheckProfileData(ProfileData *P) { Profile = P; }
+void ClangTidyContext::setEnableProfiling(bool P) { Profile = P; }
bool ClangTidyContext::isCheckEnabled(StringRef CheckName) const {
assert(CheckFilter != nullptr);
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
index b484794676d..60e5040a7ae 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -87,11 +87,6 @@ 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 DiagnosticsEngine
/// provided by this context.
///
@@ -169,12 +164,9 @@ 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; }
+ /// \brief Control profile collection in clang-tidy.
+ void setEnableProfiling(bool Profile);
+ bool getEnableProfiling() const { return Profile; }
/// \brief Should be called when starting to process new translation unit.
void setCurrentBuildDirectory(StringRef BuildDirectory) {
@@ -216,7 +208,7 @@ private:
llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
- ProfileData *Profile;
+ bool Profile;
};
/// \brief A diagnostic consumer that turns each \c Diagnostic into a
diff --git a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
new file mode 100644
index 00000000000..d332942fa24
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
@@ -0,0 +1,65 @@
+//===--- ClangTidyProfiling.cpp - clang-tidy --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangTidyProfiling.h"
+#include "llvm/ADT/STLExtras.h"
+
+#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");
+
+ // We want the measurements to be sorted by decreasing time spent.
+ llvm::sort(Timers.begin(), Timers.end());
+}
+
+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';
+ }
+
+ Total.print(Total, OS);
+ OS << "Total\n";
+ OS << Line << "\n";
+ OS.flush();
+}
+
+ClangTidyProfiling::~ClangTidyProfiling() {
+ preprocess();
+ printProfileData(llvm::errs());
+}
+
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/ClangTidyProfiling.h b/clang-tools-extra/clang-tidy/ClangTidyProfiling.h
new file mode 100644
index 00000000000..002a1489224
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/ClangTidyProfiling.h
@@ -0,0 +1,41 @@
+//===--- ClangTidyProfiling.h - clang-tidy ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYPROFILING_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYPROFILING_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <utility>
+#include <vector>
+
+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;
+
+ void preprocess();
+
+ void printProfileData(llvm::raw_ostream &OS) const;
+
+public:
+ llvm::StringMap<llvm::TimeRecord> Records;
+
+ ~ClangTidyProfiling();
+};
+
+} // end namespace tidy
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYPROFILING_H
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index 12c0e472c09..07accbbcea9 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -236,45 +236,6 @@ static void printStats(const ClangTidyStats &Stats) {
}
}
-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();
-}
-
static std::unique_ptr<ClangTidyOptionsProvider> createOptionsProvider(
llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) {
ClangTidyGlobalOptions GlobalOptions;
@@ -424,7 +385,6 @@ static int clangTidyMain(int argc, const char **argv) {
llvm::cl::PrintHelpMessage(/*Hidden=*/false, /*Categorized=*/true);
return 1;
}
- ProfileData Profile;
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargetMCs();
@@ -432,7 +392,7 @@ static int clangTidyMain(int argc, const char **argv) {
ClangTidyContext Context(std::move(OwningOptionsProvider));
runClangTidy(Context, OptionsParser.getCompilations(), PathList, BaseFS,
- EnableCheckProfile ? &Profile : nullptr);
+ EnableCheckProfile);
ArrayRef<ClangTidyError> Errors = Context.getErrors();
bool FoundErrors = llvm::find_if(Errors, [](const ClangTidyError &E) {
return E.DiagLevel == ClangTidyError::Error;
@@ -464,9 +424,6 @@ static int clangTidyMain(int argc, const char **argv) {
"Fixes have NOT been applied.\n\n";
}
- if (EnableCheckProfile)
- printProfileData(Profile, llvm::errs());
-
if (WErrorCount) {
if (!Quiet) {
StringRef Plural = WErrorCount == 1 ? "" : "s";
diff --git a/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp b/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp
new file mode 100644
index 00000000000..523b6eb049a
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp
@@ -0,0 +1,18 @@
+// 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: {{.*}} readability-function-size
+// CHECK-NEXT: {{.*}} Total
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT: {{.*}} --- Name ---
+// CHECK-NOT: {{.*}} readability-function-size
+// CHECK-NOT: {{.*}} Total
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+
+class A {
+ A() {}
+ ~A() {}
+};
diff --git a/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp b/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp
new file mode 100644
index 00000000000..9777dc9069f
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp
@@ -0,0 +1,24 @@
+// 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: {{.*}} readability-function-size
+// CHECK-NEXT: {{.*}} Total
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+
+// CHECK: ===-------------------------------------------------------------------------===
+// CHECK-NEXT: {{.*}} --- Name ---
+// CHECK-NEXT: {{.*}} readability-function-size
+// CHECK-NEXT: {{.*}} Total
+// CHECK-NEXT: ===-------------------------------------------------------------------------===
+
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+// CHECK-NOT: {{.*}} --- Name ---
+// CHECK-NOT: {{.*}} readability-function-size
+// CHECK-NOT: {{.*}} Total
+// CHECK-NOT: ===-------------------------------------------------------------------------===
+
+class A {
+ A() {}
+ ~A() {}
+};
OpenPOWER on IntegriCloud