[Lldb-commits] [clang] [lldb] [clang] Add -ast-dump-filter-path to filter AST dump by file path (PR #194266)
Taufiq Rahman via lldb-commits
lldb-commits at lists.llvm.org
Sun Aug 30 22:39:45 PDT 2026
https://github.com/Inconnu08 updated https://github.com/llvm/llvm-project/pull/194266
>From c4e587f4a7fc27302d33c0d02cfa6d3ba8f4fefd Mon Sep 17 00:00:00 2001
From: inconnu08 <taufiqrx8 at gmail.com>
Date: Sun, 26 Apr 2026 16:41:03 -0400
Subject: [PATCH 1/3] [clang] Add -ast-dump-filter-path to filter AST dump by
file path
---
clang/include/clang/Frontend/ASTConsumers.h | 11 ++--
.../include/clang/Frontend/FrontendOptions.h | 3 +
clang/include/clang/Options/Options.td | 7 ++
clang/lib/Frontend/ASTConsumers.cpp | 65 ++++++++++++++-----
clang/lib/Frontend/FrontendActions.cpp | 6 +-
clang/tools/clang-check/ClangCheck.cpp | 1 +
.../clang-import-test/clang-import-test.cpp | 2 +-
.../TypeSystem/Clang/TypeSystemClang.cpp | 1 +
8 files changed, 70 insertions(+), 26 deletions(-)
diff --git a/clang/include/clang/Frontend/ASTConsumers.h b/clang/include/clang/Frontend/ASTConsumers.h
index 890701b6ff188..0650f16df3aab 100644
--- a/clang/include/clang/Frontend/ASTConsumers.h
+++ b/clang/include/clang/Frontend/ASTConsumers.h
@@ -32,13 +32,14 @@ std::unique_ptr<ASTConsumer> CreateASTPrinter(std::unique_ptr<raw_ostream> OS,
// stream, or stdout if OS is nullptr.
std::unique_ptr<ASTConsumer>
CreateASTDumper(std::unique_ptr<raw_ostream> OS, StringRef FilterString,
- bool DumpDecls, bool Deserialize, bool DumpLookups,
- bool DumpDeclTypes, ASTDumpOutputFormat Format);
+ StringRef FilterPath, bool DumpDecls, bool Deserialize,
+ bool DumpLookups, bool DumpDeclTypes,
+ ASTDumpOutputFormat Format);
std::unique_ptr<ASTConsumer>
-CreateASTDumper(raw_ostream &OS, StringRef FilterString, bool DumpDecls,
- bool Deserialize, bool DumpLookups, bool DumpDeclTypes,
- ASTDumpOutputFormat Format);
+CreateASTDumper(raw_ostream &OS, StringRef FilterString, StringRef FilterPath,
+ bool DumpDecls, bool Deserialize, bool DumpLookups,
+ bool DumpDeclTypes, ASTDumpOutputFormat Format);
// AST Decl node lister: prints qualified names of all filterable AST Decl
// nodes.
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index b85cf4c007862..cb32509aa09e2 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -461,6 +461,9 @@ class FrontendOptions {
/// If given, filter dumped AST Decl nodes by this substring.
std::string ASTDumpFilter;
+ /// If given, filter dumped AST Decl nodes by source file path (glob pattern).
+ std::string ASTDumpFilterPath;
+
/// If given, enable code completion at the provided location.
ParsedSourceLocation CodeCompletionAt;
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 3b88dce9c822b..662a2eaf30cbc 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -8638,6 +8638,13 @@ def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
MarshallingInfoString<FrontendOpts<"ASTDumpFilter">>;
def ast_dump_filter_EQ : Joined<["-"], "ast-dump-filter=">,
Alias<ast_dump_filter>;
+def ast_dump_filter_path : Separate<["-"], "ast-dump-filter-path">,
+ MetaVarName<"<path_filter>">,
+ HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
+ " nodes whose source file path matches a glob pattern.">,
+ MarshallingInfoString<FrontendOpts<"ASTDumpFilterPath">>;
+def ast_dump_filter_path_EQ : Joined<["-"], "ast-dump-filter-path=">,
+ Alias<ast_dump_filter_path>;
def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
HelpText<"Do not automatically generate or update the global module index">,
MarshallingInfoNegativeFlag<FrontendOpts<"UseGlobalModuleIndex">>;
diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp
index 40995e32b67fa..e7f4e00c2c5b7 100644
--- a/clang/lib/Frontend/ASTConsumers.cpp
+++ b/clang/lib/Frontend/ASTConsumers.cpp
@@ -18,8 +18,11 @@
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/Diagnostic.h"
-#include "llvm/Support/Timer.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/GlobPattern.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Timer.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -34,22 +37,24 @@ namespace {
enum Kind { DumpFull, Dump, Print, None };
ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
ASTDumpOutputFormat Format, StringRef FilterString,
- bool DumpLookups = false, bool DumpDeclTypes = false)
+ StringRef FilterPath, bool DumpLookups = false,
+ bool DumpDeclTypes = false)
: Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
OutputKind(K), OutputFormat(Format), FilterString(FilterString),
- DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}
+ FilterPath(FilterPath), DumpLookups(DumpLookups),
+ DumpDeclTypes(DumpDeclTypes) {}
ASTPrinter(raw_ostream &Out, Kind K, ASTDumpOutputFormat Format,
- StringRef FilterString, bool DumpLookups = false,
- bool DumpDeclTypes = false)
+ StringRef FilterString, StringRef FilterPath,
+ bool DumpLookups = false, bool DumpDeclTypes = false)
: Out(Out), OwnedOut(nullptr), OutputKind(K), OutputFormat(Format),
- FilterString(FilterString), DumpLookups(DumpLookups),
- DumpDeclTypes(DumpDeclTypes) {}
+ FilterString(FilterString), FilterPath(FilterPath),
+ DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}
void HandleTranslationUnit(ASTContext &Context) override {
TranslationUnitDecl *D = Context.getTranslationUnitDecl();
- if (FilterString.empty())
+ if (FilterString.empty() && FilterPath.empty())
return print(D);
TraverseDecl(D);
@@ -84,7 +89,28 @@ namespace {
return "";
}
bool filterMatches(Decl *D) {
- return getName(D).find(FilterString) != std::string::npos;
+ if (!FilterString.empty() &&
+ getName(D).find(FilterString) == std::string::npos)
+ return false;
+
+ if (!FilterPath.empty()) {
+ const SourceManager &SM = D->getASTContext().getSourceManager();
+
+ SourceLocation Loc = SM.getSpellingLoc(D->getLocation());
+ if (Loc.isInvalid())
+ return false;
+
+ auto Pattern = llvm::GlobPattern::create(FilterPath);
+ if (!Pattern) {
+ llvm::consumeError(Pattern.takeError());
+ return false;
+ }
+
+ if (!Pattern->match(SM.getFilename(Loc)))
+ return false;
+ }
+
+ return true;
}
void print(Decl *D) {
if (DumpLookups) {
@@ -134,6 +160,9 @@ namespace {
/// Which declarations or DeclContexts to display.
std::string FilterString;
+ /// Which source file paths to display.
+ std::string FilterPath;
+
/// Whether the primary output is lookup results or declarations. Individual
/// results will be output with a format determined by OutputKind. This is
/// incompatible with OutputKind == Print.
@@ -170,32 +199,34 @@ std::unique_ptr<ASTConsumer>
clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
StringRef FilterString) {
return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
- ADOF_Default, FilterString);
+ ADOF_Default, FilterString, "");
}
std::unique_ptr<ASTConsumer>
clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,
- bool DumpDecls, bool Deserialize, bool DumpLookups,
+ StringRef FilterPath, bool DumpDecls,
+ bool Deserialize, bool DumpLookups,
bool DumpDeclTypes, ASTDumpOutputFormat Format) {
assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
return std::make_unique<ASTPrinter>(
std::move(Out),
Deserialize ? ASTPrinter::DumpFull
: DumpDecls ? ASTPrinter::Dump : ASTPrinter::None,
- Format, FilterString, DumpLookups, DumpDeclTypes);
+ Format, FilterString, FilterPath, DumpLookups, DumpDeclTypes);
}
std::unique_ptr<ASTConsumer>
-clang::CreateASTDumper(raw_ostream &Out, StringRef FilterString, bool DumpDecls,
- bool Deserialize, bool DumpLookups, bool DumpDeclTypes,
- ASTDumpOutputFormat Format) {
+clang::CreateASTDumper(raw_ostream &Out, StringRef FilterString,
+ StringRef FilterPath, bool DumpDecls,
+ bool Deserialize, bool DumpLookups,
+ bool DumpDeclTypes, ASTDumpOutputFormat Format) {
assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
return std::make_unique<ASTPrinter>(Out,
Deserialize ? ASTPrinter::DumpFull
: DumpDecls ? ASTPrinter::Dump
: ASTPrinter::None,
- Format, FilterString, DumpLookups,
- DumpDeclTypes);
+ Format, FilterString, FilterPath,
+ DumpLookups, DumpDeclTypes);
}
std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index e7b05740b8376..b2063e72b8b84 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -88,9 +88,9 @@ std::unique_ptr<ASTConsumer>
ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
const FrontendOptions &Opts = CI.getFrontendOpts();
return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter,
- Opts.ASTDumpDecls, Opts.ASTDumpAll,
- Opts.ASTDumpLookups, Opts.ASTDumpDeclTypes,
- Opts.ASTDumpFormat);
+ Opts.ASTDumpFilterPath, Opts.ASTDumpDecls,
+ Opts.ASTDumpAll, Opts.ASTDumpLookups,
+ Opts.ASTDumpDeclTypes, Opts.ASTDumpFormat);
}
std::unique_ptr<ASTConsumer>
diff --git a/clang/tools/clang-check/ClangCheck.cpp b/clang/tools/clang-check/ClangCheck.cpp
index 7672b59b35482..eee50759671bc 100644
--- a/clang/tools/clang-check/ClangCheck.cpp
+++ b/clang/tools/clang-check/ClangCheck.cpp
@@ -178,6 +178,7 @@ class ClangCheckActionFactory {
return clang::CreateASTDeclNodeLister();
if (ASTDump)
return clang::CreateASTDumper(nullptr /*Dump to stdout.*/, ASTDumpFilter,
+ /*FilterPath=*/"",
/*DumpDecls=*/true,
/*Deserialize=*/false,
/*DumpLookups=*/false,
diff --git a/clang/tools/clang-import-test/clang-import-test.cpp b/clang/tools/clang-import-test/clang-import-test.cpp
index 8e83687d3e96a..489651953e1d4 100644
--- a/clang/tools/clang-import-test/clang-import-test.cpp
+++ b/clang/tools/clang-import-test/clang-import-test.cpp
@@ -325,7 +325,7 @@ llvm::Expected<CIAndOrigins> Parse(const std::string &Path,
auto &CG = *static_cast<CodeGenerator *>(ASTConsumers.back().get());
if (ShouldDumpAST)
- ASTConsumers.push_back(CreateASTDumper(nullptr /*Dump to stdout.*/, "",
+ ASTConsumers.push_back(CreateASTDumper(nullptr /*Dump to stdout.*/, "", "",
true, false, false, false,
clang::ADOF_Default));
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index f11e78d4b008c..a9bfdfa44e71c 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -8521,6 +8521,7 @@ void TypeSystemClang::Dump(llvm::raw_ostream &output, llvm::StringRef filter,
auto consumer =
clang::CreateASTDumper(output, filter,
+ /*FilterPath=*/"",
/*DumpDecls=*/true,
/*Deserialize=*/false,
/*DumpLookups=*/false,
>From 0a0051c8167b77ac0d941f28280b21c20a3ece83 Mon Sep 17 00:00:00 2001
From: inconnu08 <taufiqrx8 at gmail.com>
Date: Thu, 7 May 2026 23:03:39 -0400
Subject: [PATCH 2/3] [clang] Address review feedback: use presumed loc, add
tests and release note
---
clang/docs/ReleaseNotes.md | 5 +++++
clang/include/clang/Options/Options.td | 2 +-
clang/lib/Frontend/ASTConsumers.cpp | 11 ++++++++---
clang/test/AST/ast-dump-filter-path-include.c | 7 +++++++
clang/test/AST/ast-dump-filter-path.c | 8 ++++++++
clang/test/AST/filter-header.h | 1 +
6 files changed, 30 insertions(+), 4 deletions(-)
create mode 100644 clang/test/AST/ast-dump-filter-path-include.c
create mode 100644 clang/test/AST/ast-dump-filter-path.c
create mode 100644 clang/test/AST/filter-header.h
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index bdbabf2cd98d0..72f52fe3de52d 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -229,6 +229,11 @@ features cannot lower the translation-unit ABI level;
path share one module cache, and is only sound when no module needs the path
-- a lookup that would have resolved through an ignored path simply fails.
+- Added a new `-ast-dump-filter-path` option to filter AST dump output
+ based on the source file path of declarations. The filter uses glob-style
+ matching on the presumed source location (accounting for macro expansions
+ and `#line` directives).
+
### Deprecated Compiler Flags
### Modified Compiler Flags
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 662a2eaf30cbc..6b1996e3b0c9b 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -8640,7 +8640,7 @@ def ast_dump_filter_EQ : Joined<["-"], "ast-dump-filter=">,
Alias<ast_dump_filter>;
def ast_dump_filter_path : Separate<["-"], "ast-dump-filter-path">,
MetaVarName<"<path_filter>">,
- HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
+ HelpText<"Use with '-ast-dump' or '-ast-print' to dump/print only AST declaration"
" nodes whose source file path matches a glob pattern.">,
MarshallingInfoString<FrontendOpts<"ASTDumpFilterPath">>;
def ast_dump_filter_path_EQ : Joined<["-"], "ast-dump-filter-path=">,
diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp
index e7f4e00c2c5b7..cf01056f8ffac 100644
--- a/clang/lib/Frontend/ASTConsumers.cpp
+++ b/clang/lib/Frontend/ASTConsumers.cpp
@@ -96,17 +96,22 @@ namespace {
if (!FilterPath.empty()) {
const SourceManager &SM = D->getASTContext().getSourceManager();
- SourceLocation Loc = SM.getSpellingLoc(D->getLocation());
+ SourceLocation Loc = D->getLocation();
if (Loc.isInvalid())
return false;
- auto Pattern = llvm::GlobPattern::create(FilterPath);
+ PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+ if (PLoc.isInvalid())
+ return false;
+
+ llvm::Expected<llvm::GlobPattern> Pattern =
+ llvm::GlobPattern::create(FilterPath);
if (!Pattern) {
llvm::consumeError(Pattern.takeError());
return false;
}
- if (!Pattern->match(SM.getFilename(Loc)))
+ if (!Pattern->match(PLoc.getFilename()))
return false;
}
diff --git a/clang/test/AST/ast-dump-filter-path-include.c b/clang/test/AST/ast-dump-filter-path-include.c
new file mode 100644
index 0000000000000..97a82302285d7
--- /dev/null
+++ b/clang/test/AST/ast-dump-filter-path-include.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -ast-dump -ast-dump-filter-path %s %s | FileCheck %s
+
+#include "filter-header.h"
+
+MAKE_VAR(z)
+
+// CHECK: VarDecl {{.*}} z
diff --git a/clang/test/AST/ast-dump-filter-path.c b/clang/test/AST/ast-dump-filter-path.c
new file mode 100644
index 0000000000000..d24eeea52d3b1
--- /dev/null
+++ b/clang/test/AST/ast-dump-filter-path.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -ast-dump -ast-dump-filter-path "*ast-dump-filter-path.c" %s | FileCheck %s
+
+int x;
+// CHECK: VarDecl {{.*}} x
+
+#define MAKE_VAR(name) int name;
+MAKE_VAR(y)
+// CHECK: VarDecl {{.*}} y
\ No newline at end of file
diff --git a/clang/test/AST/filter-header.h b/clang/test/AST/filter-header.h
new file mode 100644
index 0000000000000..8b54743ed8692
--- /dev/null
+++ b/clang/test/AST/filter-header.h
@@ -0,0 +1 @@
+#define MAKE_VAR(name) int name;
>From c23bc45a69755803a68daf12b870f389cac202b0 Mon Sep 17 00:00:00 2001
From: inconnu08 <taufiqrx8 at gmail.com>
Date: Mon, 31 Aug 2026 01:38:34 -0400
Subject: [PATCH 3/3] [clang] Make ast-dump-filter-path include test portable
---
clang/test/AST/ast-dump-filter-path-include.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/AST/ast-dump-filter-path-include.c b/clang/test/AST/ast-dump-filter-path-include.c
index 97a82302285d7..9394c153cc8e7 100644
--- a/clang/test/AST/ast-dump-filter-path-include.c
+++ b/clang/test/AST/ast-dump-filter-path-include.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -ast-dump -ast-dump-filter-path %s %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -ast-dump -ast-dump-filter-path "*ast-dump-filter-path-include.c" %s | FileCheck %s
#include "filter-header.h"
MAKE_VAR(z)
-// CHECK: VarDecl {{.*}} z
+// CHECK: VarDecl {{.*}} z
\ No newline at end of file
More information about the lldb-commits
mailing list