diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h --- a/lldb/include/lldb/Target/LanguageRuntime.h +++ b/lldb/include/lldb/Target/LanguageRuntime.h @@ -151,6 +151,11 @@ /// from the user interface. virtual bool IsAllowedRuntimeValue(ConstString name) { return false; } + /// Returns 'true' if we the variable with the specified 'name' + /// should be hidden from variable views (e.g., when listing variables in + /// 'frame variable' or 'target variable') + virtual bool ShouldHideVariable(llvm::StringRef name) const { return false; } + virtual std::optional GetRuntimeType(CompilerType base_type) { return std::nullopt; } diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -1600,12 +1600,20 @@ if (!process) return false; + if (!GetVariable()) + return false; + + auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage()); + if (runtime) + if (runtime->ShouldHideVariable(GetName().GetStringRef())) + return true; + // We trust that the compiler did the right thing and marked runtime support // values as artificial. - if (!GetVariable() || !GetVariable()->IsArtificial()) + if (!GetVariable()->IsArtificial()) return false; - if (auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage())) + if (runtime) if (runtime->IsAllowedRuntimeValue(GetName())) return false; diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h @@ -77,6 +77,8 @@ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop_others) override; + bool ShouldHideVariable(llvm::StringRef name) const override; + bool IsAllowedRuntimeValue(ConstString name) override; protected: // Classes that inherit from CPPLanguageRuntime can see and modify these diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -28,6 +28,7 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/ThreadPlanRunToAddress.h" #include "lldb/Target/ThreadPlanStepInRange.h" +#include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Timer.h" using namespace lldb; @@ -40,6 +41,17 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process) : LanguageRuntime(process) {} +bool CPPLanguageRuntime::ShouldHideVariable(llvm::StringRef name) const { + // Matches the global function objects in std::ranges/std::ranges::views + // E.g., + // std::__1::ranges::views::__cpo::take + // std::__1::ranges::__cpo::max_element + static RegularExpression ignore_global_ranges_pattern( + "std::__[[:alnum:]]+::ranges(::views)*::__cpo"); + + return ignore_globale_ranges_pattern.Execute(name); +} + bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) { return name == g_this; } diff --git a/lldb/test/API/lang/cpp/hide_global_ranges_vars/Makefile b/lldb/test/API/lang/cpp/hide_global_ranges_vars/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/hide_global_ranges_vars/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp +CXXFLAGS_EXTRAS := -std=c++20 + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/hide_global_ranges_vars/TestHideGlobalRangesVars.py b/lldb/test/API/lang/cpp/hide_global_ranges_vars/TestHideGlobalRangesVars.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/hide_global_ranges_vars/TestHideGlobalRangesVars.py @@ -0,0 +1,27 @@ +"""Test that frame var and target var hide +the global function objects in the libc++ +ranges implementation""" + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class HideGlobalRangesVarsTestCase(TestBase): + + @add_test_categories(["libc++"]) + @skipIf(compiler=no_match("clang")) + @skipIf(compiler="clang", compiler_version=['<', '16.0']) + def test(self): + self.build() + + lldbutil.run_to_source_breakpoint(self, "return", lldb.SBFileSpec('main.cpp', False)) + + self.expect("frame variable --show-globals", + substrs=["::ranges::views::__cpo", + "::ranges::__cpo"], + matching=False) + + self.expect("target variable", + substrs=["::ranges::views::__cpo", + "::ranges::__cpo"], + matching=False) diff --git a/lldb/test/API/lang/cpp/hide_global_ranges_vars/main.cpp b/lldb/test/API/lang/cpp/hide_global_ranges_vars/main.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/hide_global_ranges_vars/main.cpp @@ -0,0 +1,9 @@ +#include + +int main(int argc, char const *argv[]) { + int arr[3] = {1, 2, 3}; + auto arr_view = std::ranges::views::all(arr); + auto arr_max = std::ranges::max_element(arr); + + return 0; +}