aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Expression/Materializer.h
blob: 208a081339234f0d0374d224a4fcd82f83a0a8eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//===-- Materializer.h ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef lldb_Materializer_h
#define lldb_Materializer_h

#include "lldb/lldb-private-types.h"
#include "lldb/Core/Error.h"
#include "lldb/Expression/IRMemoryMap.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/StackFrame.h"

#include <vector>

namespace lldb_private
{
    
class Materializer
{
public:
    Materializer ();
    ~Materializer ();
    
    class Dematerializer
    {
    public:
        Dematerializer () :
            m_materializer(NULL),
            m_map(NULL),
            m_process_address(LLDB_INVALID_ADDRESS)
        {
        }
        
        ~Dematerializer ()
        {
            Wipe ();
        }
        
        void Dematerialize (Error &err,
                            lldb::ClangExpressionVariableSP &result_sp,
                            lldb::addr_t frame_top,
                            lldb::addr_t frame_bottom);
        
        void Wipe ();
        
        bool IsValid ()
        {
            return m_materializer && m_map && (m_process_address != LLDB_INVALID_ADDRESS);
        }
    private:
        friend class Materializer;

        Dematerializer (Materializer &materializer,
                        lldb::StackFrameSP &frame_sp,
                        IRMemoryMap &map,
                        lldb::addr_t process_address) :
            m_materializer(&materializer),
            m_map(&map),
            m_process_address(process_address)
        {
            if (frame_sp)
            {
                m_thread_wp = frame_sp->GetThread();
                m_stack_id = frame_sp->GetStackID();
            }
        }
        
        Materializer       *m_materializer;
        lldb::ThreadWP      m_thread_wp;
        StackID             m_stack_id;
        IRMemoryMap        *m_map;
        lldb::addr_t        m_process_address;
    };
    
    typedef std::shared_ptr<Dematerializer> DematerializerSP;
    typedef std::weak_ptr<Dematerializer> DematerializerWP;
    
    DematerializerSP Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
    
    uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
    uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
    uint32_t AddResultVariable (const TypeFromUser &type, bool is_lvalue, bool keep_in_memory, Error &err);
    uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
    uint32_t AddRegister (const RegisterInfo &register_info, Error &err);
    
    uint32_t GetStructAlignment ()
    {
        return m_struct_alignment;
    }
    
    uint32_t GetStructByteSize ()
    {
        return m_current_offset;
    }
    
    uint32_t GetResultOffset ()
    {
        if (m_result_entity)
            return m_result_entity->GetOffset();
        else
            return UINT32_MAX;
    }
    
    class Entity
    {
    public:
        Entity () :
            m_alignment(1),
            m_size(0),
            m_offset(0)
        {
        }
        
        virtual ~Entity ()
        {
        }
        
        virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
        virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
                                    lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) = 0;
        virtual void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) = 0;
        virtual void Wipe (IRMemoryMap &map, lldb::addr_t process_address) = 0;
        
        uint32_t GetAlignment ()
        {
            return m_alignment;
        }
        
        uint32_t GetSize ()
        {
            return m_size;
        }
        
        uint32_t GetOffset ()
        {
            return m_offset;
        }
        
        void SetOffset (uint32_t offset)
        {
            m_offset = offset;
        }
    protected:
        void SetSizeAndAlignmentFromType (ClangASTType &type);
        
        uint32_t    m_alignment;
        uint32_t    m_size;
        uint32_t    m_offset;
    };

private:
    uint32_t AddStructMember (Entity &entity);
    
    typedef std::unique_ptr<Entity>  EntityUP;
    typedef std::vector<EntityUP>   EntityVector;
    
    DematerializerWP                m_dematerializer_wp;
    EntityVector                    m_entities;
    Entity                         *m_result_entity;
    uint32_t                        m_current_offset;
    uint32_t                        m_struct_alignment;
};
    
}

#endif