1//===-- Materializer.h ------------------------------------------*- C++ -*-===//
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#ifndef LLDB_EXPRESSION_MATERIALIZER_H
10#define LLDB_EXPRESSION_MATERIALIZER_H
11
12#include <memory>
13#include <vector>
14
15#include "lldb/Expression/IRMemoryMap.h"
16#include "lldb/Symbol/TaggedASTType.h"
17#include "lldb/Target/StackFrame.h"
18#include "lldb/Utility/Status.h"
19#include "lldb/lldb-private-types.h"
20
21namespace lldb_private {
22
23class Materializer {
24public:
25 Materializer() = default;
26 ~Materializer();
27
28 class Dematerializer {
29 public:
30 Dematerializer() = default;
31
32 ~Dematerializer() { Wipe(); }
33
34 void Dematerialize(Status &err, lldb::addr_t frame_top,
35 lldb::addr_t frame_bottom);
36
37 void Wipe();
38
39 bool IsValid() {
40 return m_materializer && m_map &&
41 (m_process_address != LLDB_INVALID_ADDRESS);
42 }
43
44 private:
45 friend class Materializer;
46
47 Dematerializer(Materializer &materializer, lldb::StackFrameSP &frame_sp,
48 IRMemoryMap &map, lldb::addr_t process_address)
49 : m_materializer(&materializer), m_map(&map),
50 m_process_address(process_address) {
51 if (frame_sp) {
52 m_thread_wp = frame_sp->GetThread();
53 m_stack_id = frame_sp->GetStackID();
54 }
55 }
56
57 Materializer *m_materializer = nullptr;
58 lldb::ThreadWP m_thread_wp;
59 StackID m_stack_id;
60 IRMemoryMap *m_map = nullptr;
61 lldb::addr_t m_process_address = LLDB_INVALID_ADDRESS;
62 };
63
64 typedef std::shared_ptr<Dematerializer> DematerializerSP;
65 typedef std::weak_ptr<Dematerializer> DematerializerWP;
66
67 DematerializerSP Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
68 lldb::addr_t process_address, Status &err);
69
70 class PersistentVariableDelegate {
71 public:
72 PersistentVariableDelegate();
73 virtual ~PersistentVariableDelegate();
74 virtual ConstString GetName() = 0;
75 virtual void DidDematerialize(lldb::ExpressionVariableSP &variable) = 0;
76 };
77
78 uint32_t
79 AddPersistentVariable(lldb::ExpressionVariableSP &persistent_variable_sp,
80 PersistentVariableDelegate *delegate, Status &err);
81 uint32_t AddVariable(lldb::VariableSP &variable_sp, Status &err);
82
83 /// Create entity from supplied ValueObject and count it as a member
84 /// of the materialized struct.
85 ///
86 /// Behaviour is undefined if 'valobj_provider' is empty.
87 ///
88 /// \param[in] name Name of variable to materialize
89 ///
90 /// \param[in] valobj_provider When materializing values multiple
91 /// times, this callback gets used to fetch a fresh
92 /// ValueObject corresponding to the supplied frame.
93 /// This is mainly used for conditional breakpoints
94 /// that re-apply an expression whatever the frame
95 /// happens to be when the breakpoint got hit.
96 ///
97 /// \param[out] err Error status that gets set on error.
98 ///
99 /// \returns Offset in bytes of the member we just added to the
100 /// materialized struct.
101 uint32_t AddValueObject(ConstString name,
102 ValueObjectProviderTy valobj_provider, Status &err);
103
104 uint32_t AddResultVariable(const CompilerType &type, bool is_lvalue,
105 bool keep_in_memory,
106 PersistentVariableDelegate *delegate, Status &err);
107 uint32_t AddSymbol(const Symbol &symbol_sp, Status &err);
108 uint32_t AddRegister(const RegisterInfo &register_info, Status &err);
109
110 uint32_t GetStructAlignment() { return m_struct_alignment; }
111
112 uint32_t GetStructByteSize() { return m_current_offset; }
113
114 class Entity {
115 public:
116 Entity() = default;
117
118 virtual ~Entity() = default;
119
120 virtual void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
121 lldb::addr_t process_address, Status &err) = 0;
122 virtual void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
123 lldb::addr_t process_address,
124 lldb::addr_t frame_top,
125 lldb::addr_t frame_bottom, Status &err) = 0;
126 virtual void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address,
127 Log *log) = 0;
128 virtual void Wipe(IRMemoryMap &map, lldb::addr_t process_address) = 0;
129
130 uint32_t GetAlignment() { return m_alignment; }
131
132 uint32_t GetSize() { return m_size; }
133
134 uint32_t GetOffset() { return m_offset; }
135
136 void SetOffset(uint32_t offset) { m_offset = offset; }
137
138 protected:
139 uint32_t m_alignment = 1;
140 uint32_t m_size = 0;
141 uint32_t m_offset = 0;
142 };
143
144private:
145 uint32_t AddStructMember(Entity &entity);
146
147 typedef std::unique_ptr<Entity> EntityUP;
148 typedef std::vector<EntityUP> EntityVector;
149
150 DematerializerWP m_dematerializer_wp;
151 EntityVector m_entities;
152 uint32_t m_current_offset = 0;
153 uint32_t m_struct_alignment = 8;
154};
155
156} // namespace lldb_private
157
158#endif // LLDB_EXPRESSION_MATERIALIZER_H
159

source code of lldb/include/lldb/Expression/Materializer.h