CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
198 lines
8.0 KiB
C++
198 lines
8.0 KiB
C++
//===-- DumpValueObjectOptionsTests.cpp -----------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Plugins/Platform/Linux/PlatformLinux.h"
|
|
#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"
|
|
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
|
|
#include "TestingSupport/SubsystemRAII.h"
|
|
#include "TestingSupport/Symbol/ClangTestUtils.h"
|
|
#include "lldb/Core/Debugger.h"
|
|
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
|
|
#include "lldb/ValueObject/ValueObject.h"
|
|
#include "lldb/ValueObject/ValueObjectConstResult.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include <type_traits>
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
struct MockProcess : Process {
|
|
MockProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
|
|
: Process(target_sp, listener_sp) {}
|
|
|
|
llvm::StringRef GetPluginName() override { return "mock process"; }
|
|
|
|
bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override {
|
|
return false;
|
|
};
|
|
|
|
Status DoDestroy() override { return {}; }
|
|
|
|
void RefreshStateAfterStop() override {}
|
|
|
|
bool DoUpdateThreadList(ThreadList &old_thread_list,
|
|
ThreadList &new_thread_list) override {
|
|
return false;
|
|
};
|
|
|
|
size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
|
|
Status &error) override {
|
|
// No need to read memory in these tests.
|
|
return size;
|
|
}
|
|
};
|
|
|
|
class ValueObjectMockProcessTest : public ::testing::Test {
|
|
public:
|
|
void SetUp() override {
|
|
ArchSpec arch("i386-pc-linux");
|
|
Platform::SetHostPlatform(
|
|
platform_linux::PlatformLinux::CreateInstance(true, &arch));
|
|
m_debugger_sp = Debugger::CreateInstance();
|
|
ASSERT_TRUE(m_debugger_sp);
|
|
m_debugger_sp->GetTargetList().CreateTarget(*m_debugger_sp, "", arch,
|
|
eLoadDependentsNo,
|
|
m_platform_sp, m_target_sp);
|
|
ASSERT_TRUE(m_target_sp);
|
|
ASSERT_TRUE(m_target_sp->GetArchitecture().IsValid());
|
|
ASSERT_TRUE(m_platform_sp);
|
|
m_listener_sp = Listener::MakeListener("dummy");
|
|
m_process_sp = std::make_shared<MockProcess>(m_target_sp, m_listener_sp);
|
|
ASSERT_TRUE(m_process_sp);
|
|
m_exe_ctx = ExecutionContext(m_process_sp);
|
|
|
|
m_holder = std::make_unique<clang_utils::TypeSystemClangHolder>("test");
|
|
m_type_system = m_holder->GetAST();
|
|
}
|
|
|
|
template <typename UnderlyingType>
|
|
void TestDumpEnum(
|
|
const std::vector<std::pair<const char *, UnderlyingType>> enumerators,
|
|
const std::vector<std::tuple<UnderlyingType, DumpValueObjectOptions,
|
|
const char *>> &tests) {
|
|
CompilerType enum_type = MakeEnumType(enumerators);
|
|
StreamString strm;
|
|
ConstString var_name("test_var");
|
|
ByteOrder endian = endian::InlHostByteOrder();
|
|
ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
|
|
for (auto [value, options, expected] : tests) {
|
|
DataExtractor data_extractor{&value, sizeof(value), endian, 4};
|
|
auto valobj_sp = ValueObjectConstResult::Create(exe_scope, enum_type,
|
|
var_name, data_extractor);
|
|
if (llvm::Error error = valobj_sp->Dump(strm, options))
|
|
llvm::consumeError(std::move(error));
|
|
ASSERT_STREQ(strm.GetString().str().c_str(), expected);
|
|
strm.Clear();
|
|
}
|
|
}
|
|
|
|
template <typename UnderlyingType>
|
|
CompilerType MakeEnumType(
|
|
const std::vector<std::pair<const char *, UnderlyingType>> enumerators) {
|
|
CompilerType int_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize(
|
|
std::is_same<UnderlyingType, int>::value ? lldb::eEncodingSint
|
|
: lldb::eEncodingUint,
|
|
32);
|
|
CompilerType enum_type = m_type_system->CreateEnumerationType(
|
|
"TestEnum", m_type_system->GetTranslationUnitDecl(),
|
|
OptionalClangModuleID(), Declaration(), int_type, false);
|
|
|
|
m_type_system->StartTagDeclarationDefinition(enum_type);
|
|
Declaration decl;
|
|
for (auto [name, value] : enumerators)
|
|
m_type_system->AddEnumerationValueToEnumerationType(enum_type, decl, name,
|
|
value, 32);
|
|
m_type_system->CompleteTagDeclarationDefinition(enum_type);
|
|
|
|
return enum_type;
|
|
}
|
|
|
|
ExecutionContext m_exe_ctx;
|
|
TypeSystemClang *m_type_system;
|
|
|
|
private:
|
|
SubsystemRAII<FileSystem, HostInfo, platform_linux::PlatformLinux,
|
|
ScriptInterpreterNone>
|
|
m_subsystems;
|
|
|
|
std::unique_ptr<clang_utils::TypeSystemClangHolder> m_holder;
|
|
lldb::DebuggerSP m_debugger_sp;
|
|
lldb::TargetSP m_target_sp;
|
|
lldb::PlatformSP m_platform_sp;
|
|
lldb::ListenerSP m_listener_sp;
|
|
lldb::ProcessSP m_process_sp;
|
|
};
|
|
|
|
TEST_F(ValueObjectMockProcessTest, EmptyEnum) {
|
|
// All values of an empty enum should be shown as plain numbers.
|
|
TestDumpEnum<unsigned>({}, {{0, {}, "(TestEnum) test_var = 0\n"},
|
|
{1, {}, "(TestEnum) test_var = 1\n"},
|
|
{2, {}, "(TestEnum) test_var = 2\n"}});
|
|
|
|
TestDumpEnum<int>({}, {{-2, {}, "(TestEnum) test_var = -2\n"},
|
|
{-1, {}, "(TestEnum) test_var = -1\n"},
|
|
{0, {}, "(TestEnum) test_var = 0\n"},
|
|
{1, {}, "(TestEnum) test_var = 1\n"},
|
|
{2, {}, "(TestEnum) test_var = 2\n"}});
|
|
}
|
|
|
|
TEST_F(ValueObjectMockProcessTest, Enum) {
|
|
// This is not a bitfield-like enum, so values are printed as decimal by
|
|
// default. Also we only show the enumerator name if the value is an
|
|
// exact match.
|
|
TestDumpEnum<unsigned>(
|
|
{{"test_2", 2}, {"test_3", 3}},
|
|
{{0, {}, "(TestEnum) test_var = 0\n"},
|
|
{1, {}, "(TestEnum) test_var = 1\n"},
|
|
{2, {}, "(TestEnum) test_var = test_2\n"},
|
|
{3, {}, "(TestEnum) test_var = test_3\n"},
|
|
{4, {}, "(TestEnum) test_var = 4\n"},
|
|
{5, {}, "(TestEnum) test_var = 5\n"},
|
|
{1, DumpValueObjectOptions().SetHideRootName(true), "(TestEnum) 1\n"},
|
|
{1, DumpValueObjectOptions().SetHideRootType(true), "test_var = 1\n"},
|
|
{1, DumpValueObjectOptions().SetHideRootName(true).SetHideRootType(true),
|
|
"1\n"},
|
|
{1, DumpValueObjectOptions().SetHideName(true), "(TestEnum) 1\n"},
|
|
{1, DumpValueObjectOptions().SetHideValue(true),
|
|
"(TestEnum) test_var =\n"},
|
|
{1, DumpValueObjectOptions().SetHideName(true).SetHideValue(true),
|
|
"(TestEnum) \n"}});
|
|
}
|
|
|
|
TEST_F(ValueObjectMockProcessTest, BitFieldLikeEnum) {
|
|
// These enumerators set individual bits in the value, as if it were a flag
|
|
// set. lldb treats this as a "bitfield like enum". This means we show values
|
|
// as hex, and values without exact matches are shown as a combination of
|
|
// enumerators and any remaining value left over.
|
|
TestDumpEnum<unsigned>(
|
|
{{"test_2", 2}, {"test_4", 4}},
|
|
{
|
|
{0, {}, "(TestEnum) test_var = 0x0\n"},
|
|
{1, {}, "(TestEnum) test_var = 0x1\n"},
|
|
{2, {}, "(TestEnum) test_var = test_2\n"},
|
|
{4, {}, "(TestEnum) test_var = test_4\n"},
|
|
{6, {}, "(TestEnum) test_var = test_2 | test_4\n"},
|
|
{7, {}, "(TestEnum) test_var = test_2 | test_4 | 0x1\n"},
|
|
{8, {}, "(TestEnum) test_var = 0x8\n"},
|
|
{1, DumpValueObjectOptions().SetHideRootName(true),
|
|
"(TestEnum) 0x1\n"},
|
|
{1, DumpValueObjectOptions().SetHideRootType(true),
|
|
"test_var = 0x1\n"},
|
|
{1,
|
|
DumpValueObjectOptions().SetHideRootName(true).SetHideRootType(true),
|
|
"0x1\n"},
|
|
{1, DumpValueObjectOptions().SetHideName(true), "(TestEnum) 0x1\n"},
|
|
{1, DumpValueObjectOptions().SetHideValue(true),
|
|
"(TestEnum) test_var =\n"},
|
|
{1, DumpValueObjectOptions().SetHideName(true).SetHideValue(true),
|
|
"(TestEnum) \n"},
|
|
});
|
|
}
|