================ @@ -0,0 +1,122 @@ +//===---------------------------------------------------------------------===// +// +// 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 "LibStdcpp.h" + +#include "lldb/DataFormatters/TypeSynthetic.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/ValueObject/ValueObject.h" +#include "lldb/lldb-enumerations.h" + +using namespace lldb; + +namespace lldb_private::formatters { + +class LibStdcppAtomicSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + explicit LibStdcppAtomicSyntheticFrontEnd(const ValueObjectSP &valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), + m_inner_name(ConstString("Value")) {} + + llvm::Expected<uint32_t> CalculateNumChildren() final { + return m_inner ? 1 : 0; + } + + ValueObjectSP GetChildAtIndex(uint32_t idx) final { + if (idx == 0 && m_inner) + return m_inner->GetSP()->Clone(m_inner_name); + + return {}; + } + + lldb::ChildCacheState Update() final { + if (ValueObjectSP value = ContainerFieldName(m_backend)) { + // show the Type, instead of std::__atomic_base<Type>::__Type_type. + value = value->Cast(value->GetCompilerType().GetCanonicalType()); + m_inner = value.get(); + } + + return lldb::ChildCacheState::eRefetch; + } + + llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) final { + if (name == m_inner_name) + return 0; + + return llvm::createStringError("Type has no child named '%s'", + name.AsCString()); + } + + static ValueObjectSP ContainerFieldName(ValueObject &backend_syn) { + const ValueObjectSP non_synthetic = backend_syn.GetNonSyntheticValue(); + if (!non_synthetic || !non_synthetic.get()) + return {}; + ValueObject &backend = *non_synthetic; + + const CompilerType type = backend.GetCompilerType(); + if (!type.IsValid() || type.GetNumTemplateArguments() < 1) + return {}; + + const CompilerType first_type = type.GetTypeTemplateArgument(0); + const lldb::BasicType basic_type = first_type.GetBasicTypeEnumeration(); + if (basic_type == eBasicTypeBool) + return backend.GetChildAtNamePath({"_M_base", "_M_i"}); + + if (first_type.GetTypeInfo() & lldb::eTypeIsFloat) { + // added float types specialization in c++17 + if (const auto child = backend.GetChildMemberWithName("_M_fp")) + return child; + + return backend.GetChildMemberWithName("_M_i"); + } + + if (first_type.IsPointerType()) + return backend.GetChildAtNamePath({"_M_b", "_M_p"}); + + return backend.GetChildMemberWithName("_M_i"); + } + +private: + ConstString m_inner_name; + ValueObject *m_inner{}; +}; + +SyntheticChildrenFrontEnd * +LibStdcppAtomicSyntheticFrontEndCreator(CXXSyntheticChildren * /*unused*/, + const lldb::ValueObjectSP &valobj_sp) { + if (!valobj_sp) + return nullptr; + + auto valobj = valobj_sp->GetNonSyntheticValue(); + if (!valobj || !valobj.get()) ---------------- Michael137 wrote:
`ContainerFieldName` already does this. So this is redundant? https://github.com/llvm/llvm-project/pull/174218 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
