[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`.
This commit is contained in:
parent
d3a70f3b2c
commit
cdbe28887b
@ -3,6 +3,7 @@ class Property<string name, string type> {
|
||||
string Name = name;
|
||||
string Type = type;
|
||||
string Definition;
|
||||
string Path;
|
||||
}
|
||||
|
||||
// Sets the description for the property that should be displayed to the user.
|
||||
|
||||
@ -60,7 +60,9 @@ public:
|
||||
void Apropos(llvm::StringRef keyword,
|
||||
std::vector<const Property *> &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<Property> m_properties;
|
||||
llvm::StringMap<size_t> m_name_to_index;
|
||||
std::string m_expected_path;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
@ -30,7 +30,10 @@ struct PropertyDefinition {
|
||||
const char *description;
|
||||
};
|
||||
|
||||
using PropertyDefinitions = llvm::ArrayRef<PropertyDefinition>;
|
||||
struct PropertyCollectionDefinition {
|
||||
llvm::ArrayRef<PropertyDefinition> definitions;
|
||||
llvm::StringRef expected_path;
|
||||
};
|
||||
|
||||
class Property {
|
||||
public:
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -215,7 +215,7 @@ enum {
|
||||
#ifndef NDEBUG
|
||||
TestingProperties::TestingProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>("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());
|
||||
|
||||
@ -80,7 +80,7 @@ enum {
|
||||
|
||||
ModuleListProperties::ModuleListProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>("symbols");
|
||||
m_collection_sp->Initialize(g_modulelist_properties);
|
||||
m_collection_sp->Initialize(g_modulelist_properties_def);
|
||||
m_collection_sp->SetValueChangedCallback(ePropertySymLinkPaths,
|
||||
[this] { UpdateSymlinkMappings(); });
|
||||
|
||||
|
||||
@ -2019,6 +2019,7 @@ GetDebuggerPropertyForPlugins(Debugger &debugger, llvm::StringRef plugin_type_na
|
||||
if (!plugin_properties_sp && can_create) {
|
||||
plugin_properties_sp =
|
||||
std::make_shared<OptionValueProperties>(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<OptionValueProperties>(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<OptionValueProperties>(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<OptionValueProperties>(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);
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ public:
|
||||
|
||||
DynamicLoaderDarwinKernelProperties() : Properties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_dynamicloaderdarwinkernel_properties);
|
||||
m_collection_sp->Initialize(g_dynamicloaderdarwinkernel_properties_def);
|
||||
}
|
||||
|
||||
~DynamicLoaderDarwinKernelProperties() override = default;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -95,7 +95,7 @@ public:
|
||||
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_jitloadergdb_properties);
|
||||
m_collection_sp->Initialize(g_jitloadergdb_properties_def);
|
||||
}
|
||||
|
||||
EnableJITLoaderGDB GetEnable() const {
|
||||
|
||||
@ -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">,
|
||||
|
||||
@ -2612,7 +2612,7 @@ public:
|
||||
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_language_cplusplus_properties);
|
||||
m_collection_sp->Initialize(g_language_cplusplus_properties_def);
|
||||
}
|
||||
|
||||
FormatEntity::Entry GetFunctionNameFormat() const {
|
||||
|
||||
@ -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}">,
|
||||
|
||||
@ -86,7 +86,7 @@ public:
|
||||
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_objectfilepecoff_properties);
|
||||
m_collection_sp->Initialize(g_objectfilepecoff_properties_def);
|
||||
}
|
||||
|
||||
llvm::Triple::EnvironmentType ABI() const {
|
||||
|
||||
@ -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">,
|
||||
|
||||
@ -45,7 +45,7 @@ public:
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(
|
||||
PlatformAndroid::GetPluginNameStatic(false));
|
||||
m_collection_sp->Initialize(g_android_properties);
|
||||
m_collection_sp->Initialize(g_android_properties_def);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -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<"">,
|
||||
|
||||
@ -135,7 +135,7 @@ public:
|
||||
|
||||
PlatformDarwinProperties() : Properties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_platformdarwin_properties);
|
||||
m_collection_sp->Initialize(g_platformdarwin_properties_def);
|
||||
}
|
||||
|
||||
~PlatformDarwinProperties() override = default;
|
||||
|
||||
@ -196,7 +196,7 @@ public:
|
||||
|
||||
PlatformDarwinKernelProperties() : Properties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_platformdarwinkernel_properties);
|
||||
m_collection_sp->Initialize(g_platformdarwinkernel_properties_def);
|
||||
}
|
||||
|
||||
~PlatformDarwinKernelProperties() override = default;
|
||||
|
||||
@ -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 '|' "
|
||||
|
||||
@ -37,7 +37,7 @@ public:
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(
|
||||
PlatformQemuUser::GetPluginNameStatic());
|
||||
m_collection_sp->Initialize(g_platformqemuuser_properties);
|
||||
m_collection_sp->Initialize(g_platformqemuuser_properties_def);
|
||||
}
|
||||
|
||||
llvm::StringRef GetArchitecture() {
|
||||
|
||||
@ -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<"">,
|
||||
|
||||
@ -41,7 +41,7 @@ public:
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(
|
||||
PlatformWasm::GetPluginNameStatic());
|
||||
m_collection_sp->Initialize(g_platformwasm_properties);
|
||||
m_collection_sp->Initialize(g_platformwasm_properties_def);
|
||||
}
|
||||
|
||||
FileSpec GetRuntimePath() const {
|
||||
|
||||
@ -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<"">,
|
||||
|
||||
@ -70,7 +70,7 @@ public:
|
||||
|
||||
PluginProperties() : Properties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_processkdp_properties);
|
||||
m_collection_sp->Initialize(g_processkdp_properties_def);
|
||||
}
|
||||
|
||||
~PluginProperties() override = default;
|
||||
|
||||
@ -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>,
|
||||
|
||||
@ -146,7 +146,7 @@ public:
|
||||
|
||||
PluginProperties() : Properties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_processgdbremote_properties);
|
||||
m_collection_sp->Initialize(g_processgdbremote_properties_def);
|
||||
}
|
||||
|
||||
~PluginProperties() override = default;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -126,7 +126,7 @@ public:
|
||||
|
||||
StructuredDataDarwinLogProperties() : Properties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_darwinlog_properties);
|
||||
m_collection_sp->Initialize(g_darwinlog_properties_def);
|
||||
}
|
||||
|
||||
~StructuredDataDarwinLogProperties() override = default;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -132,7 +132,7 @@ public:
|
||||
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_symbolfiledwarf_properties);
|
||||
m_collection_sp->Initialize(g_symbolfiledwarf_properties_def);
|
||||
}
|
||||
|
||||
bool IgnoreFileIndexes() const {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -123,7 +123,7 @@ public:
|
||||
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_symbolfilepdb_properties);
|
||||
m_collection_sp->Initialize(g_symbolfilepdb_properties_def);
|
||||
}
|
||||
|
||||
bool UseNativeReader() const {
|
||||
|
||||
@ -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">,
|
||||
|
||||
@ -40,7 +40,7 @@ public:
|
||||
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(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<llvm::StringRef> urls = llvm::getDefaultDebuginfodUrls();
|
||||
|
||||
@ -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.">;
|
||||
|
||||
@ -54,7 +54,7 @@ llvm::StringRef TraceIntelPT::PluginProperties::GetSettingName() {
|
||||
|
||||
TraceIntelPT::PluginProperties::PluginProperties() : Properties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_traceintelpt_properties);
|
||||
m_collection_sp->Initialize(g_traceintelpt_properties_def);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -49,7 +49,7 @@ llvm::StringRef LanguageProperties::GetSettingName() {
|
||||
|
||||
LanguageProperties::LanguageProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_language_properties);
|
||||
m_collection_sp->Initialize(g_language_properties_def);
|
||||
}
|
||||
|
||||
bool LanguageProperties::GetEnableFilterForLineBreakpoints() const {
|
||||
|
||||
@ -79,7 +79,7 @@ llvm::StringRef PlatformProperties::GetSettingName() {
|
||||
|
||||
PlatformProperties::PlatformProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(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)
|
||||
|
||||
@ -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<ProcessOptionValueProperties>("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());
|
||||
|
||||
@ -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<TargetOptionValueProperties>("target");
|
||||
m_collection_sp->Initialize(g_target_properties);
|
||||
m_collection_sp->Initialize(g_target_properties_def);
|
||||
m_experimental_properties_up =
|
||||
std::make_unique<TargetExperimentalProperties>();
|
||||
m_collection_sp->AppendProperty(
|
||||
|
||||
@ -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.">;
|
||||
|
||||
@ -107,7 +107,7 @@ public:
|
||||
ThreadProperties::ThreadProperties(bool is_global) : Properties() {
|
||||
if (is_global) {
|
||||
m_collection_sp = std::make_shared<ThreadOptionValueProperties>("thread");
|
||||
m_collection_sp->Initialize(g_thread_properties);
|
||||
m_collection_sp->Initialize(g_thread_properties_def);
|
||||
} else
|
||||
m_collection_sp =
|
||||
OptionValueProperties::CreateLocalCopy(Thread::GetGlobalProperties());
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "llvm/TableGen/Record.h"
|
||||
#include "llvm/TableGen/StringMatcher.h"
|
||||
#include "llvm/TableGen/TableGenBackend.h"
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
@ -124,6 +125,19 @@ static void emitProperty(const Record *Property, raw_ostream &OS) {
|
||||
OS << "},\n";
|
||||
}
|
||||
|
||||
static std::optional<StringRef>
|
||||
getPropertyPath(const std::vector<const Record *> &PropertyRecords) {
|
||||
std::optional<StringRef> 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<const Record *> &PropertyRecords,
|
||||
@ -133,6 +147,8 @@ static void emityProperties(std::string PropertyName,
|
||||
std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
|
||||
llvm::replace(NeededMacro, ' ', '_');
|
||||
|
||||
std::optional<StringRef> 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";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user