Index: include/lldb/Target/CPPLanguageRuntime.h =================================================================== --- include/lldb/Target/CPPLanguageRuntime.h +++ include/lldb/Target/CPPLanguageRuntime.h @@ -78,7 +78,7 @@ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop_others) override; - bool IsRuntimeSupportValue(ValueObject &valobj) override; + bool IsWhitelistedRuntimeValue(ConstString name) override; protected: // Classes that inherit from CPPLanguageRuntime can see and modify these CPPLanguageRuntime(Process *process); Index: include/lldb/Target/LanguageRuntime.h =================================================================== --- include/lldb/Target/LanguageRuntime.h +++ include/lldb/Target/LanguageRuntime.h @@ -16,6 +16,7 @@ #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/LLVMUserExpression.h" +#include "lldb/Symbol/Variable.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/lldb-private.h" #include "lldb/lldb-public.h" @@ -150,9 +151,15 @@ virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop_others) = 0; - /// Identify whether a value is a language implementation detaul + /// Identify whether a value is a language implementation detail /// that should be hidden from the user interface by default. - virtual bool IsRuntimeSupportValue(ValueObject &valobj) { return false; } + virtual bool IsRuntimeSupportValue(ValueObject &valobj) { + return valobj.GetVariable() && valobj.GetVariable()->IsArtificial(); + } + + /// Identify whether a name is a runtime value that should not be hidden by + /// from the user interface. + virtual bool IsWhitelistedRuntimeValue(ConstString name) { return false; } virtual void ModulesDidLoad(const ModuleList &module_list) {} Index: include/lldb/Target/ObjCLanguageRuntime.h =================================================================== --- include/lldb/Target/ObjCLanguageRuntime.h +++ include/lldb/Target/ObjCLanguageRuntime.h @@ -299,8 +299,7 @@ /// Check whether the name is "self" or "_cmd" and should show up in /// "frame variable". - static bool IsWhitelistedRuntimeValue(ConstString name); - bool IsRuntimeSupportValue(ValueObject &valobj) override; + bool IsWhitelistedRuntimeValue(ConstString name) override; protected: // Classes that inherit from ObjCLanguageRuntime can see and modify these Index: source/Core/ValueObject.cpp =================================================================== --- source/Core/ValueObject.cpp +++ source/Core/ValueObject.cpp @@ -1696,14 +1696,26 @@ bool ValueObject::IsRuntimeSupportValue() { Process *process(GetProcessSP().get()); if (process) { - LanguageRuntime *runtime = - process->GetLanguageRuntime(GetObjectRuntimeLanguage()); - if (!runtime) - runtime = ObjCLanguageRuntime::Get(*process); - if (runtime) - return runtime->IsRuntimeSupportValue(*this); - // If there is no language runtime, trust the compiler to mark all - // runtime support variables as artificial. + // It's possible we have more than one language involved here. For example, + // in ObjC `_cmd` is a whitelisted runtime variable name, but + // GetObjectRuntimeLanguage will say it's a C variable since it's just a + // cstring. + bool marked_as_runtime_support_val = false; + for (auto *runtime : process->GetLanguageRuntimes()) { + bool is_runtime_support_val = runtime->IsRuntimeSupportValue(*this); + if (is_runtime_support_val && runtime->IsWhitelistedRuntimeValue(GetName())) + return false; + + marked_as_runtime_support_val |= is_runtime_support_val; + } + + // If any language runtimes marked it as a runtime support value, we say so. + if (marked_as_runtime_support_val) + return true; + + // If no language runtime claims that this value is a runtime support value, + // then we trust that the compiler marked runtime support variables as + // artificial. return GetVariable() && GetVariable()->IsArtificial(); } return false; Index: source/Target/CPPLanguageRuntime.cpp =================================================================== --- source/Target/CPPLanguageRuntime.cpp +++ source/Target/CPPLanguageRuntime.cpp @@ -43,20 +43,8 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process) : LanguageRuntime(process) {} -bool CPPLanguageRuntime::IsRuntimeSupportValue(ValueObject &valobj) { - // All runtime support values have to be marked as artificial by the - // compiler. But not all artificial variables should be hidden from - // the user. - if (!valobj.GetVariable()) - return false; - if (!valobj.GetVariable()->IsArtificial()) - return false; - - // Whitelist "this" and since there is no ObjC++ runtime, any ObjC names. - ConstString name = valobj.GetName(); - if (name == g_this) - return false; - return !ObjCLanguageRuntime::IsWhitelistedRuntimeValue(name); +bool CPPLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) { + return name == g_this; } bool CPPLanguageRuntime::GetObjectDescription(Stream &str, Index: source/Target/ObjCLanguageRuntime.cpp =================================================================== --- source/Target/ObjCLanguageRuntime.cpp +++ source/Target/ObjCLanguageRuntime.cpp @@ -46,19 +46,6 @@ return name == g_self || name == g_cmd; } -bool ObjCLanguageRuntime::IsRuntimeSupportValue(ValueObject &valobj) { - // All runtime support values have to be marked as artificial by the - // compiler. But not all artificial variables should be hidden from - // the user. - if (!valobj.GetVariable()) - return false; - if (!valobj.GetVariable()->IsArtificial()) - return false; - - // Whitelist "self" and "_cmd". - return !IsWhitelistedRuntimeValue(valobj.GetName()); -} - bool ObjCLanguageRuntime::AddClass(ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name) {