1 //===-- Materializer.h ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_Materializer_h
11 #define liblldb_Materializer_h
12 
13 #include <memory>
14 #include <vector>
15 
16 #include "lldb/Expression/IRMemoryMap.h"
17 #include "lldb/Symbol/TaggedASTType.h"
18 #include "lldb/Target/StackFrame.h"
19 #include "lldb/Utility/Status.h"
20 #include "lldb/lldb-private-types.h"
21 
22 namespace lldb_private {
23 
24 class Materializer {
25 public:
26   Materializer();
27   ~Materializer();
28 
29   class Dematerializer {
30   public:
Dematerializer()31     Dematerializer()
32         : m_materializer(nullptr), m_map(nullptr),
33           m_process_address(LLDB_INVALID_ADDRESS) {}
34 
~Dematerializer()35     ~Dematerializer() { Wipe(); }
36 
37     void Dematerialize(Status &err, lldb::addr_t frame_top,
38                        lldb::addr_t frame_bottom);
39 
40     void Wipe();
41 
IsValid()42     bool IsValid() {
43       return m_materializer && m_map &&
44              (m_process_address != LLDB_INVALID_ADDRESS);
45     }
46 
47   private:
48     friend class Materializer;
49 
Dematerializer(Materializer & materializer,lldb::StackFrameSP & frame_sp,IRMemoryMap & map,lldb::addr_t process_address)50     Dematerializer(Materializer &materializer, lldb::StackFrameSP &frame_sp,
51                    IRMemoryMap &map, lldb::addr_t process_address)
52         : m_materializer(&materializer), m_map(&map),
53           m_process_address(process_address) {
54       if (frame_sp) {
55         m_thread_wp = frame_sp->GetThread();
56         m_stack_id = frame_sp->GetStackID();
57       }
58     }
59 
60     Materializer *m_materializer;
61     lldb::ThreadWP m_thread_wp;
62     StackID m_stack_id;
63     IRMemoryMap *m_map;
64     lldb::addr_t m_process_address;
65   };
66 
67   typedef std::shared_ptr<Dematerializer> DematerializerSP;
68   typedef std::weak_ptr<Dematerializer> DematerializerWP;
69 
70   DematerializerSP Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
71                                lldb::addr_t process_address, Status &err);
72 
73   class PersistentVariableDelegate {
74   public:
75     virtual ~PersistentVariableDelegate();
76     virtual ConstString GetName() = 0;
77     virtual void DidDematerialize(lldb::ExpressionVariableSP &variable) = 0;
78   };
79 
80   uint32_t
81   AddPersistentVariable(lldb::ExpressionVariableSP &persistent_variable_sp,
82                         PersistentVariableDelegate *delegate, Status &err);
83   uint32_t AddVariable(lldb::VariableSP &variable_sp, Status &err);
84   uint32_t AddResultVariable(const CompilerType &type, bool is_lvalue,
85                              bool keep_in_memory,
86                              PersistentVariableDelegate *delegate, Status &err);
87   uint32_t AddSymbol(const Symbol &symbol_sp, Status &err);
88   uint32_t AddRegister(const RegisterInfo &register_info, Status &err);
89 
GetStructAlignment()90   uint32_t GetStructAlignment() { return m_struct_alignment; }
91 
GetStructByteSize()92   uint32_t GetStructByteSize() { return m_current_offset; }
93 
94   class Entity {
95   public:
Entity()96     Entity() : m_alignment(1), m_size(0), m_offset(0) {}
97 
98     virtual ~Entity() = default;
99 
100     virtual void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
101                              lldb::addr_t process_address, Status &err) = 0;
102     virtual void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
103                                lldb::addr_t process_address,
104                                lldb::addr_t frame_top,
105                                lldb::addr_t frame_bottom, Status &err) = 0;
106     virtual void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address,
107                            Log *log) = 0;
108     virtual void Wipe(IRMemoryMap &map, lldb::addr_t process_address) = 0;
109 
GetAlignment()110     uint32_t GetAlignment() { return m_alignment; }
111 
GetSize()112     uint32_t GetSize() { return m_size; }
113 
GetOffset()114     uint32_t GetOffset() { return m_offset; }
115 
SetOffset(uint32_t offset)116     void SetOffset(uint32_t offset) { m_offset = offset; }
117 
118   protected:
119     void SetSizeAndAlignmentFromType(CompilerType &type);
120 
121     uint32_t m_alignment;
122     uint32_t m_size;
123     uint32_t m_offset;
124   };
125 
126 private:
127   uint32_t AddStructMember(Entity &entity);
128 
129   typedef std::unique_ptr<Entity> EntityUP;
130   typedef std::vector<EntityUP> EntityVector;
131 
132   DematerializerWP m_dematerializer_wp;
133   EntityVector m_entities;
134   uint32_t m_current_offset;
135   uint32_t m_struct_alignment;
136 };
137 
138 } // namespace lldb_private
139 
140 #endif // liblldb_Materializer_h
141