brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · e20dd31 Raw
155 lines · cpp
1//===-- LibCxxAtomic.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 "LibCxxAtomic.h"10#include "lldb/DataFormatters/FormattersHelpers.h"11 12using namespace lldb;13using namespace lldb_private;14using namespace lldb_private::formatters;15 16//17// We are supporting two versions of libc++ std::atomic18//19// Given std::atomic<int> i;20//21// The previous version of std::atomic was laid out like this22//23// (lldb) frame var -L -R i24// 0x00007ffeefbff9a0: (std::__1::atomic<int>) i = {25// 0x00007ffeefbff9a0:   std::__1::__atomic_base<int, true> = {26// 0x00007ffeefbff9a0:     std::__1::__atomic_base<int, false> = {27// 0x00007ffeefbff9a0:       __a_ = 528//        }29//    }30// }31//32// In this case we need to obtain __a_ and the current version is laid out as so33//34// (lldb) frame var -L -R i35// 0x00007ffeefbff9b0: (std::__1::atomic<int>) i = {36// 0x00007ffeefbff9b0:   std::__1::__atomic_base<int, true> = {37// 0x00007ffeefbff9b0:     std::__1::__atomic_base<int, false> = {38// 0x00007ffeefbff9b0:       __a_ = {39// 0x00007ffeefbff9b0:         std::__1::__cxx_atomic_base_impl<int> = {40// 0x00007ffeefbff9b0:           __a_value = 541//                }42//          }43//       }44//    }45//}46//47// In this case we need to obtain __a_value48//49// The below method covers both cases and returns the relevant member as a50// ValueObjectSP51//52ValueObjectSP53lldb_private::formatters::GetLibCxxAtomicValue(ValueObject &valobj) {54  ValueObjectSP non_sythetic = valobj.GetNonSyntheticValue();55  if (!non_sythetic)56    return {};57 58  ValueObjectSP member__a_ = non_sythetic->GetChildMemberWithName("__a_");59  if (!member__a_)60    return {};61 62  ValueObjectSP member__a_value =63      member__a_->GetChildMemberWithName("__a_value");64  if (!member__a_value)65    return member__a_;66 67  return member__a_value;68}69 70bool lldb_private::formatters::LibCxxAtomicSummaryProvider(71    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {72 73  if (ValueObjectSP atomic_value = GetLibCxxAtomicValue(valobj)) {74    std::string summary;75    if (atomic_value->GetSummaryAsCString(summary, options) &&76        summary.size() > 0) {77      stream.Printf("%s", summary.c_str());78      return true;79    }80  }81 82  return false;83}84 85namespace lldb_private {86namespace formatters {87class LibcxxStdAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd {88public:89  LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);90 91  ~LibcxxStdAtomicSyntheticFrontEnd() override = default;92 93  llvm::Expected<uint32_t> CalculateNumChildren() override;94 95  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;96 97  lldb::ChildCacheState Update() override;98 99  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;100 101private:102  ValueObject *m_real_child = nullptr;103};104} // namespace formatters105} // namespace lldb_private106 107lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::108    LibcxxStdAtomicSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)109    : SyntheticChildrenFrontEnd(*valobj_sp) {}110 111lldb::ChildCacheState112lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::Update() {113  ValueObjectSP atomic_value = GetLibCxxAtomicValue(m_backend);114  if (atomic_value)115    m_real_child = GetLibCxxAtomicValue(m_backend).get();116 117  return lldb::ChildCacheState::eRefetch;118}119 120llvm::Expected<uint32_t> lldb_private::formatters::121    LibcxxStdAtomicSyntheticFrontEnd::CalculateNumChildren() {122  return m_real_child ? 1 : 0;123}124 125lldb::ValueObjectSP126lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex(127    uint32_t idx) {128  if (idx == 0)129    return m_real_child->GetSP()->Clone(ConstString("Value"));130  return nullptr;131}132 133llvm::Expected<size_t>134lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::135    GetIndexOfChildWithName(ConstString name) {136  if (name == "Value")137    return 0;138  return llvm::createStringError("Type has no child named '%s'",139                                 name.AsCString());140}141 142SyntheticChildrenFrontEnd *143lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator(144    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {145  if (valobj_sp && IsLibCxxAtomic(*valobj_sp))146    return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp);147  return nullptr;148}149 150bool lldb_private::formatters::IsLibCxxAtomic(ValueObject &valobj) {151  if (auto valobj_sp = valobj.GetNonSyntheticValue())152    return valobj_sp->GetChildMemberWithName("__a_") != nullptr;153  return false;154}155