diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index ff67e002e5b02..3b4d7bc01d132 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -297,7 +297,8 @@ class SymbolFile : public PluginInterface { lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); - virtual void DumpClangAST(Stream &s, llvm::StringRef filter) {} + virtual void DumpClangAST(Stream &s, llvm::StringRef filter, + bool show_colors) {} virtual void FindGlobalVariables(ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h index 6e3c2477d1769..b376de73419d4 100644 --- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h +++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -127,7 +127,8 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile { lldb_private::SymbolContextList &sc_list) override; void Dump(lldb_private::Stream &s) override; - void DumpClangAST(lldb_private::Stream &s, llvm::StringRef filter) override; + void DumpClangAST(lldb_private::Stream &s, llvm::StringRef filter, + bool show_color) override; void FindGlobalVariables(lldb_private::ConstString name, diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index 16a2e0b5a52fb..0ec3a28898329 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -448,7 +448,9 @@ class TypeSystem : public PluginInterface, /// \param[out] output Stream to dup the AST into. /// \param[in] filter If empty, dump whole AST. If non-empty, will only /// dump decls whose names contain \c filter. - virtual void Dump(llvm::raw_ostream &output, llvm::StringRef filter) = 0; + /// \param[in] show_color If true, prints the AST color-highlighted. + virtual void Dump(llvm::raw_ostream &output, llvm::StringRef filter, + bool show_color) = 0; /// This is used by swift. virtual bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) = 0; diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 004542e3e6aed..0f96fa92a731d 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -2275,7 +2275,8 @@ class CommandObjectTargetModulesDumpClangAST if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast")) break; if (SymbolFile *sf = module_sp->GetSymbolFile()) - sf->DumpClangAST(result.GetOutputStream(), filter); + sf->DumpClangAST(result.GetOutputStream(), filter, + GetCommandInterpreter().GetDebugger().GetUseColor()); } result.SetStatus(eReturnStatusSuccessFinishResult); return; @@ -2304,7 +2305,8 @@ class CommandObjectTargetModulesDumpClangAST Module *m = module_list.GetModulePointerAtIndex(i); if (SymbolFile *sf = m->GetSymbolFile()) - sf->DumpClangAST(result.GetOutputStream(), filter); + sf->DumpClangAST(result.GetOutputStream(), filter, + GetCommandInterpreter().GetDebugger().GetUseColor()); } } result.SetStatus(eReturnStatusSuccessFinishResult); @@ -5294,7 +5296,8 @@ class CommandObjectTargetDumpTypesystem : public CommandObjectParsed { // Go over every scratch TypeSystem and dump to the command output. for (lldb::TypeSystemSP ts : GetTarget().GetScratchTypeSystems()) if (ts) - ts->Dump(result.GetOutputStream().AsRawOstream(), ""); + ts->Dump(result.GetOutputStream().AsRawOstream(), "", + GetCommandInterpreter().GetDebugger().GetUseColor()); result.SetStatus(eReturnStatusSuccessFinishResult); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index d3d0110d5e302..5801fa97bf753 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -4325,7 +4325,8 @@ void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); } -void SymbolFileDWARF::DumpClangAST(Stream &s, llvm::StringRef filter) { +void SymbolFileDWARF::DumpClangAST(Stream &s, llvm::StringRef filter, + bool show_color) { auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); if (!ts_or_err) return; @@ -4333,7 +4334,7 @@ void SymbolFileDWARF::DumpClangAST(Stream &s, llvm::StringRef filter) { TypeSystemClang *clang = llvm::dyn_cast_or_null(ts.get()); if (!clang) return; - clang->Dump(s.AsRawOstream(), filter); + clang->Dump(s.AsRawOstream(), filter, show_color); } bool SymbolFileDWARF::GetSeparateDebugInfo(StructuredData::Dictionary &d, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 85306d8b4fb5f..a60527b8eda33 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -277,7 +277,8 @@ class SymbolFileDWARF : public SymbolFileCommon { void Dump(Stream &s) override; - void DumpClangAST(Stream &s, llvm::StringRef filter) override; + void DumpClangAST(Stream &s, llvm::StringRef filter, + bool show_colors) override; /// List separate dwo files. bool GetSeparateDebugInfo(StructuredData::Dictionary &d, bool errors_only, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 8b8229a7020c5..a44bf82d3b705 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1267,9 +1267,10 @@ CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( return matching_namespace; } -void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s, llvm::StringRef filter) { +void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s, llvm::StringRef filter, + bool show_color) { ForEachSymbolFile("Dumping clang AST", [&](SymbolFileDWARF &oso_dwarf) { - oso_dwarf.DumpClangAST(s, filter); + oso_dwarf.DumpClangAST(s, filter, show_color); // The underlying assumption is that DumpClangAST(...) will obtain the // AST from the underlying TypeSystem and therefore we only need to do // this once and can stop after the first iteration hence we return true. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index bce1ed2671af0..74b97f610f29c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -129,7 +129,8 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon { std::vector> ParseCallEdgesInFunction(UserID func_id) override; - void DumpClangAST(Stream &s, llvm::StringRef filter) override; + void DumpClangAST(Stream &s, llvm::StringRef filter, + bool show_color) override; /// List separate oso files. bool GetSeparateDebugInfo(StructuredData::Dictionary &d, bool errors_only, diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 933c4361d93da..51bdcc92b05a8 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -1454,8 +1454,9 @@ PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) { return static_cast(context.GetOpaqueDeclContext()); } -void PdbAstBuilder::Dump(Stream &stream, llvm::StringRef filter) { - m_clang.Dump(stream.AsRawOstream(), filter); +void PdbAstBuilder::Dump(Stream &stream, llvm::StringRef filter, + bool show_color) { + m_clang.Dump(stream.AsRawOstream(), filter, show_color); } clang::NamespaceDecl * diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h index fef65227bc8f5..16247fcf88b12 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -87,7 +87,7 @@ class PdbAstBuilder { TypeSystemClang &clang() { return m_clang; } ClangASTImporter &GetClangASTImporter() { return m_importer; } - void Dump(Stream &stream, llvm::StringRef filter); + void Dump(Stream &stream, llvm::StringRef filter, bool show_color); clang::NamespaceDecl *FindNamespaceDecl(const clang::DeclContext *parent, llvm::StringRef name); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index cfecda4817976..b866e473853f3 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1683,7 +1683,8 @@ size_t SymbolFileNativePDB::ParseSymbolArrayInScope( return count; } -void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter) { +void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter, + bool show_color) { auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); if (!ts_or_err) return; @@ -1691,7 +1692,7 @@ void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter) { TypeSystemClang *clang = llvm::dyn_cast_or_null(ts.get()); if (!clang) return; - clang->GetNativePDBParser()->Dump(s, filter); + clang->GetNativePDBParser()->Dump(s, filter, show_color); } void SymbolFileNativePDB::CacheGlobalBaseNames() { diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 095b40c72c52a..2405f8b299339 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -157,7 +157,8 @@ class SymbolFileNativePDB : public SymbolFileCommon { PdbIndex &GetIndex() { return *m_index; }; - void DumpClangAST(Stream &s, llvm::StringRef filter) override; + void DumpClangAST(Stream &s, llvm::StringRef filter, + bool show_color) override; std::optional GetParentType(llvm::codeview::TypeIndex ti); diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 2f0b6539445fb..0e2ca1784e7e9 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1515,7 +1515,8 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { symtab.Finalize(); } -void SymbolFilePDB::DumpClangAST(Stream &s, llvm::StringRef filter) { +void SymbolFilePDB::DumpClangAST(Stream &s, llvm::StringRef filter, + bool show_color) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { @@ -1529,7 +1530,7 @@ void SymbolFilePDB::DumpClangAST(Stream &s, llvm::StringRef filter) { llvm::dyn_cast_or_null(ts.get()); if (!clang_type_system) return; - clang_type_system->Dump(s.AsRawOstream(), filter); + clang_type_system->Dump(s.AsRawOstream(), filter, show_color); } void SymbolFilePDB::FindTypesByRegex( diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index e6560813ce75e..ccbf02db1159f 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -159,7 +159,8 @@ class SymbolFilePDB : public lldb_private::SymbolFileCommon { const llvm::pdb::IPDBSession &GetPDBSession() const; - void DumpClangAST(lldb_private::Stream &s, llvm::StringRef filter) override; + void DumpClangAST(lldb_private::Stream &s, llvm::StringRef filter, + bool show_color) override; private: struct SecContribInfo { diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 39aacdb58e694..406ac07092ce1 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -11,6 +11,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/ExprCXX.h" #include "clang/Frontend/ASTConsumers.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Casting.h" #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" @@ -8540,7 +8541,24 @@ TypeSystemClang::dump(lldb::opaque_compiler_type_t type) const { } #endif -void TypeSystemClang::Dump(llvm::raw_ostream &output, llvm::StringRef filter) { +namespace { +struct ScopedASTColor { + ScopedASTColor(clang::ASTContext &ast, bool show_colors) + : ast(ast), old_show_colors(ast.getDiagnostics().getShowColors()) { + ast.getDiagnostics().setShowColors(show_colors); + } + + ~ScopedASTColor() { ast.getDiagnostics().setShowColors(old_show_colors); } + + clang::ASTContext * + const bool old_show_colors; +}; +} // namespace + +void TypeSystemClang::Dump(llvm::raw_ostream &output, llvm::StringRef filter, + bool show_color) { + ScopedASTColor colored(getASTContext(), show_color); + auto consumer = clang::CreateASTDumper(output, filter, /*DumpDecls=*/true, @@ -9683,10 +9701,10 @@ GetNameForIsolatedASTKind(ScratchTypeSystemClang::IsolatedASTKind kind) { } void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output, - llvm::StringRef filter) { + llvm::StringRef filter, bool show_color) { // First dump the main scratch AST. output << "State of scratch Clang type system:\n"; - TypeSystemClang::Dump(output, filter); + TypeSystemClang::Dump(output, filter, show_color); // Now sort the isolated sub-ASTs. typedef std::pair KeyAndTS; @@ -9701,7 +9719,7 @@ void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output, static_cast(a.first); output << "State of scratch Clang type subsystem " << GetNameForIsolatedASTKind(kind) << ":\n"; - a.second->Dump(output, filter); + a.second->Dump(output, filter, show_color); } } diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 709f89590ba3b..9e0a54209345d 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -1074,7 +1074,8 @@ class TypeSystemClang : public TypeSystem { #endif /// \see lldb_private::TypeSystem::Dump - void Dump(llvm::raw_ostream &output, llvm::StringRef filter) override; + void Dump(llvm::raw_ostream &output, llvm::StringRef filter, + bool show_color) override; /// Dump clang AST types from the symbol file. /// @@ -1318,7 +1319,8 @@ class ScratchTypeSystemClang : public TypeSystemClang { } /// \see lldb_private::TypeSystem::Dump - void Dump(llvm::raw_ostream &output, llvm::StringRef filter) override; + void Dump(llvm::raw_ostream &output, llvm::StringRef filter, + bool show_color) override; UserExpression *GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, diff --git a/lldb/source/Symbol/SymbolFileOnDemand.cpp b/lldb/source/Symbol/SymbolFileOnDemand.cpp index 807c2124e48d9..9fc13c5989fc2 100644 --- a/lldb/source/Symbol/SymbolFileOnDemand.cpp +++ b/lldb/source/Symbol/SymbolFileOnDemand.cpp @@ -306,13 +306,13 @@ void SymbolFileOnDemand::Dump(lldb_private::Stream &s) { } void SymbolFileOnDemand::DumpClangAST(lldb_private::Stream &s, - llvm::StringRef filter) { + llvm::StringRef filter, bool show_color) { if (!m_debug_info_enabled) { LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(), __FUNCTION__); return; } - return m_sym_file_impl->DumpClangAST(s, filter); + return m_sym_file_impl->DumpClangAST(s, filter, show_color); } void SymbolFileOnDemand::FindGlobalVariables(const RegularExpression ®ex, diff --git a/lldb/test/Shell/Commands/command-image-dump-ast-colored.test b/lldb/test/Shell/Commands/command-image-dump-ast-colored.test new file mode 100644 index 0000000000000..355ef6bb1d199 --- /dev/null +++ b/lldb/test/Shell/Commands/command-image-dump-ast-colored.test @@ -0,0 +1,34 @@ +# Test AST dumping with and without color. + +# RUN: split-file %s %t +# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.out +# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \ +# RUN: | FileCheck %s + +#--- main.cpp + +int main() {} + +#--- commands.input + +settings set use-color true + +target modules dump ast + +# CHECK: target modules dump ast +# CHECK: TranslationUnitDecl +# CHECK-SAME:  + +target dump typesystem + +# CHECK: target dump typesystem +# CHECK: TranslationUnitDecl +# CHECK-SAME:  + +settings set use-color false + +target modules dump ast +target dump typesystem + +# CHECK: settings set use-color false +# CHECK-NOT: