diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -29,6 +29,7 @@ #include "support/Trace.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" @@ -54,7 +55,9 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -341,7 +344,10 @@ // ancestors outside this scope). // In practice almost all checks work well without modifications. std::vector> CTChecks; - ast_matchers::MatchFinder CTFinder; + llvm::StringMap CTCheckTimings; + ast_matchers::MatchFinder::MatchFinderOptions CTFinderOpts; + CTFinderOpts.CheckProfiling.emplace(CTCheckTimings); + ast_matchers::MatchFinder CTFinder(CTFinderOpts); llvm::Optional CTContext; llvm::Optional FixIncludes; // No need to run clang-tidy or IncludeFixerif we are not going to surface @@ -492,6 +498,10 @@ // (The preprocessor part ran already, via PPCallbacks). trace::Span Tracer("ClangTidyMatch"); CTFinder.matchAST(Clang->getASTContext()); + static constexpr trace::Metric TidyCheckLatencies( + "tidy_check_latency", trace::Metric::Distribution, "check_name"); + for (auto &Elem : CTCheckTimings) + TidyCheckLatencies.record(Elem.second.getWallTime(), Elem.first()); } // XXX: This is messy: clang-tidy checks flush some diagnostics at EOF. diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -21,6 +21,7 @@ #include "index/MemIndex.h" #include "support/Context.h" #include "support/Path.h" +#include "support/TestTracer.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticSema.h" #include "llvm/Support/ScopedPrinter.h" @@ -305,6 +306,7 @@ "modernize-use-trailing-return-type," "misc-no-recursion"); TU.ExtraArgs.push_back("-Wno-unsequenced"); + trace::TestTracer Tracer; EXPECT_THAT( *TU.build().getDiagnostics(), ifTidyChecks(UnorderedElementsAre( @@ -336,6 +338,11 @@ "function 'foo' is within a recursive call chain"), Diag(Test.range("bar"), "function 'bar' is within a recursive call chain")))); + if (CLANGD_TIDY_CHECKS) { + EXPECT_THAT(Tracer.takeMetric("tidy_check_latency", + "modernize-use-trailing-return-type"), + Not(IsEmpty())); + } } TEST(DiagnosticsTest, ClangTidyEOF) {