[clang-tools-extra] 8d018c7 - Add srcloc output to clang-query
Stephen Kelly via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 25 04:24:17 PDT 2021
Author: Stephen Kelly
Date: 2021-04-25T12:12:04+01:00
New Revision: 8d018c79ee5f14e1433b8cbb02dd89d0941516ff
URL: https://github.com/llvm/llvm-project/commit/8d018c79ee5f14e1433b8cbb02dd89d0941516ff
DIFF: https://github.com/llvm/llvm-project/commit/8d018c79ee5f14e1433b8cbb02dd89d0941516ff.diff
LOG: Add srcloc output to clang-query
Differential Revision: https://reviews.llvm.org/D93325
Added:
Modified:
clang-tools-extra/clang-query/CMakeLists.txt
clang-tools-extra/clang-query/Query.cpp
clang-tools-extra/clang-query/Query.h
clang-tools-extra/clang-query/QueryParser.cpp
clang-tools-extra/clang-query/QuerySession.h
clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-query/CMakeLists.txt b/clang-tools-extra/clang-query/CMakeLists.txt
index 043d26147a7f..8355ef0aba5e 100644
--- a/clang-tools-extra/clang-query/CMakeLists.txt
+++ b/clang-tools-extra/clang-query/CMakeLists.txt
@@ -19,6 +19,7 @@ clang_target_link_libraries(clangQuery
clangBasic
clangDynamicASTMatchers
clangFrontend
+ clangTooling
clangSerialization
)
diff --git a/clang-tools-extra/clang-query/Query.cpp b/clang-tools-extra/clang-query/Query.cpp
index 5cf24dbb58a7..2c169b1f9a7f 100644
--- a/clang-tools-extra/clang-query/Query.cpp
+++ b/clang-tools-extra/clang-query/Query.cpp
@@ -12,6 +12,7 @@
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/TextDiagnostic.h"
+#include "clang/Tooling/NodeIntrospection.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang::ast_matchers;
@@ -66,6 +67,8 @@ bool HelpQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
"Diagnostic location for bound nodes.\n"
" detailed-ast "
"Detailed AST output for bound nodes.\n"
+ " srcloc "
+ "Source locations and ranges for bound nodes.\n"
" dump "
"Detailed AST output for bound nodes (alias of detailed-ast).\n\n";
return true;
@@ -86,6 +89,90 @@ struct CollectBoundNodes : MatchFinder::MatchCallback {
}
};
+void dumpLocations(llvm::raw_ostream &OS, DynTypedNode Node, ASTContext &Ctx,
+ const DiagnosticsEngine &Diags, SourceManager const &SM) {
+ auto Locs = clang::tooling::NodeIntrospection::GetLocations(Node);
+
+ auto PrintLocations = [](llvm::raw_ostream &OS, auto Iter, auto End) {
+ auto CommonEntry = Iter->first;
+ auto Scout = Iter;
+ SmallVector<std::string> LocationStrings;
+ while (Scout->first == CommonEntry) {
+ LocationStrings.push_back(
+ tooling::LocationCallFormatterCpp::format(*Iter->second));
+ if (Scout == End)
+ break;
+ ++Scout;
+ if (Scout->first == CommonEntry)
+ ++Iter;
+ }
+ llvm::sort(LocationStrings);
+ for (auto &LS : LocationStrings) {
+ OS << " * \"" << LS << "\"\n";
+ }
+ return Iter;
+ };
+
+ TextDiagnostic TD(OS, Ctx.getLangOpts(), &Diags.getDiagnosticOptions());
+
+ for (auto Iter = Locs.LocationAccessors.begin();
+ Iter != Locs.LocationAccessors.end(); ++Iter) {
+ if (!Iter->first.isValid())
+ continue;
+
+ TD.emitDiagnostic(FullSourceLoc(Iter->first, SM), DiagnosticsEngine::Note,
+ "source locations here", None, None);
+
+ Iter = PrintLocations(OS, Iter, Locs.LocationAccessors.end());
+ OS << '\n';
+ }
+
+ for (auto Iter = Locs.RangeAccessors.begin();
+ Iter != Locs.RangeAccessors.end(); ++Iter) {
+
+ if (!Iter->first.getBegin().isValid())
+ continue;
+
+ if (SM.getPresumedLineNumber(Iter->first.getBegin()) !=
+ SM.getPresumedLineNumber(Iter->first.getEnd()))
+ continue;
+
+ TD.emitDiagnostic(FullSourceLoc(Iter->first.getBegin(), SM),
+ DiagnosticsEngine::Note,
+ "source ranges here " + Iter->first.printToString(SM),
+ CharSourceRange::getTokenRange(Iter->first), None);
+
+ Iter = PrintLocations(OS, Iter, Locs.RangeAccessors.end());
+ }
+ for (auto Iter = Locs.RangeAccessors.begin();
+ Iter != Locs.RangeAccessors.end(); ++Iter) {
+
+ if (!Iter->first.getBegin().isValid())
+ continue;
+
+ if (SM.getPresumedLineNumber(Iter->first.getBegin()) ==
+ SM.getPresumedLineNumber(Iter->first.getEnd()))
+ continue;
+
+ TD.emitDiagnostic(
+ FullSourceLoc(Iter->first.getBegin(), SM), DiagnosticsEngine::Note,
+ "source range " + Iter->first.printToString(SM) + " starting here...",
+ CharSourceRange::getTokenRange(Iter->first), None);
+
+ auto ColNum = SM.getPresumedColumnNumber(Iter->first.getEnd());
+ auto LastLineLoc = Iter->first.getEnd().getLocWithOffset(-(ColNum - 1));
+
+ TD.emitDiagnostic(FullSourceLoc(Iter->first.getEnd(), SM),
+ DiagnosticsEngine::Note, "... ending here",
+ CharSourceRange::getTokenRange(
+ SourceRange(LastLineLoc, Iter->first.getEnd())),
+ None);
+
+ Iter = PrintLocations(OS, Iter, Locs.RangeAccessors.end());
+ }
+ OS << "\n";
+}
+
} // namespace
bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
@@ -106,8 +193,10 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
return false;
}
- AST->getASTContext().getParentMapContext().setTraversalKind(QS.TK);
- Finder.matchAST(AST->getASTContext());
+ auto &Ctx = AST->getASTContext();
+ const auto &SM = Ctx.getSourceManager();
+ Ctx.getParentMapContext().setTraversalKind(QS.TK);
+ Finder.matchAST(Ctx);
if (QS.PrintMatcher) {
SmallVector<StringRef, 4> Lines;
@@ -159,6 +248,13 @@ bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
Dumper.Visit(BI->second);
OS << "\n";
}
+ if (QS.SrcLocOutput) {
+ OS << "\n \"" << BI->first << "\" Source locations\n";
+ OS << " " << std::string(19 + BI->first.size(), '-') << '\n';
+
+ dumpLocations(OS, BI->second, Ctx, AST->getDiagnostics(), SM);
+ OS << "\n";
+ }
}
if (MI->getMap().empty())
diff --git a/clang-tools-extra/clang-query/Query.h b/clang-tools-extra/clang-query/Query.h
index 4c95195d96c1..38be29101c96 100644
--- a/clang-tools-extra/clang-query/Query.h
+++ b/clang-tools-extra/clang-query/Query.h
@@ -18,7 +18,7 @@
namespace clang {
namespace query {
-enum OutputKind { OK_Diag, OK_Print, OK_DetailedAST };
+enum OutputKind { OK_Diag, OK_Print, OK_DetailedAST, OK_SrcLoc };
enum QueryKind {
QK_Invalid,
diff --git a/clang-tools-extra/clang-query/QueryParser.cpp b/clang-tools-extra/clang-query/QueryParser.cpp
index b01d8001b669..b444162cfc0a 100644
--- a/clang-tools-extra/clang-query/QueryParser.cpp
+++ b/clang-tools-extra/clang-query/QueryParser.cpp
@@ -108,6 +108,7 @@ template <typename QueryType> QueryRef QueryParser::parseSetOutputKind() {
.Case("diag", OK_Diag)
.Case("print", OK_Print)
.Case("detailed-ast", OK_DetailedAST)
+ .Case("srcloc", OK_SrcLoc)
.Case("dump", OK_DetailedAST)
.Default(~0u);
if (OutKind == ~0u) {
@@ -123,6 +124,8 @@ template <typename QueryType> QueryRef QueryParser::parseSetOutputKind() {
return new QueryType(&QuerySession::DiagOutput);
case OK_Print:
return new QueryType(&QuerySession::PrintOutput);
+ case OK_SrcLoc:
+ return new QueryType(&QuerySession::SrcLocOutput);
}
llvm_unreachable("Invalid output kind");
diff --git a/clang-tools-extra/clang-query/QuerySession.h b/clang-tools-extra/clang-query/QuerySession.h
index 31a4900e2619..9a08289a2534 100644
--- a/clang-tools-extra/clang-query/QuerySession.h
+++ b/clang-tools-extra/clang-query/QuerySession.h
@@ -25,14 +25,15 @@ class QuerySession {
public:
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) {}
+ DetailedASTOutput(false), SrcLocOutput(false), BindRoot(true),
+ PrintMatcher(false), Terminate(false), TK(TK_AsIs) {}
llvm::ArrayRef<std::unique_ptr<ASTUnit>> ASTs;
bool PrintOutput;
bool DiagOutput;
bool DetailedASTOutput;
+ bool SrcLocOutput;
bool BindRoot;
bool PrintMatcher;
diff --git a/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp b/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
index 76ab85680b9f..713a6c23848a 100644
--- a/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
+++ b/clang-tools-extra/unittests/clang-query/QueryParserTest.cpp
@@ -218,7 +218,7 @@ TEST_F(QueryParserTest, Complete) {
EXPECT_EQ("output", Comps[0].DisplayText);
Comps = QueryParser::complete("enable output ", 14, QS);
- ASSERT_EQ(4u, Comps.size());
+ ASSERT_EQ(5u, Comps.size());
EXPECT_EQ("diag ", Comps[0].TypedText);
EXPECT_EQ("diag", Comps[0].DisplayText);
@@ -226,8 +226,10 @@ TEST_F(QueryParserTest, Complete) {
EXPECT_EQ("print", Comps[1].DisplayText);
EXPECT_EQ("detailed-ast ", Comps[2].TypedText);
EXPECT_EQ("detailed-ast", Comps[2].DisplayText);
- EXPECT_EQ("dump ", Comps[3].TypedText);
- EXPECT_EQ("dump", Comps[3].DisplayText);
+ EXPECT_EQ("srcloc ", Comps[3].TypedText);
+ EXPECT_EQ("srcloc", Comps[3].DisplayText);
+ EXPECT_EQ("dump ", Comps[4].TypedText);
+ EXPECT_EQ("dump", Comps[4].DisplayText);
Comps = QueryParser::complete("set traversal ", 14, QS);
ASSERT_EQ(2u, Comps.size());
More information about the cfe-commits
mailing list