| //===-- OptionValueProperties.cpp ---------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "lldb/Interpreter/OptionValueProperties.h" |
| |
| // C Includes |
| // C++ Includes |
| // Other libraries and framework includes |
| // Project includes |
| #include "lldb/Core/Flags.h" |
| #include "lldb/Core/Stream.h" |
| #include "lldb/Core/StringList.h" |
| #include "lldb/Core/UserSettingsController.h" |
| #include "lldb/Interpreter/Args.h" |
| #include "lldb/Interpreter/OptionValues.h" |
| #include "lldb/Interpreter/Property.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| |
| OptionValueProperties::OptionValueProperties (const ConstString &name) : |
| OptionValue (), |
| m_name (name), |
| m_properties (), |
| m_name_to_index () |
| { |
| } |
| |
| OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) : |
| OptionValue (global_properties), |
| std::enable_shared_from_this<OptionValueProperties> (), |
| m_name (global_properties.m_name), |
| m_properties (global_properties.m_properties), |
| m_name_to_index (global_properties.m_name_to_index) |
| { |
| // We now have an exact copy of "global_properties". We need to now |
| // find all non-global settings and copy the property values so that |
| // all non-global settings get new OptionValue instances created for |
| // them. |
| const size_t num_properties = m_properties.size(); |
| for (size_t i=0; i<num_properties; ++i) |
| { |
| // Duplicate any values that are not global when constructing properties from |
| // a global copy |
| if (m_properties[i].IsGlobal() == false) |
| { |
| lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy()); |
| m_properties[i].SetOptionValue(new_value_sp); |
| } |
| } |
| } |
| |
| |
| |
| size_t |
| OptionValueProperties::GetNumProperties() const |
| { |
| return m_properties.size(); |
| } |
| |
| |
| void |
| OptionValueProperties::Initialize (const PropertyDefinition *defs) |
| { |
| for (size_t i=0; defs[i].name; ++i) |
| { |
| Property property(defs[i]); |
| assert(property.IsValid()); |
| m_name_to_index.Append(property.GetName().GetCString(),m_properties.size()); |
| property.GetValue()->SetParent(shared_from_this()); |
| m_properties.push_back(property); |
| } |
| m_name_to_index.Sort(); |
| } |
| |
| void |
| OptionValueProperties::AppendProperty(const ConstString &name, |
| const ConstString &desc, |
| bool is_global, |
| const OptionValueSP &value_sp) |
| { |
| Property property(name, desc, is_global, value_sp); |
| m_name_to_index.Append(name.GetCString(),m_properties.size()); |
| m_properties.push_back(property); |
| value_sp->SetParent (shared_from_this()); |
| m_name_to_index.Sort(); |
| } |
| |
| |
| |
| //bool |
| //OptionValueProperties::GetQualifiedName (Stream &strm) |
| //{ |
| // bool dumped_something = false; |
| //// lldb::OptionValuePropertiesSP parent_sp(GetParent ()); |
| //// if (parent_sp) |
| //// { |
| //// parent_sp->GetQualifiedName (strm); |
| //// strm.PutChar('.'); |
| //// dumped_something = true; |
| //// } |
| // if (m_name) |
| // { |
| // strm << m_name; |
| // dumped_something = true; |
| // } |
| // return dumped_something; |
| //} |
| // |
| lldb::OptionValueSP |
| OptionValueProperties::GetValueForKey (const ExecutionContext *exe_ctx, |
| const ConstString &key, |
| bool will_modify) const |
| { |
| lldb::OptionValueSP value_sp; |
| size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX); |
| if (idx < m_properties.size()) |
| value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue(); |
| return value_sp; |
| } |
| |
| lldb::OptionValueSP |
| OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx, |
| const char *name, |
| bool will_modify, |
| Error &error) const |
| { |
| lldb::OptionValueSP value_sp; |
| |
| if (name && name[0]) |
| { |
| const char *sub_name = nullptr; |
| ConstString key; |
| size_t key_len = ::strcspn (name, ".[{"); |
| |
| if (name[key_len]) |
| { |
| key.SetCStringWithLength (name, key_len); |
| sub_name = name + key_len; |
| } |
| else |
| key.SetCString (name); |
| |
| value_sp = GetValueForKey (exe_ctx, key, will_modify); |
| if (sub_name && value_sp) |
| { |
| switch (sub_name[0]) |
| { |
| case '.': |
| return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error); |
| |
| case '{': |
| // Predicate matching for predicates like |
| // "<setting-name>{<predicate>}" |
| // strings are parsed by the current OptionValueProperties subclass |
| // to mean whatever they want to. For instance a subclass of |
| // OptionValueProperties for a lldb_private::Target might implement: |
| // "target.run-args{arch==i386}" -- only set run args if the arch is i386 |
| // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches |
| // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if executable basename is "test" and arch is "x86_64" |
| if (sub_name[1]) |
| { |
| const char *predicate_start = sub_name + 1; |
| const char *predicate_end = strchr(predicate_start, '}'); |
| if (predicate_end) |
| { |
| std::string predicate(predicate_start, predicate_end); |
| if (PredicateMatches(exe_ctx, predicate.c_str())) |
| { |
| if (predicate_end[1]) |
| { |
| // Still more subvalue string to evaluate |
| return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error); |
| } |
| else |
| { |
| // We have a match! |
| break; |
| } |
| } |
| } |
| } |
| // Predicate didn't match or wasn't correctly formed |
| value_sp.reset(); |
| break; |
| |
| case '[': |
| // Array or dictionary access for subvalues like: |
| // "[12]" -- access 12th array element |
| // "['hello']" -- dictionary access of key named hello |
| return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error); |
| |
| default: |
| value_sp.reset(); |
| break; |
| } |
| } |
| } |
| return value_sp; |
| } |
| |
| Error |
| OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx, |
| VarSetOperationType op, |
| const char *name, |
| const char *value) |
| { |
| Error error; |
| const bool will_modify = true; |
| lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error)); |
| if (value_sp) |
| error = value_sp->SetValueFromCString(value, op); |
| else |
| { |
| if (error.AsCString() == nullptr) |
| error.SetErrorStringWithFormat("invalid value path '%s'", name); |
| } |
| return error; |
| } |
| |
| |
| ConstString |
| OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const |
| { |
| const Property *property = GetPropertyAtIndex(nullptr, false, idx); |
| if (property) |
| return property->GetName(); |
| return ConstString(); |
| |
| } |
| |
| const char * |
| OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const |
| { |
| const Property *property = GetPropertyAtIndex(nullptr, false, idx); |
| if (property) |
| return property->GetDescription(); |
| return nullptr; |
| } |
| |
| uint32_t |
| OptionValueProperties::GetPropertyIndex (const ConstString &name) const |
| { |
| return m_name_to_index.Find (name.GetCString(), SIZE_MAX); |
| } |
| |
| const Property * |
| OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const |
| { |
| return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX)); |
| } |
| |
| const Property * |
| OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const |
| { |
| return ProtectedGetPropertyAtIndex (idx); |
| } |
| |
| lldb::OptionValueSP |
| OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx, |
| bool will_modify, |
| uint32_t idx) const |
| { |
| const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx); |
| if (setting) |
| return setting->GetValue(); |
| return OptionValueSP(); |
| } |
| |
| OptionValuePathMappings * |
| OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const |
| { |
| OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); |
| if (value_sp) |
| return value_sp->GetAsPathMappings(); |
| return nullptr; |
| } |
| |
| OptionValueFileSpecList * |
| OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const |
| { |
| OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); |
| if (value_sp) |
| return value_sp->GetAsFileSpecList(); |
| return nullptr; |
| } |
| |
| OptionValueArch * |
| OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| return property->GetValue()->GetAsArch(); |
| return nullptr; |
| } |
| |
| bool |
| OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| { |
| const OptionValueArray *array = value->GetAsArray(); |
| if (array) |
| return array->GetArgs(args); |
| else |
| { |
| const OptionValueDictionary *dict = value->GetAsDictionary(); |
| if (dict) |
| return dict->GetArgs(args); |
| } |
| } |
| } |
| return false; |
| } |
| |
| bool |
| OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| { |
| OptionValueArray *array = value->GetAsArray(); |
| if (array) |
| return array->SetArgs(args, eVarSetOperationAssign).Success(); |
| else |
| { |
| OptionValueDictionary *dict = value->GetAsDictionary(); |
| if (dict) |
| return dict->SetArgs(args, eVarSetOperationAssign).Success(); |
| } |
| } |
| } |
| return false; |
| } |
| |
| bool |
| OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetBooleanValue(fail_value); |
| } |
| return fail_value; |
| } |
| |
| bool |
| OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value) |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| { |
| value->SetBooleanValue(new_value); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| OptionValueDictionary * |
| OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| return property->GetValue()->GetAsDictionary(); |
| return nullptr; |
| } |
| |
| int64_t |
| OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetEnumerationValue(fail_value); |
| } |
| return fail_value; |
| } |
| |
| bool |
| OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->SetEnumerationValue(new_value); |
| } |
| return false; |
| } |
| |
| |
| OptionValueFileSpec * |
| OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetAsFileSpec(); |
| } |
| return nullptr; |
| } |
| |
| |
| FileSpec |
| OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetFileSpecValue(); |
| } |
| return FileSpec(); |
| } |
| |
| |
| bool |
| OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec) |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->SetFileSpecValue(new_file_spec); |
| } |
| return false; |
| } |
| |
| const RegularExpression * |
| OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetRegexValue(); |
| } |
| return nullptr; |
| } |
| |
| OptionValueSInt64 * |
| OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetAsSInt64(); |
| } |
| return nullptr; |
| } |
| |
| int64_t |
| OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetSInt64Value(fail_value); |
| } |
| return fail_value; |
| } |
| |
| bool |
| OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->SetSInt64Value(new_value); |
| } |
| return false; |
| } |
| |
| const char * |
| OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetStringValue(fail_value); |
| } |
| return fail_value; |
| } |
| |
| bool |
| OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value) |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->SetStringValue(new_value); |
| } |
| return false; |
| } |
| |
| OptionValueString * |
| OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const |
| { |
| OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx)); |
| if (value_sp) |
| return value_sp->GetAsString(); |
| return nullptr; |
| } |
| |
| |
| uint64_t |
| OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, false, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->GetUInt64Value(fail_value); |
| } |
| return fail_value; |
| } |
| |
| bool |
| OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value) |
| { |
| const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); |
| if (property) |
| { |
| OptionValue *value = property->GetValue().get(); |
| if (value) |
| return value->SetUInt64Value(new_value); |
| } |
| return false; |
| } |
| |
| bool |
| OptionValueProperties::Clear () |
| { |
| const size_t num_properties = m_properties.size(); |
| for (size_t i=0; i<num_properties; ++i) |
| m_properties[i].GetValue()->Clear(); |
| return true; |
| } |
| |
| |
| Error |
| OptionValueProperties::SetValueFromCString (const char *value, VarSetOperationType op) |
| { |
| Error error; |
| |
| // Args args(value_cstr); |
| // const size_t argc = args.GetArgumentCount(); |
| switch (op) |
| { |
| case eVarSetOperationClear: |
| Clear (); |
| break; |
| |
| case eVarSetOperationReplace: |
| case eVarSetOperationAssign: |
| case eVarSetOperationRemove: |
| case eVarSetOperationInsertBefore: |
| case eVarSetOperationInsertAfter: |
| case eVarSetOperationAppend: |
| case eVarSetOperationInvalid: |
| error = OptionValue::SetValueFromCString (value, op); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) |
| { |
| const size_t num_properties = m_properties.size(); |
| for (size_t i=0; i<num_properties; ++i) |
| { |
| const Property *property = GetPropertyAtIndex(exe_ctx, false, i); |
| if (property) |
| { |
| OptionValue *option_value = property->GetValue().get(); |
| assert (option_value); |
| const bool transparent_value = option_value->ValueIsTransparent (); |
| property->Dump (exe_ctx, |
| strm, |
| dump_mask); |
| if (!transparent_value) |
| strm.EOL(); |
| } |
| } |
| } |
| |
| Error |
| OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx, |
| Stream &strm, |
| const char *property_path, |
| uint32_t dump_mask) |
| { |
| Error error; |
| const bool will_modify = false; |
| lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error)); |
| if (value_sp) |
| { |
| if (!value_sp->ValueIsTransparent ()) |
| { |
| if (dump_mask & eDumpOptionName) |
| strm.PutCString (property_path); |
| if (dump_mask & ~eDumpOptionName) |
| strm.PutChar (' '); |
| } |
| value_sp->DumpValue (exe_ctx, strm, dump_mask); |
| } |
| return error; |
| } |
| |
| lldb::OptionValueSP |
| OptionValueProperties::DeepCopy () const |
| { |
| assert(!"this shouldn't happen"); |
| return lldb::OptionValueSP(); |
| } |
| |
| const Property * |
| OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx, |
| bool will_modify, |
| const char *name) const |
| { |
| const Property *property = nullptr; |
| if (name && name[0]) |
| { |
| const char *sub_name = nullptr; |
| ConstString key; |
| size_t key_len = ::strcspn (name, ".[{"); |
| |
| if (name[key_len]) |
| { |
| key.SetCStringWithLength (name, key_len); |
| sub_name = name + key_len; |
| } |
| else |
| key.SetCString (name); |
| |
| property = GetProperty (exe_ctx, will_modify, key); |
| if (sub_name && property) |
| { |
| if (sub_name[0] == '.') |
| { |
| OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties(); |
| if (sub_properties) |
| return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1); |
| } |
| property = nullptr; |
| } |
| } |
| return property; |
| } |
| |
| void |
| OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter, |
| Stream &strm) const |
| { |
| size_t max_name_len = 0; |
| const size_t num_properties = m_properties.size(); |
| for (size_t i=0; i<num_properties; ++i) |
| { |
| const Property *property = ProtectedGetPropertyAtIndex(i); |
| if (property) |
| max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len); |
| } |
| for (size_t i=0; i<num_properties; ++i) |
| { |
| const Property *property = ProtectedGetPropertyAtIndex(i); |
| if (property) |
| property->DumpDescription (interpreter, strm, max_name_len, false); |
| } |
| } |
| |
| void |
| OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const |
| { |
| const size_t num_properties = m_properties.size(); |
| StreamString strm; |
| for (size_t i=0; i<num_properties; ++i) |
| { |
| const Property *property = ProtectedGetPropertyAtIndex(i); |
| if (property) |
| { |
| const OptionValueProperties *properties = property->GetValue()->GetAsProperties(); |
| if (properties) |
| { |
| properties->Apropos (keyword, matching_properties); |
| } |
| else |
| { |
| bool match = false; |
| const char *name = property->GetName().GetCString(); |
| if (name && ::strcasestr(name, keyword)) |
| match = true; |
| else |
| { |
| const char *desc = property->GetDescription(); |
| if (desc && ::strcasestr(desc, keyword)) |
| match = true; |
| } |
| if (match) |
| { |
| matching_properties.push_back (property); |
| } |
| } |
| } |
| } |
| } |
| |
| lldb::OptionValuePropertiesSP |
| OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx, |
| const ConstString &name) |
| { |
| lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false)); |
| if (option_value_sp) |
| { |
| OptionValueProperties *ov_properties = option_value_sp->GetAsProperties (); |
| if (ov_properties) |
| return ov_properties->shared_from_this(); |
| } |
| return lldb::OptionValuePropertiesSP(); |
| } |
| |
| |
| |