Index: lldb/include/lldb/Core/Module.h =================================================================== --- lldb/include/lldb/Core/Module.h +++ lldb/include/lldb/Core/Module.h @@ -29,6 +29,7 @@ #include "lldb/lldb-types.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Chrono.h" @@ -814,6 +815,8 @@ llvm::Expected GetTypeSystemForLanguage(lldb::LanguageType language); + void ForEachTypeSystem(llvm::function_ref const &callback); + // Special error functions that can do printf style formatting that will // prepend the message with something appropriate for this module (like the // architecture, path and object name (if any)). This centralizes code so Index: lldb/include/lldb/Symbol/TypeSystem.h =================================================================== --- lldb/include/lldb/Symbol/TypeSystem.h +++ lldb/include/lldb/Symbol/TypeSystem.h @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallBitVector.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" +#include "llvm/Support/JSON.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Expression/Expression.h" @@ -508,6 +509,8 @@ // meaningless type itself, instead preferring to use the dynamic type virtual bool IsMeaninglessWithoutDynamicResolution(void *type); + virtual llvm::Optional ReportStatistics(); + protected: SymbolFile *m_sym_file = nullptr; }; Index: lldb/include/lldb/Target/Statistics.h =================================================================== --- lldb/include/lldb/Target/Statistics.h +++ lldb/include/lldb/Target/Statistics.h @@ -12,6 +12,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-forward.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/JSON.h" #include #include @@ -107,6 +108,7 @@ // identifiers of these modules in the global module list. This allows us to // track down all of the stats that contribute to this module. std::vector symfile_modules; + llvm::StringMap type_system_stats; double symtab_parse_time = 0.0; double symtab_index_time = 0.0; double debug_parse_time = 0.0; Index: lldb/source/Core/Module.cpp =================================================================== --- lldb/source/Core/Module.cpp +++ lldb/source/Core/Module.cpp @@ -369,6 +369,11 @@ return m_type_system_map.GetTypeSystemForLanguage(language, this, true); } +void Module::ForEachTypeSystem( + llvm::function_ref const &callback) { + m_type_system_map.ForEach(callback); +} + void Module::ParseAllDebugSymbols() { std::lock_guard guard(m_mutex); size_t num_comp_units = GetNumCompileUnits(); Index: lldb/source/Symbol/TypeSystem.cpp =================================================================== --- lldb/source/Symbol/TypeSystem.cpp +++ lldb/source/Symbol/TypeSystem.cpp @@ -178,6 +178,10 @@ return {}; } +llvm::Optional TypeSystem::ReportStatistics() { + return llvm::None; +} + #pragma mark TypeSystemMap TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {} Index: lldb/source/Target/Statistics.cpp =================================================================== --- lldb/source/Target/Statistics.cpp +++ lldb/source/Target/Statistics.cpp @@ -75,6 +75,17 @@ symfile_ids.emplace_back(symfile_id); module.try_emplace("symbolFileModuleIdentifiers", std::move(symfile_ids)); } + + if (!type_system_stats.empty()) { + json::Array type_systems; + for (const auto &entry : type_system_stats) { + json::Object obj; + obj.try_emplace(entry.first().str(), entry.second); + type_systems.emplace_back(std::move(obj)); + } + module.try_emplace("typeSystemInfo", std::move(type_systems)); + } + return module; } @@ -256,6 +267,11 @@ debug_parse_time += module_stat.debug_parse_time; debug_index_time += module_stat.debug_index_time; debug_info_size += module_stat.debug_info_size; + module->ForEachTypeSystem([&](TypeSystem *ts) { + if (auto stats = ts->ReportStatistics()) + module_stat.type_system_stats.insert({ts->GetPluginName(), *stats}); + return true; + }); json_modules.emplace_back(module_stat.ToJSON()); }