Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang-tools-extra/clang-query/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS
add_clang_library(clangQuery STATIC
Query.cpp
QueryParser.cpp
QueryProfile.cpp

DEPENDS
omp_gen
Expand Down
28 changes: 24 additions & 4 deletions clang-tools-extra/clang-query/Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "Query.h"
#include "QueryParser.h"
#include "QueryProfile.h"
#include "QuerySession.h"
#include "clang/AST/ASTDumper.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
Expand Down Expand Up @@ -44,7 +45,9 @@ bool HelpQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
" set bind-root (true|false) "
"Set whether to bind the root matcher to \"root\".\n"
" set print-matcher (true|false) "
"Set whether to print the current matcher,\n"
"Set whether to print the current matcher.\n"
" set enable-profile (true|false) "
"Set whether to enable matcher profiling.\n"
" set traversal <kind> "
"Set traversal kind of clang-query session. Available kinds are:\n"
" AsIs "
Expand Down Expand Up @@ -82,27 +85,42 @@ namespace {

struct CollectBoundNodes : MatchFinder::MatchCallback {
std::vector<BoundNodes> &Bindings;
CollectBoundNodes(std::vector<BoundNodes> &Bindings) : Bindings(Bindings) {}
StringRef Unit;
CollectBoundNodes(std::vector<BoundNodes> &Bindings, StringRef Unit)
: Bindings(Bindings), Unit(Unit) {}
void run(const MatchFinder::MatchResult &Result) override {
Bindings.push_back(Result.Nodes);
}
StringRef getID() const override { return Unit; }
};

} // namespace

bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
unsigned MatchCount = 0;

std::optional<QueryProfile> Profiling;
if (QS.EnableProfile)
Profiling.emplace();

for (auto &AST : QS.ASTs) {
MatchFinder Finder;
ast_matchers::MatchFinder::MatchFinderOptions FinderOptions;
std::optional<llvm::StringMap<llvm::TimeRecord>> Records;
if (QS.EnableProfile) {
Records.emplace();
FinderOptions.CheckProfiling.emplace(*Records);
}

MatchFinder Finder(FinderOptions);
std::vector<BoundNodes> Matches;
DynTypedMatcher MaybeBoundMatcher = Matcher;
if (QS.BindRoot) {
std::optional<DynTypedMatcher> M = Matcher.tryBind("root");
if (M)
MaybeBoundMatcher = *M;
}
CollectBoundNodes Collect(Matches);
StringRef OrigSrcName = AST->getOriginalSourceFileName();
CollectBoundNodes Collect(Matches, OrigSrcName);
if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) {
OS << "Not a valid top-level matcher.\n";
return false;
Expand All @@ -111,6 +129,8 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
ASTContext &Ctx = AST->getASTContext();
Ctx.getParentMapContext().setTraversalKind(QS.TK);
Finder.matchAST(Ctx);
if (QS.EnableProfile)
Profiling->Records[OrigSrcName] += (*Records)[OrigSrcName];

if (QS.PrintMatcher) {
SmallVector<StringRef, 4> Lines;
Expand Down
5 changes: 5 additions & 0 deletions clang-tools-extra/clang-query/QueryParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ enum ParsedQueryVariable {
PQV_Output,
PQV_BindRoot,
PQV_PrintMatcher,
PQV_EnableProfile,
PQV_Traversal
};

Expand Down Expand Up @@ -285,6 +286,7 @@ QueryRef QueryParser::doParse() {
.Case("output", PQV_Output)
.Case("bind-root", PQV_BindRoot)
.Case("print-matcher", PQV_PrintMatcher)
.Case("enable-profile", PQV_EnableProfile)
.Case("traversal", PQV_Traversal)
.Default(PQV_Invalid);
if (VarStr.empty())
Expand All @@ -303,6 +305,9 @@ QueryRef QueryParser::doParse() {
case PQV_PrintMatcher:
Q = parseSetBool(&QuerySession::PrintMatcher);
break;
case PQV_EnableProfile:
Q = parseSetBool(&QuerySession::EnableProfile);
break;
case PQV_Traversal:
Q = parseSetTraversalKind(&QuerySession::TK);
break;
Expand Down
24 changes: 24 additions & 0 deletions clang-tools-extra/clang-query/QueryProfile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-------- QueryProfile.cpp - clang-query --------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "QueryProfile.h"
#include "llvm/Support/raw_ostream.h"

namespace clang::query {

void QueryProfile::printUserFriendlyTable(llvm::raw_ostream &OS) {
TG->print(OS);
OS.flush();
}

QueryProfile::~QueryProfile() {
TG.emplace("clang-query", "clang-query matcher profiling", Records);
printUserFriendlyTable(llvm::errs());
}

} // namespace clang::query
35 changes: 35 additions & 0 deletions clang-tools-extra/clang-query/QueryProfile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===--------- QueryProfile.h - clang-query ---------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H

#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Timer.h"
#include <optional>

namespace llvm {
class raw_ostream;
} // namespace llvm

namespace clang::query {

class QueryProfile {
public:
llvm::StringMap<llvm::TimeRecord> Records;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than leave this public, should we add an interface to insert a new record?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QueryProfile is a very small utility like class, I'll move it into Query.cpp.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QueryProfiler could be simplified to no more then 10 lines.

QueryProfile() = default;
~QueryProfile();

private:
std::optional<llvm::TimerGroup> TG;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this optional?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to be optional, I'll remove it.

void printUserFriendlyTable(llvm::raw_ostream &OS);
};

} // namespace clang::query

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_PROFILE_H
3 changes: 2 additions & 1 deletion clang-tools-extra/clang-query/QuerySession.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class QuerySession {
QuerySession(llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs)
: ASTs(ASTs), PrintOutput(false), DiagOutput(true),
DetailedASTOutput(false), BindRoot(true), PrintMatcher(false),
Terminate(false), TK(TK_AsIs) {}
EnableProfile(false), Terminate(false), TK(TK_AsIs) {}

llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs;

Expand All @@ -36,6 +36,7 @@ class QuerySession {

bool BindRoot;
bool PrintMatcher;
bool EnableProfile;
bool Terminate;

TraversalKind TK;
Expand Down
Loading