Skip to content

Commit 88767a3

Browse files
committed
[lldb] Add filter option to AST dump command (llvm#142164)
Depends on llvm#142163 This patch makes the `-ast-dump-filter` Clang option available to the `target modules dump ast` command. This allows us to selectively dump parts of the AST by name. The AST can quickly grow way too large to skim on the console. This will aid in debugging AST related issues. Example: ``` (lldb) target modules dump ast --filter func Dumping clang ast for 48 modules. Dumping func: FunctionDecl 0xc4b785008 <<invalid sloc>> <invalid sloc> func 'void (int)' extern |-ParmVarDecl 0xc4b7853d8 <<invalid sloc>> <invalid sloc> x 'int' `-AsmLabelAttr 0xc4b785358 <<invalid sloc>> Implicit "_Z4funcIiEvT_" Dumping func<int>: FunctionDecl 0xc4b7850b8 <<invalid sloc>> <invalid sloc> func<int> 'void (int)' implicit_instantiation extern |-TemplateArgument type 'int' | `-BuiltinType 0xc4b85b110 'int' `-ParmVarDecl 0xc4b7853d8 <<invalid sloc>> <invalid sloc> x 'int' ``` The majority of this patch is adjust the `Dump` API. The main change in behaviour is in `TypeSystemClang::Dump`, where we now use the `ASTPrinter` for dumping the `TranslationUnitDecl`. This is where the `-ast-dump-filter` functionality lives in Clang. (cherry picked from commit 0f7e10b)
1 parent 6c2414b commit 88767a3

18 files changed

+131
-32
lines changed

lldb/include/lldb/Symbol/SymbolFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ class SymbolFile : public PluginInterface {
302302
lldb::SymbolContextItem resolve_scope,
303303
SymbolContextList &sc_list);
304304

305-
virtual void DumpClangAST(Stream &s) {}
305+
virtual void DumpClangAST(Stream &s, llvm::StringRef filter) {}
306306
virtual void FindGlobalVariables(ConstString name,
307307
const CompilerDeclContext &parent_decl_ctx,
308308
uint32_t max_matches,

lldb/include/lldb/Symbol/SymbolFileOnDemand.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
127127
lldb_private::SymbolContextList &sc_list) override;
128128

129129
void Dump(lldb_private::Stream &s) override;
130-
void DumpClangAST(lldb_private::Stream &s) override;
130+
void DumpClangAST(lldb_private::Stream &s, llvm::StringRef filter) override;
131131

132132
void
133133
FindGlobalVariables(lldb_private::ConstString name,

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,11 @@ class TypeSystem : public PluginInterface,
482482
/// given stream.
483483
///
484484
/// This should not modify the state of the TypeSystem if possible.
485-
virtual void Dump(llvm::raw_ostream &output) = 0;
485+
///
486+
/// \param[out] output Stream to dup the AST into.
487+
/// \param[in] filter If empty, dump whole AST. If non-empty, will only
488+
/// dump decls whose names contain \c filter.
489+
virtual void Dump(llvm::raw_ostream &output, llvm::StringRef filter) = 0;
486490

487491
/// This is used by swift.
488492
virtual bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) = 0;

lldb/source/Commands/CommandObjectTarget.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,11 +2237,23 @@ class CommandObjectTargetModulesDumpClangAST
22372237
: CommandObjectTargetModulesModuleAutoComplete(
22382238
interpreter, "target modules dump ast",
22392239
"Dump the clang ast for a given module's symbol file.",
2240-
//"target modules dump ast [<file1> ...]")
2241-
nullptr, eCommandRequiresTarget) {}
2240+
"target modules dump ast [--filter <name>] [<file1> ...]",
2241+
eCommandRequiresTarget),
2242+
m_filter(LLDB_OPT_SET_1, false, "filter", 'f', 0, eArgTypeName,
2243+
"Dump only the decls whose names contain the specified filter "
2244+
"string.",
2245+
/*default_value=*/"") {
2246+
m_option_group.Append(&m_filter, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2247+
m_option_group.Finalize();
2248+
}
2249+
2250+
Options *GetOptions() override { return &m_option_group; }
22422251

22432252
~CommandObjectTargetModulesDumpClangAST() override = default;
22442253

2254+
OptionGroupOptions m_option_group;
2255+
OptionGroupString m_filter;
2256+
22452257
protected:
22462258
void DoExecute(Args &command, CommandReturnObject &result) override {
22472259
Target *target = &GetTarget();
@@ -2253,6 +2265,8 @@ class CommandObjectTargetModulesDumpClangAST
22532265
return;
22542266
}
22552267

2268+
llvm::StringRef filter = m_filter.GetOptionValue().GetCurrentValueAsRef();
2269+
22562270
if (command.GetArgumentCount() == 0) {
22572271
// Dump all ASTs for all modules images
22582272
result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
@@ -2261,7 +2275,7 @@ class CommandObjectTargetModulesDumpClangAST
22612275
if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
22622276
break;
22632277
if (SymbolFile *sf = module_sp->GetSymbolFile())
2264-
sf->DumpClangAST(result.GetOutputStream());
2278+
sf->DumpClangAST(result.GetOutputStream(), filter);
22652279
}
22662280
result.SetStatus(eReturnStatusSuccessFinishResult);
22672281
return;
@@ -2290,7 +2304,7 @@ class CommandObjectTargetModulesDumpClangAST
22902304

22912305
Module *m = module_list.GetModulePointerAtIndex(i);
22922306
if (SymbolFile *sf = m->GetSymbolFile())
2293-
sf->DumpClangAST(result.GetOutputStream());
2307+
sf->DumpClangAST(result.GetOutputStream(), filter);
22942308
}
22952309
}
22962310
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -5290,7 +5304,7 @@ class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
52905304
// Go over every scratch TypeSystem and dump to the command output.
52915305
for (lldb::TypeSystemSP ts : GetTarget().GetScratchTypeSystems())
52925306
if (ts)
5293-
ts->Dump(result.GetOutputStream().AsRawOstream());
5307+
ts->Dump(result.GetOutputStream().AsRawOstream(), "");
52945308

52955309
result.SetStatus(eReturnStatusSuccessFinishResult);
52965310
}

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4355,15 +4355,15 @@ void SymbolFileDWARF::Dump(Stream &s) {
43554355
m_index->Dump(s);
43564356
}
43574357

4358-
void SymbolFileDWARF::DumpClangAST(Stream &s) {
4358+
void SymbolFileDWARF::DumpClangAST(Stream &s, llvm::StringRef filter) {
43594359
auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
43604360
if (!ts_or_err)
43614361
return;
43624362
auto ts = *ts_or_err;
43634363
TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
43644364
if (!clang)
43654365
return;
4366-
clang->Dump(s.AsRawOstream());
4366+
clang->Dump(s.AsRawOstream(), filter);
43674367
}
43684368

43694369
bool SymbolFileDWARF::GetSeparateDebugInfo(StructuredData::Dictionary &d,

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ class SymbolFileDWARF : public SymbolFileCommon {
299299

300300
void Dump(Stream &s) override;
301301

302-
void DumpClangAST(Stream &s) override;
302+
void DumpClangAST(Stream &s, llvm::StringRef filter) override;
303303

304304
/// List separate dwo files.
305305
bool GetSeparateDebugInfo(StructuredData::Dictionary &d,

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,9 +1280,9 @@ bool SymbolFileDWARFDebugMap::GetCompileOption(const char *option,
12801280
return success;
12811281
}
12821282

1283-
void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
1283+
void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s, llvm::StringRef filter) {
12841284
ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) {
1285-
oso_dwarf->DumpClangAST(s);
1285+
oso_dwarf.DumpClangAST(s, filter);
12861286
// The underlying assumption is that DumpClangAST(...) will obtain the
12871287
// AST from the underlying TypeSystem and therefore we only need to do
12881288
// this once and can stop after the first iteration hence we return true.

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {
139139
std::vector<lldb::DataBufferSP>
140140
GetASTData(lldb::LanguageType language) override;
141141

142-
void DumpClangAST(Stream &s) override;
142+
void DumpClangAST(Stream &s, llvm::StringRef filter) override;
143143

144144
/// List separate oso files.
145145
bool GetSeparateDebugInfo(StructuredData::Dictionary &d,

lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,6 @@ PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {
14491449
return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext());
14501450
}
14511451

1452-
void PdbAstBuilder::Dump(Stream &stream) {
1453-
m_clang.Dump(stream.AsRawOstream());
1452+
void PdbAstBuilder::Dump(Stream &stream, llvm::StringRef filter) {
1453+
m_clang.Dump(stream.AsRawOstream(), filter);
14541454
}

lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class PdbAstBuilder {
8787
TypeSystemClang &clang() { return m_clang; }
8888
ClangASTImporter &GetClangASTImporter() { return m_importer; }
8989

90-
void Dump(Stream &stream);
90+
void Dump(Stream &stream, llvm::StringRef filter);
9191

9292
private:
9393
clang::Decl *TryGetDecl(PdbSymUid uid) const;

lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,15 +1640,15 @@ size_t SymbolFileNativePDB::ParseSymbolArrayInScope(
16401640
return count;
16411641
}
16421642

1643-
void SymbolFileNativePDB::DumpClangAST(Stream &s) {
1643+
void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter) {
16441644
auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
16451645
if (!ts_or_err)
16461646
return;
16471647
auto ts = *ts_or_err;
16481648
TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
16491649
if (!clang)
16501650
return;
1651-
clang->GetNativePDBParser()->Dump(s);
1651+
clang->GetNativePDBParser()->Dump(s, filter);
16521652
}
16531653

16541654
void SymbolFileNativePDB::FindGlobalVariables(

lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class SymbolFileNativePDB : public SymbolFileCommon {
157157

158158
PdbIndex &GetIndex() { return *m_index; };
159159

160-
void DumpClangAST(Stream &s) override;
160+
void DumpClangAST(Stream &s, llvm::StringRef filter) override;
161161

162162
std::optional<llvm::codeview::TypeIndex>
163163
GetParentType(llvm::codeview::TypeIndex ti);

lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,7 +1446,7 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
14461446
symtab.Finalize();
14471447
}
14481448

1449-
void SymbolFilePDB::DumpClangAST(Stream &s) {
1449+
void SymbolFilePDB::DumpClangAST(Stream &s, llvm::StringRef filter) {
14501450
auto type_system_or_err =
14511451
GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
14521452
if (auto err = type_system_or_err.takeError()) {
@@ -1460,7 +1460,7 @@ void SymbolFilePDB::DumpClangAST(Stream &s) {
14601460
llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
14611461
if (!clang_type_system)
14621462
return;
1463-
clang_type_system->Dump(s.AsRawOstream());
1463+
clang_type_system->Dump(s.AsRawOstream(), filter);
14641464
}
14651465

14661466
void SymbolFilePDB::FindTypesByRegex(

lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class SymbolFilePDB : public lldb_private::SymbolFileCommon {
157157

158158
const llvm::pdb::IPDBSession &GetPDBSession() const;
159159

160-
void DumpClangAST(lldb_private::Stream &s) override;
160+
void DumpClangAST(lldb_private::Stream &s, llvm::StringRef filter) override;
161161

162162
private:
163163
struct SecContribInfo {

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "clang/AST/DeclBase.h"
1212
#include "clang/AST/DeclCXX.h"
1313
#include "clang/AST/ExprCXX.h"
14+
#include "clang/Frontend/ASTConsumers.h"
1415
#include "llvm/ADT/STLForwardCompat.h"
1516
#include "llvm/Support/Casting.h"
1617
#include "llvm/Support/FormatAdapters.h"
@@ -8819,8 +8820,16 @@ TypeSystemClang::dump(lldb::opaque_compiler_type_t type) const {
88198820
}
88208821
#endif
88218822

8822-
void TypeSystemClang::Dump(llvm::raw_ostream &output) {
8823-
GetTranslationUnitDecl()->dump(output);
8823+
void TypeSystemClang::Dump(llvm::raw_ostream &output, llvm::StringRef filter) {
8824+
auto consumer =
8825+
clang::CreateASTDumper(output, filter,
8826+
/*DumpDecls=*/true,
8827+
/*Deserialize=*/false,
8828+
/*DumpLookups=*/false,
8829+
/*DumpDeclTypes=*/false, clang::ADOF_Default);
8830+
assert(consumer);
8831+
assert(m_ast_up);
8832+
consumer->HandleTranslationUnit(*m_ast_up);
88248833
}
88258834

88268835
void TypeSystemClang::DumpFromSymbolFile(Stream &s,
@@ -10029,10 +10038,11 @@ GetNameForIsolatedASTKind(ScratchTypeSystemClang::IsolatedASTKind kind) {
1002910038
llvm_unreachable("Unimplemented IsolatedASTKind?");
1003010039
}
1003110040

10032-
void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output) {
10041+
void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output,
10042+
llvm::StringRef filter) {
1003310043
// First dump the main scratch AST.
1003410044
output << "State of scratch Clang type system:\n";
10035-
TypeSystemClang::Dump(output);
10045+
TypeSystemClang::Dump(output, filter);
1003610046

1003710047
// Now sort the isolated sub-ASTs.
1003810048
typedef std::pair<IsolatedASTKey, TypeSystem *> KeyAndTS;
@@ -10047,7 +10057,7 @@ void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output) {
1004710057
static_cast<ScratchTypeSystemClang::IsolatedASTKind>(a.first);
1004810058
output << "State of scratch Clang type subsystem "
1004910059
<< GetNameForIsolatedASTKind(kind) << ":\n";
10050-
a.second->Dump(output);
10060+
a.second->Dump(output, filter);
1005110061
}
1005210062
}
1005310063

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ class TypeSystemClang : public TypeSystem {
11311131
#endif
11321132

11331133
/// \see lldb_private::TypeSystem::Dump
1134-
void Dump(llvm::raw_ostream &output) override;
1134+
void Dump(llvm::raw_ostream &output, llvm::StringRef filter) override;
11351135

11361136
/// Dump clang AST types from the symbol file.
11371137
///
@@ -1392,7 +1392,7 @@ class ScratchTypeSystemClang : public TypeSystemClang {
13921392
}
13931393

13941394
/// \see lldb_private::TypeSystem::Dump
1395-
void Dump(llvm::raw_ostream &output) override;
1395+
void Dump(llvm::raw_ostream &output, llvm::StringRef filter) override;
13961396

13971397
UserExpression *GetUserExpression(llvm::StringRef expr,
13981398
llvm::StringRef prefix,

lldb/source/Symbol/SymbolFileOnDemand.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,14 @@ void SymbolFileOnDemand::Dump(lldb_private::Stream &s) {
305305
return m_sym_file_impl->Dump(s);
306306
}
307307

308-
void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s) {
308+
void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s,
309+
llvm::StringRef filter) {
309310
if (!m_debug_info_enabled) {
310311
LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
311312
__FUNCTION__);
312313
return;
313314
}
314-
return m_sym_file_impl->DumpClangAST(s);
315+
return m_sym_file_impl->DumpClangAST(s, filter);
315316
}
316317

317318
void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression &regex,
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Test `image dump ast` command.
2+
3+
# RUN: split-file %s %t
4+
# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.out
5+
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
6+
# RUN: | FileCheck %s
7+
8+
#--- main.cpp
9+
10+
void A() {}
11+
void A1() {}
12+
void BA1() {}
13+
void AB() {}
14+
15+
int main() {
16+
A();
17+
A1();
18+
BA1();
19+
AB();
20+
}
21+
22+
#--- commands.input
23+
24+
break set -n main
25+
run
26+
expr A(); A1(); BA1(); AB()
27+
28+
image dump ast
29+
30+
# CHECK: image dump ast
31+
# CHECK-DAG: FunctionDecl {{.*}} main
32+
# CHECK-DAG: FunctionDecl {{.*}} A
33+
# CHECK-DAG: FunctionDecl {{.*}} A1
34+
# CHECK-DAG: FunctionDecl {{.*}} BA1
35+
# CHECK-DAG: FunctionDecl {{.*}} AB
36+
37+
image dump ast --filter A
38+
39+
# CHECK: image dump ast --filter A
40+
# CHECK: Dumping A
41+
# CHECK-NOT: FunctionDecl {{.*}} main
42+
# CHECK-DAG: FunctionDecl {{.*}} A1
43+
# CHECK-DAG: FunctionDecl {{.*}} BA1
44+
# CHECK-DAG: FunctionDecl {{.*}} AB
45+
46+
image dump ast --filter A1
47+
48+
# CHECK: image dump ast --filter A1
49+
# CHECK: Dumping A
50+
# CHECK-NOT: FunctionDecl {{.*}} main
51+
# CHECK-NOT: FunctionDecl {{.*}} AB
52+
# CHECK-DAG: FunctionDecl {{.*}} A1
53+
# CHECK-DAG: FunctionDecl {{.*}} BA1
54+
55+
image dump ast --filter ""
56+
57+
# CHECK: image dump ast --filter ""
58+
# CHECK-DAG: FunctionDecl {{.*}} main
59+
# CHECK-DAG: FunctionDecl {{.*}} AB
60+
# CHECK-DAG: FunctionDecl {{.*}} A1
61+
# CHECK-DAG: FunctionDecl {{.*}} BA1
62+
63+
image dump ast -f AB
64+
65+
# CHECK: image dump ast -f AB
66+
# CHECK: Dumping AB
67+
# CHECK-NOT: FunctionDecl {{.*}} main
68+
# CHECK-NOT: FunctionDecl {{.*}} A1
69+
# CHECK-NOT: FunctionDecl {{.*}} BA1
70+
# CHECK: FunctionDecl {{.*}} AB

0 commit comments

Comments
 (0)