brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · c3fb8cb Raw
198 lines · cpp
1//===-- DumpValueObjectOptionsTests.cpp -----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Plugins/Platform/Linux/PlatformLinux.h"10#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"11#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"12#include "TestingSupport/SubsystemRAII.h"13#include "TestingSupport/Symbol/ClangTestUtils.h"14#include "lldb/Core/Debugger.h"15#include "lldb/DataFormatters/DumpValueObjectOptions.h"16#include "lldb/ValueObject/ValueObject.h"17#include "lldb/ValueObject/ValueObjectConstResult.h"18 19#include "gtest/gtest.h"20 21#include <type_traits>22 23using namespace lldb;24using namespace lldb_private;25 26struct MockProcess : Process {27  MockProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)28      : Process(target_sp, listener_sp) {}29 30  llvm::StringRef GetPluginName() override { return "mock process"; }31 32  bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override {33    return false;34  };35 36  Status DoDestroy() override { return {}; }37 38  void RefreshStateAfterStop() override {}39 40  bool DoUpdateThreadList(ThreadList &old_thread_list,41                          ThreadList &new_thread_list) override {42    return false;43  };44 45  size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,46                      Status &error) override {47    // No need to read memory in these tests.48    return size;49  }50};51 52class ValueObjectMockProcessTest : public ::testing::Test {53public:54  void SetUp() override {55    ArchSpec arch("i386-pc-linux");56    Platform::SetHostPlatform(57        platform_linux::PlatformLinux::CreateInstance(true, &arch));58    m_debugger_sp = Debugger::CreateInstance();59    ASSERT_TRUE(m_debugger_sp);60    m_debugger_sp->GetTargetList().CreateTarget(*m_debugger_sp, "", arch,61                                                eLoadDependentsNo,62                                                m_platform_sp, m_target_sp);63    ASSERT_TRUE(m_target_sp);64    ASSERT_TRUE(m_target_sp->GetArchitecture().IsValid());65    ASSERT_TRUE(m_platform_sp);66    m_listener_sp = Listener::MakeListener("dummy");67    m_process_sp = std::make_shared<MockProcess>(m_target_sp, m_listener_sp);68    ASSERT_TRUE(m_process_sp);69    m_exe_ctx = ExecutionContext(m_process_sp);70 71    m_holder = std::make_unique<clang_utils::TypeSystemClangHolder>("test");72    m_type_system = m_holder->GetAST();73  }74 75  template <typename UnderlyingType>76  void TestDumpEnum(77      const std::vector<std::pair<const char *, UnderlyingType>> enumerators,78      const std::vector<std::tuple<UnderlyingType, DumpValueObjectOptions,79                                   const char *>> &tests) {80    CompilerType enum_type = MakeEnumType(enumerators);81    StreamString strm;82    ConstString var_name("test_var");83    ByteOrder endian = endian::InlHostByteOrder();84    ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();85    for (auto [value, options, expected] : tests) {86      DataExtractor data_extractor{&value, sizeof(value), endian, 4};87      auto valobj_sp = ValueObjectConstResult::Create(exe_scope, enum_type,88                                                      var_name, data_extractor);89      if (llvm::Error error = valobj_sp->Dump(strm, options))90        llvm::consumeError(std::move(error));91      ASSERT_STREQ(strm.GetString().str().c_str(), expected);92      strm.Clear();93    }94  }95 96  template <typename UnderlyingType>97  CompilerType MakeEnumType(98      const std::vector<std::pair<const char *, UnderlyingType>> enumerators) {99    CompilerType int_type = m_type_system->GetBuiltinTypeForEncodingAndBitSize(100        std::is_same<UnderlyingType, int>::value ? lldb::eEncodingSint101                                                 : lldb::eEncodingUint,102        32);103    CompilerType enum_type = m_type_system->CreateEnumerationType(104        "TestEnum", m_type_system->GetTranslationUnitDecl(),105        OptionalClangModuleID(), Declaration(), int_type, false);106 107    m_type_system->StartTagDeclarationDefinition(enum_type);108    Declaration decl;109    for (auto [name, value] : enumerators)110      m_type_system->AddEnumerationValueToEnumerationType(enum_type, decl, name,111                                                          value, 32);112    m_type_system->CompleteTagDeclarationDefinition(enum_type);113 114    return enum_type;115  }116 117  ExecutionContext m_exe_ctx;118  TypeSystemClang *m_type_system;119 120private:121  SubsystemRAII<FileSystem, HostInfo, platform_linux::PlatformLinux,122                ScriptInterpreterNone>123      m_subsystems;124 125  std::unique_ptr<clang_utils::TypeSystemClangHolder> m_holder;126  lldb::DebuggerSP m_debugger_sp;127  lldb::TargetSP m_target_sp;128  lldb::PlatformSP m_platform_sp;129  lldb::ListenerSP m_listener_sp;130  lldb::ProcessSP m_process_sp;131};132 133TEST_F(ValueObjectMockProcessTest, EmptyEnum) {134  // All values of an empty enum should be shown as plain numbers.135  TestDumpEnum<unsigned>({}, {{0, {}, "(TestEnum) test_var = 0\n"},136                              {1, {}, "(TestEnum) test_var = 1\n"},137                              {2, {}, "(TestEnum) test_var = 2\n"}});138 139  TestDumpEnum<int>({}, {{-2, {}, "(TestEnum) test_var = -2\n"},140                         {-1, {}, "(TestEnum) test_var = -1\n"},141                         {0, {}, "(TestEnum) test_var = 0\n"},142                         {1, {}, "(TestEnum) test_var = 1\n"},143                         {2, {}, "(TestEnum) test_var = 2\n"}});144}145 146TEST_F(ValueObjectMockProcessTest, Enum) {147  // This is not a bitfield-like enum, so values are printed as decimal by148  // default. Also we only show the enumerator name if the value is an149  // exact match.150  TestDumpEnum<unsigned>(151      {{"test_2", 2}, {"test_3", 3}},152      {{0, {}, "(TestEnum) test_var = 0\n"},153       {1, {}, "(TestEnum) test_var = 1\n"},154       {2, {}, "(TestEnum) test_var = test_2\n"},155       {3, {}, "(TestEnum) test_var = test_3\n"},156       {4, {}, "(TestEnum) test_var = 4\n"},157       {5, {}, "(TestEnum) test_var = 5\n"},158       {1, DumpValueObjectOptions().SetHideRootName(true), "(TestEnum) 1\n"},159       {1, DumpValueObjectOptions().SetHideRootType(true), "test_var = 1\n"},160       {1, DumpValueObjectOptions().SetHideRootName(true).SetHideRootType(true),161        "1\n"},162       {1, DumpValueObjectOptions().SetHideName(true), "(TestEnum) 1\n"},163       {1, DumpValueObjectOptions().SetHideValue(true),164        "(TestEnum) test_var =\n"},165       {1, DumpValueObjectOptions().SetHideName(true).SetHideValue(true),166        "(TestEnum) \n"}});167}168 169TEST_F(ValueObjectMockProcessTest, BitFieldLikeEnum) {170  // These enumerators set individual bits in the value, as if it were a flag171  // set. lldb treats this as a "bitfield like enum". This means we show values172  // as hex, and values without exact matches are shown as a combination of173  // enumerators and any remaining value left over.174  TestDumpEnum<unsigned>(175      {{"test_2", 2}, {"test_4", 4}},176      {177          {0, {}, "(TestEnum) test_var = 0x0\n"},178          {1, {}, "(TestEnum) test_var = 0x1\n"},179          {2, {}, "(TestEnum) test_var = test_2\n"},180          {4, {}, "(TestEnum) test_var = test_4\n"},181          {6, {}, "(TestEnum) test_var = test_2 | test_4\n"},182          {7, {}, "(TestEnum) test_var = test_2 | test_4 | 0x1\n"},183          {8, {}, "(TestEnum) test_var = 0x8\n"},184          {1, DumpValueObjectOptions().SetHideRootName(true),185           "(TestEnum) 0x1\n"},186          {1, DumpValueObjectOptions().SetHideRootType(true),187           "test_var = 0x1\n"},188          {1,189           DumpValueObjectOptions().SetHideRootName(true).SetHideRootType(true),190           "0x1\n"},191          {1, DumpValueObjectOptions().SetHideName(true), "(TestEnum) 0x1\n"},192          {1, DumpValueObjectOptions().SetHideValue(true),193           "(TestEnum) test_var =\n"},194          {1, DumpValueObjectOptions().SetHideName(true).SetHideValue(true),195           "(TestEnum) \n"},196      });197}198