From cdbe28887bc9b4740f990dd5b3d8a86e9b14c131 Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Tue, 10 Feb 2026 19:43:29 +0100 Subject: [PATCH] [LLDB] Set and verify paths of properties from tablegen (#179524) In #168245, I attempted to dump the available settings to Markdown. That required a full build of LLDB. However, to build the docs, only the swig wrappers should need to be compiled. The comment was that we should be able to use the definitions from the TableGen files. Currently, the property definitions in don't have information about the path where they will be available. They only contain a `Definition` which groups properties, so they can be added to `OptionValueProperties`. With this PR, I'm adding the path for each property definition. For example, `symbols.enable-external-lookup` would have `Name = enable-external-lookup, Path = symbols`. In LLDB itself, we don't need this path, we only need it for the documentation. To avoid mismatches between the actual path and the declared one, I added a debug-only check when a property group is added to a parent (`OptionValueProperties::AppendProperty`). The TableGen emitter for the properties now additionally emits `g_{definition}_properties_def`, which includes both the array of properties and the expected path. This constant has to be used to initialize a `OptionValueProperties`. I couldn't test this for everything (e.g. IntelPT or ProcessKDP), but the necessary changes are simple: (1) set the `Path` in the TableGen file, (2) update `initialize` to use `_def`. --- lldb/include/lldb/Core/PropertiesBase.td | 1 + .../lldb/Interpreter/OptionValueProperties.h | 7 +++- lldb/include/lldb/Interpreter/Property.h | 5 ++- lldb/source/Core/CoreProperties.td | 6 +-- lldb/source/Core/Debugger.cpp | 4 +- lldb/source/Core/ModuleList.cpp | 2 +- lldb/source/Core/PluginManager.cpp | 6 +++ .../source/Interpreter/CommandInterpreter.cpp | 2 +- .../Interpreter/InterpreterProperties.td | 2 +- .../Interpreter/OptionValueProperties.cpp | 41 ++++++++++++++++++- .../DynamicLoaderDarwinKernel.cpp | 2 +- .../DynamicLoaderDarwinKernelProperties.td | 2 +- .../Plugins/JITLoader/GDB/JITLoaderGDB.cpp | 2 +- .../JITLoader/GDB/JITLoaderGDBProperties.td | 2 +- .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 2 +- .../CPlusPlus/LanguageCPlusPlusProperties.td | 2 +- .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp | 2 +- .../PECOFF/ObjectFilePECOFFProperties.td | 2 +- .../Platform/Android/PlatformAndroid.cpp | 2 +- .../Android/PlatformAndroidProperties.td | 2 +- .../Platform/MacOSX/PlatformDarwin.cpp | 2 +- .../Platform/MacOSX/PlatformDarwinKernel.cpp | 2 +- .../MacOSX/PlatformMacOSXProperties.td | 4 +- .../Platform/QemuUser/PlatformQemuUser.cpp | 2 +- .../QemuUser/PlatformQemuUserProperties.td | 2 +- .../Platform/WebAssembly/PlatformWasm.cpp | 2 +- .../WebAssembly/PlatformWasmProperties.td | 2 +- .../Process/MacOSX-Kernel/ProcessKDP.cpp | 2 +- .../MacOSX-Kernel/ProcessKDPProperties.td | 2 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 2 +- .../gdb-remote/ProcessGDBRemoteProperties.td | 2 +- .../DarwinLog/StructuredDataDarwinLog.cpp | 2 +- .../StructuredDataDarwinLogProperties.td | 2 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 +- .../DWARF/SymbolFileDWARFProperties.td | 2 +- .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 2 +- .../SymbolFile/PDB/SymbolFilePDBProperties.td | 2 +- .../Debuginfod/SymbolLocatorDebuginfod.cpp | 2 +- .../SymbolLocatorDebuginfodProperties.td | 2 +- .../Plugins/Trace/intel-pt/TraceIntelPT.cpp | 2 +- .../Trace/intel-pt/TraceIntelPTProperties.td | 2 +- lldb/source/Target/Language.cpp | 2 +- lldb/source/Target/Platform.cpp | 2 +- lldb/source/Target/Process.cpp | 4 +- lldb/source/Target/Target.cpp | 4 +- lldb/source/Target/TargetProperties.td | 14 +++---- lldb/source/Target/Thread.cpp | 2 +- .../utils/TableGen/LLDBPropertyDefEmitter.cpp | 24 +++++++++++ 48 files changed, 134 insertions(+), 58 deletions(-) diff --git a/lldb/include/lldb/Core/PropertiesBase.td b/lldb/include/lldb/Core/PropertiesBase.td index 1be3b908ed41..f7767db14042 100644 --- a/lldb/include/lldb/Core/PropertiesBase.td +++ b/lldb/include/lldb/Core/PropertiesBase.td @@ -3,6 +3,7 @@ class Property { string Name = name; string Type = type; string Definition; + string Path; } // Sets the description for the property that should be displayed to the user. diff --git a/lldb/include/lldb/Interpreter/OptionValueProperties.h b/lldb/include/lldb/Interpreter/OptionValueProperties.h index 91a395596237..21da8e584a7b 100644 --- a/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -60,7 +60,9 @@ public: void Apropos(llvm::StringRef keyword, std::vector &matching_properties) const; - void Initialize(const PropertyDefinitions &setting_definitions); + void Initialize(const PropertyCollectionDefinition &setting_definitions); + + void SetExpectedPath(std::string path); // Subclass specific functions @@ -174,9 +176,12 @@ protected: return ((idx < m_properties.size()) ? &m_properties[idx] : nullptr); } + bool VerifyPath(); + std::string m_name; std::vector m_properties; llvm::StringMap m_name_to_index; + std::string m_expected_path; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Interpreter/Property.h b/lldb/include/lldb/Interpreter/Property.h index 09f09358e8af..74da58275dba 100644 --- a/lldb/include/lldb/Interpreter/Property.h +++ b/lldb/include/lldb/Interpreter/Property.h @@ -30,7 +30,10 @@ struct PropertyDefinition { const char *description; }; -using PropertyDefinitions = llvm::ArrayRef; +struct PropertyCollectionDefinition { + llvm::ArrayRef definitions; + llvm::StringRef expected_path; +}; class Property { public: diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index 63efcae3d15d..383834eea22a 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -1,6 +1,6 @@ include "../../include/lldb/Core/PropertiesBase.td" -let Definition = "modulelist" in { +let Definition = "modulelist", Path = "symbols" in { def EnableExternalLookup: Property<"enable-external-lookup", "Boolean">, Global, DefaultTrue, @@ -53,7 +53,7 @@ let Definition = "modulelist" in { } #ifndef NDEBUG -let Definition = "testing" in { +let Definition = "testing", Path = "testing" in { def InjectVarLocListError : Property<"inject-variable-location-error", "Boolean">, Global, @@ -62,7 +62,7 @@ let Definition = "testing" in { } #endif -let Definition = "debugger" in { +let Definition = "debugger", Path = "" in { def AutoConfirm: Property<"auto-confirm", "Boolean">, Global, DefaultFalse, diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index a08744f024d9..00dea7da3497 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -215,7 +215,7 @@ enum { #ifndef NDEBUG TestingProperties::TestingProperties() { m_collection_sp = std::make_shared("testing"); - m_collection_sp->Initialize(g_testing_properties); + m_collection_sp->Initialize(g_testing_properties_def); } bool TestingProperties::GetInjectVarLocListError() const { @@ -1016,7 +1016,7 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) m_forward_listener_sp(), m_clear_once() { // Initialize the debugger properties as early as possible as other parts of // LLDB will start querying them during construction. - m_collection_sp->Initialize(g_debugger_properties); + m_collection_sp->Initialize(g_debugger_properties_def); m_collection_sp->AppendProperty( "target", "Settings specify to debugging targets.", true, Target::GetGlobalProperties().GetValueProperties()); diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index fb4a80740200..845123ce053c 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -80,7 +80,7 @@ enum { ModuleListProperties::ModuleListProperties() { m_collection_sp = std::make_shared("symbols"); - m_collection_sp->Initialize(g_modulelist_properties); + m_collection_sp->Initialize(g_modulelist_properties_def); m_collection_sp->SetValueChangedCallback(ePropertySymLinkPaths, [this] { UpdateSymlinkMappings(); }); diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index 4e3563cf419f..835837e462ed 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -2019,6 +2019,7 @@ GetDebuggerPropertyForPlugins(Debugger &debugger, llvm::StringRef plugin_type_na if (!plugin_properties_sp && can_create) { plugin_properties_sp = std::make_shared(g_property_name); + plugin_properties_sp->SetExpectedPath("plugin"); parent_properties_sp->AppendProperty(g_property_name, "Settings specify to plugins.", true, plugin_properties_sp); @@ -2030,6 +2031,8 @@ GetDebuggerPropertyForPlugins(Debugger &debugger, llvm::StringRef plugin_type_na if (!plugin_type_properties_sp && can_create) { plugin_type_properties_sp = std::make_shared(plugin_type_name); + plugin_type_properties_sp->SetExpectedPath( + ("plugin." + plugin_type_name).str()); plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, true, plugin_type_properties_sp); } @@ -2054,6 +2057,7 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( if (!plugin_properties_sp && can_create) { plugin_properties_sp = std::make_shared(plugin_type_name); + plugin_properties_sp->SetExpectedPath(plugin_type_name.str()); parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, true, plugin_properties_sp); } @@ -2064,6 +2068,8 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( if (!plugin_type_properties_sp && can_create) { plugin_type_properties_sp = std::make_shared(g_property_name); + plugin_type_properties_sp->SetExpectedPath( + (plugin_type_name + ".plugin").str()); plugin_properties_sp->AppendProperty(g_property_name, "Settings specific to plugins", true, plugin_type_properties_sp); diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index fdde65428326..9aed94649263 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -148,7 +148,7 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger, SetEventName(eBroadcastBitQuitCommandReceived, "quit"); SetSynchronous(synchronous_execution); CheckInWithManager(); - m_collection_sp->Initialize(g_interpreter_properties); + m_collection_sp->Initialize(g_interpreter_properties_def); } bool CommandInterpreter::GetExpandRegexAliases() const { diff --git a/lldb/source/Interpreter/InterpreterProperties.td b/lldb/source/Interpreter/InterpreterProperties.td index ffb87ea5e045..c795e66a39e8 100644 --- a/lldb/source/Interpreter/InterpreterProperties.td +++ b/lldb/source/Interpreter/InterpreterProperties.td @@ -1,6 +1,6 @@ include "../../include/lldb/Core/PropertiesBase.td" -let Definition = "interpreter" in { +let Definition = "interpreter", Path = "interpreter" in { def ExpandRegexAliases: Property<"expand-regex-aliases", "Boolean">, Global, DefaultFalse, diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp index cb71bffa8fe2..521de3ddd538 100644 --- a/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/lldb/source/Interpreter/OptionValueProperties.cpp @@ -23,14 +23,21 @@ using namespace lldb_private; OptionValueProperties::OptionValueProperties(llvm::StringRef name) : m_name(name.str()) {} -void OptionValueProperties::Initialize(const PropertyDefinitions &defs) { - for (const auto &definition : defs) { +void OptionValueProperties::Initialize( + const PropertyCollectionDefinition &defs) { + for (const auto &definition : defs.definitions) { Property property(definition); assert(property.IsValid()); m_name_to_index.insert({property.GetName(), m_properties.size()}); property.GetValue()->SetParent(shared_from_this()); m_properties.push_back(property); } + SetExpectedPath(defs.expected_path.str()); +} + +void OptionValueProperties::SetExpectedPath(std::string path) { + assert(m_expected_path.empty() || m_expected_path == path); + m_expected_path = path; } void OptionValueProperties::SetValueChangedCallback( @@ -47,6 +54,15 @@ void OptionValueProperties::AppendProperty(llvm::StringRef name, m_name_to_index.insert({name, m_properties.size()}); m_properties.push_back(property); value_sp->SetParent(shared_from_this()); + +#ifndef NDEBUG + OptionValueProperties *properties = value_sp->GetAsProperties(); + if (properties) { + assert(value_sp->GetName() == name); + assert(properties->VerifyPath() && + "Mismatch between parents from TableGen and actual parents"); + } +#endif } lldb::OptionValueSP @@ -489,3 +505,24 @@ OptionValueProperties::GetSubProperty(const ExecutionContext *exe_ctx, } return lldb::OptionValuePropertiesSP(); } + +bool OptionValueProperties::VerifyPath() { + OptionValueSP parent = GetParent(); + if (!parent) { + // Only the top level value should have an empty path. + return m_expected_path.empty(); + } + OptionValueProperties *parent_properties = parent->GetAsProperties(); + if (!parent_properties) + return false; + + auto [prefix, expected_name] = llvm::StringRef(m_expected_path).rsplit('.'); + + if (expected_name.empty()) { + // There is no dot, so the parent should be the top-level (core properties). + return parent_properties->m_expected_path.empty() && GetName() == prefix; + } + + return parent_properties->m_expected_path == prefix && + GetName() == expected_name; +} diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index 142ebb7d1ca6..f89b0fe6b6db 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -106,7 +106,7 @@ public: DynamicLoaderDarwinKernelProperties() : Properties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_dynamicloaderdarwinkernel_properties); + m_collection_sp->Initialize(g_dynamicloaderdarwinkernel_properties_def); } ~DynamicLoaderDarwinKernelProperties() override = default; diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernelProperties.td b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernelProperties.td index 6c662d737fab..15f87f3ce9f7 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernelProperties.td +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernelProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "dynamicloaderdarwinkernel" in { +let Definition = "dynamicloaderdarwinkernel", Path = "plugin.dynamic-loader.darwin-kernel" in { def LoadKexts: Property<"load-kexts", "Boolean">, Global, DefaultTrue, diff --git a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp index b8e33c6568ea..b336a605b747 100644 --- a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -95,7 +95,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_jitloadergdb_properties); + m_collection_sp->Initialize(g_jitloadergdb_properties_def); } EnableJITLoaderGDB GetEnable() const { diff --git a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td index 0493838bc85d..6f7e5934d5c0 100644 --- a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td +++ b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDBProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "jitloadergdb" in { +let Definition = "jitloadergdb", Path = "plugin.jit-loader.gdb" in { def Enable: Property<"enable", "Enum">, Global, DefaultEnumValue<"eEnableJITLoaderGDBDefault">, diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 58f7d834f46c..7a0f556b3aed 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -2612,7 +2612,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_language_cplusplus_properties); + m_collection_sp->Initialize(g_language_cplusplus_properties_def); } FormatEntity::Entry GetFunctionNameFormat() const { diff --git a/lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td b/lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td index 4d74a040f4de..f9b43ba306b5 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td +++ b/lldb/source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "language_cplusplus" in { +let Definition = "language_cplusplus", Path = "plugin.cplusplus.display" in { def FunctionNameFormat: Property<"function-name-format", "FormatEntity">, Global, DefaultStringValue<"${function.return-left}${function.scope}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.template-arguments}${function.formatted-arguments}${function.return-right}${function.qualifiers}${function.suffix}">, diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index cf2f84677b0f..3a17b4c46a78 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -86,7 +86,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_objectfilepecoff_properties); + m_collection_sp->Initialize(g_objectfilepecoff_properties_def); } llvm::Triple::EnvironmentType ABI() const { diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFFProperties.td b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFFProperties.td index 7655f6dab384..8563e446132c 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFFProperties.td +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFFProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "objectfilepecoff" in { +let Definition = "objectfilepecoff", Path = "plugin.object-file.pe-coff" in { def ABI: Property<"abi", "Enum">, Global, DefaultEnumValue<"llvm::Triple::UnknownEnvironment">, diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp index 22b9711fda48..ce7dad8b0279 100644 --- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -45,7 +45,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared( PlatformAndroid::GetPluginNameStatic(false)); - m_collection_sp->Initialize(g_android_properties); + m_collection_sp->Initialize(g_android_properties_def); } }; diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidProperties.td b/lldb/source/Plugins/Platform/Android/PlatformAndroidProperties.td index bf1bc7b3cef0..b885872d768c 100644 --- a/lldb/source/Plugins/Platform/Android/PlatformAndroidProperties.td +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "android" in { +let Definition = "android", Path = "platform.plugin.remote-android" in { def PlatformPackageName: Property<"package-name", "String">, Global, DefaultStringValue<"">, diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index bfbd85ea3420..3e085e993cad 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -135,7 +135,7 @@ public: PlatformDarwinProperties() : Properties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_platformdarwin_properties); + m_collection_sp->Initialize(g_platformdarwin_properties_def); } ~PlatformDarwinProperties() override = default; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp index 04e87b9dea69..b19ddcc19e58 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp @@ -196,7 +196,7 @@ public: PlatformDarwinKernelProperties() : Properties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_platformdarwinkernel_properties); + m_collection_sp->Initialize(g_platformdarwinkernel_properties_def); } ~PlatformDarwinKernelProperties() override = default; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td index f0d305a63085..89bf4ad812f3 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td @@ -1,12 +1,12 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "platformdarwinkernel" in { +let Definition = "platformdarwinkernel", Path = "platform.plugin.darwin-kernel" in { def KextDirectories: Property<"kext-directories", "FileSpecList">, DefaultStringValue<"">, Desc<"Directories/KDKs to search for kexts in when starting a kernel debug session.">; } -let Definition = "platformdarwin" in { +let Definition = "platformdarwin", Path = "platform.plugin.darwin" in { def IgnoredExceptions: Property<"ignored-exceptions", "String">, DefaultStringValue<"">, Desc<"List the mach exceptions to ignore, separated by '|' " diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp index 105489249673..ea446f67e0fc 100644 --- a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp +++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp @@ -37,7 +37,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared( PlatformQemuUser::GetPluginNameStatic()); - m_collection_sp->Initialize(g_platformqemuuser_properties); + m_collection_sp->Initialize(g_platformqemuuser_properties_def); } llvm::StringRef GetArchitecture() { diff --git a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td index c7ec4bbc6e78..40bf435b20af 100644 --- a/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td +++ b/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUserProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "platformqemuuser" in { +let Definition = "platformqemuuser", Path = "platform.plugin.qemu-user" in { def Architecture: Property<"architecture", "String">, Global, DefaultStringValue<"">, diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp index 30f31cb9ae75..bcc71f83a017 100644 --- a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp +++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasm.cpp @@ -41,7 +41,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared( PlatformWasm::GetPluginNameStatic()); - m_collection_sp->Initialize(g_platformwasm_properties); + m_collection_sp->Initialize(g_platformwasm_properties_def); } FileSpec GetRuntimePath() const { diff --git a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td index 5626372482f1..1f25f1aa8038 100644 --- a/lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td +++ b/lldb/source/Plugins/Platform/WebAssembly/PlatformWasmProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "platformwasm" in { +let Definition = "platformwasm", Path = "platform.plugin.wasm" in { def RuntimePath : Property<"runtime-path", "FileSpec">, Global, DefaultStringValue<"">, diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 3c26afa3d486..471beb4f0b9b 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -70,7 +70,7 @@ public: PluginProperties() : Properties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_processkdp_properties); + m_collection_sp->Initialize(g_processkdp_properties_def); } ~PluginProperties() override = default; diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPProperties.td b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPProperties.td index 0063bdbec004..ec89f3cec0ce 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPProperties.td +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "processkdp" in { +let Definition = "processkdp", Parent = "plugin.process.kdp" in { def KDPPacketTimeout: Property<"packet-timeout", "UInt64">, Global, DefaultUnsignedValue<5>, diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 6234973accf4..767684e01ee3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -146,7 +146,7 @@ public: PluginProperties() : Properties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_processgdbremote_properties); + m_collection_sp->Initialize(g_processgdbremote_properties_def); } ~PluginProperties() override = default; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td index 520dad062e09..08dee3089a09 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "processgdbremote" in { +let Definition = "processgdbremote", Path = "plugin.process.gdb-remote" in { def PacketTimeout: Property<"packet-timeout", "UInt64">, Global, #ifdef LLDB_SANITIZED diff --git a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp index 70093c9624f0..130bff7a99f3 100644 --- a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp +++ b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp @@ -126,7 +126,7 @@ public: StructuredDataDarwinLogProperties() : Properties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_darwinlog_properties); + m_collection_sp->Initialize(g_darwinlog_properties_def); } ~StructuredDataDarwinLogProperties() override = default; diff --git a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td index 5c22158542f9..5e3ed81c270a 100644 --- a/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td +++ b/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLogProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "darwinlog" in { +let Definition = "darwinlog", Path = "plugin.structured-data.darwin-log" in { def EnableOnStartup: Property<"enable-on-startup", "Boolean">, Global, DefaultFalse, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 3a790afb1458..0326f0698182 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -132,7 +132,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_symbolfiledwarf_properties); + m_collection_sp->Initialize(g_symbolfiledwarf_properties_def); } bool IgnoreFileIndexes() const { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td index 2f1ce88808b7..cba39a73aa01 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "symbolfiledwarf" in { +let Definition = "symbolfiledwarf", Path = "plugin.symbol-file.dwarf" in { def IgnoreIndexes: Property<"ignore-file-indexes", "Boolean">, Global, DefaultFalse, diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 97c995fc9b22..e35195fec2ef 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -123,7 +123,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_symbolfilepdb_properties); + m_collection_sp->Initialize(g_symbolfilepdb_properties_def); } bool UseNativeReader() const { diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td index 329b495e8f04..10fa1619aec9 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDBProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "symbolfilepdb" in { +let Definition = "symbolfilepdb", Path = "plugin.symbol-file.pdb" in { def Reader: Property<"reader", "Enum">, Global, DefaultEnumValue<"ePDBReaderDefault">, diff --git a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp index b775ec98c9a1..a09bb356e3a8 100644 --- a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp +++ b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp @@ -40,7 +40,7 @@ public: PluginProperties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_symbollocatordebuginfod_properties); + m_collection_sp->Initialize(g_symbollocatordebuginfod_properties_def); // We need to read the default value first to read the environment variable. llvm::SmallVector urls = llvm::getDefaultDebuginfodUrls(); diff --git a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfodProperties.td b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfodProperties.td index 0ff02674b8ea..a7bcec44d069 100644 --- a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfodProperties.td +++ b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfodProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "symbollocatordebuginfod" in { +let Definition = "symbollocatordebuginfod", Path = "plugin.symbol-locator.debuginfod" in { def ServerURLs : Property<"server-urls", "Array">, ElementType<"String">, Desc<"An ordered list of Debuginfod server URLs to query for symbols. This defaults to the contents of the DEBUGINFOD_URLS environment variable.">; diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp index 72e9948ffe81..740af59d0c1a 100644 --- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp +++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp @@ -54,7 +54,7 @@ llvm::StringRef TraceIntelPT::PluginProperties::GetSettingName() { TraceIntelPT::PluginProperties::PluginProperties() : Properties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_traceintelpt_properties); + m_collection_sp->Initialize(g_traceintelpt_properties_def); } uint64_t diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td index d338df1df5cb..96eb3397f66d 100644 --- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td +++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTProperties.td @@ -1,6 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" -let Definition = "traceintelpt" in { +let Definition = "traceintelpt", Parent = "plugin.trace.intel-pt" in { def InfiniteDecodingLoopVerificationThreshold: Property<"infinite-decoding-loop-verification-threshold", "UInt64">, Global, diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp index c8b09c32ac08..d22e58b0a6a9 100644 --- a/lldb/source/Target/Language.cpp +++ b/lldb/source/Target/Language.cpp @@ -49,7 +49,7 @@ llvm::StringRef LanguageProperties::GetSettingName() { LanguageProperties::LanguageProperties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_language_properties); + m_collection_sp->Initialize(g_language_properties_def); } bool LanguageProperties::GetEnableFilterForLineBreakpoints() const { diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index bf9e2f2c2b2f..4068210cc163 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -79,7 +79,7 @@ llvm::StringRef PlatformProperties::GetSettingName() { PlatformProperties::PlatformProperties() { m_collection_sp = std::make_shared(GetSettingName()); - m_collection_sp->Initialize(g_platform_properties); + m_collection_sp->Initialize(g_platform_properties_def); auto module_cache_dir = GetModuleCacheDirectory(); if (module_cache_dir) diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 0cd46f2fc740..67978d3efe72 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -147,7 +147,7 @@ public: ProcessExperimentalProperties::ProcessExperimentalProperties() : Properties(OptionValuePropertiesSP( new ProcessExperimentalOptionValueProperties())) { - m_collection_sp->Initialize(g_process_experimental_properties); + m_collection_sp->Initialize(g_process_experimental_properties_def); } ProcessProperties::ProcessProperties(lldb_private::Process *process) @@ -157,7 +157,7 @@ ProcessProperties::ProcessProperties(lldb_private::Process *process) if (process == nullptr) { // Global process properties, set them up one time m_collection_sp = std::make_shared("process"); - m_collection_sp->Initialize(g_process_properties); + m_collection_sp->Initialize(g_process_properties_def); m_collection_sp->AppendProperty( "thread", "Settings specific to threads.", true, Thread::GetGlobalProperties().GetValueProperties()); diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 787e66bfaf7a..07c3653782c6 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -4460,7 +4460,7 @@ public: TargetExperimentalProperties::TargetExperimentalProperties() : Properties(OptionValuePropertiesSP( new TargetExperimentalOptionValueProperties())) { - m_collection_sp->Initialize(g_target_experimental_properties); + m_collection_sp->Initialize(g_target_experimental_properties_def); } // TargetProperties @@ -4509,7 +4509,7 @@ TargetProperties::TargetProperties(Target *target) true, m_experimental_properties_up->GetValueProperties()); } else { m_collection_sp = std::make_shared("target"); - m_collection_sp->Initialize(g_target_properties); + m_collection_sp->Initialize(g_target_properties_def); m_experimental_properties_up = std::make_unique(); m_collection_sp->AppendProperty( diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td index b8ac3660fb2d..2361314d506a 100644 --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -1,6 +1,6 @@ include "../../include/lldb/Core/PropertiesBase.td" -let Definition = "target_experimental" in { +let Definition = "target_experimental", Path = "target.experimental" in { def InjectLocalVars : Property<"inject-local-vars", "Boolean">, Global, DefaultTrue, Desc<"If true, inject local variables explicitly into the expression text. This will fix symbol resolution when there are name collisions between ivars and local variables. But it can make expressions run much more slowly.">; @@ -9,7 +9,7 @@ let Definition = "target_experimental" in { Desc<"If true, use the DIL implementation for frame variable evaluation.">; } -let Definition = "target" in { +let Definition = "target", Path = "target" in { def DefaultArch: Property<"default-arch", "Arch">, Global, DefaultStringValue<"">, @@ -222,14 +222,14 @@ let Definition = "target" in { Desc<"Enable loading of modules in parallel for the dynamic loader.">; } -let Definition = "process_experimental" in { +let Definition = "process_experimental", Path = "target.process.experimental" in { def OSPluginReportsAllThreads: Property<"os-plugin-reports-all-threads", "Boolean">, Global, DefaultTrue, Desc<"Set to False if your Python OS Plugin doesn't report all threads on each stop.">; } -let Definition = "process" in { +let Definition = "process", Path = "target.process" in { def DisableMemCache: Property<"disable-memory-cache", "Boolean">, DefaultFalse, Desc<"Disable reading and caching of memory in fixed-size units.">; @@ -304,7 +304,7 @@ let Definition = "process" in { Desc<"If true, memory cache modifications (which happen often during expressions evaluation) will bump process state ID (and invalidate all synthetic children). Disabling this option helps to avoid synthetic children reevaluation when pretty printers heavily use expressions. The downside of disabled setting is that convenience variables won't reevaluate synthetic children automatically.">; } -let Definition = "platform" in { +let Definition = "platform", Path = "platform" in { def UseModuleCache: Property<"use-module-cache", "Boolean">, Global, DefaultTrue, @@ -315,7 +315,7 @@ let Definition = "platform" in { Desc<"Root directory for cached modules.">; } -let Definition = "thread" in { +let Definition = "thread", Path = "target.process.thread" in { def StepInAvoidsNoDebug: Property<"step-in-avoid-nodebug", "Boolean">, Global, DefaultTrue, @@ -344,7 +344,7 @@ let Definition = "thread" in { Desc<"The time in milliseconds to wait for single thread ThreadPlan to move forward before resuming all threads to resolve any potential deadlock. Specify value 0 to disable timeout.">; } -let Definition = "language" in { +let Definition = "language", Path = "language" in { def EnableFilterForLineBreakpoints: Property<"enable-filter-for-line-breakpoints", "Boolean">, DefaultTrue, Desc<"If true, allow Language plugins to filter locations when setting breakpoints by line number or regex.">; diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 2c95c2d209b4..44b664ac70d2 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -107,7 +107,7 @@ public: ThreadProperties::ThreadProperties(bool is_global) : Properties() { if (is_global) { m_collection_sp = std::make_shared("thread"); - m_collection_sp->Initialize(g_thread_properties); + m_collection_sp->Initialize(g_thread_properties_def); } else m_collection_sp = OptionValueProperties::CreateLocalCopy(Thread::GetGlobalProperties()); diff --git a/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp b/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp index 1d4495f9281b..e713dc790a49 100644 --- a/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp +++ b/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp @@ -16,6 +16,7 @@ #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" #include "llvm/TableGen/TableGenBackend.h" +#include #include using namespace llvm; @@ -124,6 +125,19 @@ static void emitProperty(const Record *Property, raw_ostream &OS) { OS << "},\n"; } +static std::optional +getPropertyPath(const std::vector &PropertyRecords) { + std::optional Path; + for (const Record *R : PropertyRecords) { + StringRef P = R->getValueAsString("Path"); + if (!Path) + Path.emplace(P); + assert(*Path == P && + "All records with one definition should have the same path"); + } + return Path; +} + /// Emits all property initializers to the raw_ostream. static void emityProperties(std::string PropertyName, const std::vector &PropertyRecords, @@ -133,6 +147,8 @@ static void emityProperties(std::string PropertyName, std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName; llvm::replace(NeededMacro, ' ', '_'); + std::optional Path = getPropertyPath(PropertyRecords); + // All options are in one file, so we need put them behind macros and ask the // user to define the macro for the options that are needed. OS << "// Property definitions for " << PropertyName << "\n"; @@ -142,6 +158,14 @@ static void emityProperties(std::string PropertyName, for (const Record *R : PropertyRecords) emitProperty(R, OS); OS << "};\n"; + + OS << "static constexpr PropertyCollectionDefinition g_" << PropertyName + << "_properties_def = {\n"; + OS << "/*properties=*/g_" << PropertyName << "_properties,\n"; + if (Path) + OS << "/*expected_path=*/\"" << *Path << "\",\n"; + OS << "};\n"; + // We undefine the macro for the user like Clang's include files are doing it. OS << "#undef " << NeededMacro << "\n"; OS << "#endif // " << PropertyName << " Property\n\n";