1 //===-- LibCxxRangesRefView.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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "LibCxx.h"
10 
11 #include "lldb/Core/ValueObject.h"
12 #include "lldb/DataFormatters/FormattersHelpers.h"
13 #include "lldb/Utility/ConstString.h"
14 #include "llvm/ADT/APSInt.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 using namespace lldb_private::formatters;
19 
20 namespace lldb_private {
21 namespace formatters {
22 
23 class LibcxxStdRangesRefViewSyntheticFrontEnd
24     : public SyntheticChildrenFrontEnd {
25 public:
26   LibcxxStdRangesRefViewSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
27 
28   ~LibcxxStdRangesRefViewSyntheticFrontEnd() override = default;
29 
30   size_t CalculateNumChildren() override {
31     // __range_ will be the sole child of this type
32     return 1;
33   }
34 
35   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
36     // Since we only have a single child, return it
37     assert(idx == 0);
38     return m_range_sp;
39   }
40 
41   bool Update() override;
42 
43   bool MightHaveChildren() override { return true; }
44 
45   size_t GetIndexOfChildWithName(ConstString name) override {
46     // We only have a single child
47     return 0;
48   }
49 
50 private:
51   /// Pointer to the dereferenced __range_ member
52   lldb::ValueObjectSP m_range_sp = nullptr;
53 };
54 
55 lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEnd::
56     LibcxxStdRangesRefViewSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
57     : SyntheticChildrenFrontEnd(*valobj_sp) {
58   if (valobj_sp)
59     Update();
60 }
61 
62 bool lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEnd::
63     Update() {
64   ValueObjectSP range_ptr =
65       GetChildMemberWithName(m_backend, {ConstString("__range_")});
66   if (!range_ptr)
67     return false;
68 
69   lldb_private::Status error;
70   m_range_sp = range_ptr->Dereference(error);
71 
72   return error.Success();
73 }
74 
75 lldb_private::SyntheticChildrenFrontEnd *
76 LibcxxStdRangesRefViewSyntheticFrontEndCreator(CXXSyntheticChildren *,
77                                                lldb::ValueObjectSP valobj_sp) {
78   if (!valobj_sp)
79     return nullptr;
80   CompilerType type = valobj_sp->GetCompilerType();
81   if (!type.IsValid())
82     return nullptr;
83   return new LibcxxStdRangesRefViewSyntheticFrontEnd(valobj_sp);
84 }
85 
86 } // namespace formatters
87 } // namespace lldb_private
88