SBType.cpp revision d6dfe043486507c06a0559cef7171ae6c3cc1a97
1//===-- SBType.cpp ----------------------------------------------*- 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#include <string.h>
11
12#include "lldb/API/SBType.h"
13#include "lldb/API/SBStream.h"
14#include "lldb/Core/ConstString.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Symbol/ClangASTContext.h"
17#include "lldb/Symbol/ClangASTType.h"
18
19using namespace lldb;
20using namespace lldb_private;
21
22
23bool
24SBType::IsPointerType (void *opaque_type)
25{
26    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
27
28    //if (log)
29    //    log->Printf ("SBType::IsPointerType (%p)", opaque_type);
30
31    bool ret_value = ClangASTContext::IsPointerType (opaque_type);
32
33    if (log)
34        log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false"));
35
36    return ret_value;
37}
38
39
40SBType::SBType (void *ast, void *clang_type) :
41    m_ast (ast),
42    m_type (clang_type)
43{
44}
45
46SBType::SBType (const SBType &rhs) :
47    m_ast (rhs.m_ast),
48    m_type (rhs.m_type)
49{
50}
51
52const SBType &
53SBType::operator =(const SBType &rhs)
54{
55    m_ast = rhs.m_ast;
56    m_type = rhs.m_type;
57    return *this;
58}
59
60SBType::~SBType ()
61{
62}
63
64bool
65SBType::IsValid ()
66{
67    return m_ast != NULL && m_type != NULL;
68}
69
70const char *
71SBType::GetName ()
72{
73    if (IsValid ())
74        return ClangASTType::GetClangTypeName (m_type).AsCString(NULL);
75    return NULL;
76}
77
78uint64_t
79SBType::GetByteSize()
80{
81    if (IsValid ())
82        return ClangASTType::GetClangTypeBitWidth (static_cast<clang::ASTContext *>(m_ast), m_type);
83    return NULL;
84}
85
86Encoding
87SBType::GetEncoding (uint32_t &count)
88{
89    if (IsValid ())
90        return ClangASTType::GetEncoding (m_type, count);
91    count = 0;
92    return eEncodingInvalid;
93}
94
95uint64_t
96SBType::GetNumberChildren (bool omit_empty_base_classes)
97{
98    if (IsValid ())
99        return ClangASTContext::GetNumChildren(m_type, omit_empty_base_classes);
100    return 0;
101}
102
103
104bool
105SBType::GetChildAtIndex (bool omit_empty_base_classes, uint32_t idx, SBTypeMember &member)
106{
107    void *child_clang_type = NULL;
108    std::string child_name;
109    uint32_t child_byte_size = 0;
110    int32_t child_byte_offset = 0;
111    uint32_t child_bitfield_bit_size = 0;
112    uint32_t child_bitfield_bit_offset = 0;
113    bool child_is_base_class = false;
114
115    if (IsValid ())
116    {
117
118        child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (static_cast<clang::ASTContext *>(m_ast),
119                                                                      NULL,
120                                                                      m_type,
121                                                                      idx,
122                                                                      false, // transparent pointers
123                                                                      omit_empty_base_classes,
124                                                                      child_name,
125                                                                      child_byte_size,
126                                                                      child_byte_offset,
127                                                                      child_bitfield_bit_size,
128                                                                      child_bitfield_bit_offset,
129                                                                      child_is_base_class);
130
131    }
132
133    if (child_clang_type)
134    {
135        member.m_ast = m_ast;
136        member.m_parent_type = m_type;
137        member.m_member_type = child_clang_type,
138        member.SetName (child_name.c_str());
139        member.m_offset = child_byte_offset;
140        member.m_bit_size = child_bitfield_bit_size;
141        member.m_bit_offset = child_bitfield_bit_offset;
142        member.m_is_base_class = child_is_base_class;
143    }
144    else
145    {
146        member.Clear();
147    }
148
149    return child_clang_type != NULL;
150}
151
152uint32_t
153SBType::GetChildIndexForName (bool omit_empty_base_classes, const char *name)
154{
155    return ClangASTContext::GetIndexOfChildWithName (static_cast<clang::ASTContext *>(m_ast),
156                                                     m_type,
157                                                     name,
158                                                     omit_empty_base_classes);
159}
160
161bool
162SBType::IsPointerType ()
163{
164    return ClangASTContext::IsPointerType (m_type);
165}
166
167SBType
168SBType::GetPointeeType ()
169{
170    void *pointee_type = NULL;
171    if (IsPointerType ())
172    {
173        pointee_type = ClangASTType::GetPointeeType (m_type);
174    }
175    return SBType (pointee_type ? m_ast : NULL, pointee_type);
176}
177
178bool
179SBType::GetDescription (SBStream &description)
180{
181    const char *name = GetName();
182    uint64_t byte_size = GetByteSize();
183    uint64_t num_children = GetNumberChildren (true);
184    bool is_ptr = IsPointerType ();
185
186    description.Printf ("type_name: %s, size: %d bytes", (name != NULL ? name : "<unknown type name>"), byte_size);
187    if (is_ptr)
188    {
189        SBType pointee_type = GetPointeeType();
190        const char *pointee_name = pointee_type.GetName();
191        description.Printf (", (* %s)", (pointee_name != NULL ? pointee_name : "<unknown type name>"));
192    }
193    else if (num_children > 0)
194    {
195        description.Printf (", %d members:\n", num_children);
196        for (uint32_t i = 0; i < num_children; ++i)
197        {
198            SBTypeMember field;
199            GetChildAtIndex (true, i, field);
200            const char *field_name = field.GetName();
201            SBType field_type = field.GetType();
202            const char *field_type_name = field_type.GetName();
203
204            description.Printf ("     %s (type: %s", (field_name != NULL ? field_name : "<unknown member name>"),
205                                (field_type_name != NULL ? field_type_name : "<unknown type name>"));
206
207            if (field.IsBitfield())
208            {
209                size_t width = field.GetBitfieldWidth ();
210                description.Printf (" , %d bits", (int) width);
211            }
212            description.Printf (")\n");
213        }
214    }
215    return true;
216}
217
218SBTypeMember::SBTypeMember () :
219    m_ast (NULL),
220    m_parent_type (NULL),
221    m_member_type (NULL),
222    m_member_name (NULL),
223    m_offset (0),
224    m_bit_size (0),
225    m_bit_offset (0),
226    m_is_base_class (false)
227
228{
229}
230
231SBTypeMember::SBTypeMember (const SBTypeMember &rhs) :
232    m_ast (rhs.m_ast),
233    m_parent_type (rhs.m_parent_type),
234    m_member_type (rhs.m_member_type),
235    m_member_name (rhs.m_member_name),
236    m_offset (rhs.m_offset),
237    m_bit_size (rhs.m_bit_size),
238    m_bit_offset (rhs.m_bit_offset),
239    m_is_base_class (rhs.m_is_base_class)
240{
241}
242
243const SBTypeMember&
244SBTypeMember::operator =(const SBTypeMember &rhs)
245{
246    if (this != &rhs)
247    {
248        m_ast = rhs.m_ast;
249        m_parent_type = rhs.m_parent_type;
250        m_member_type = rhs.m_member_type;
251        m_member_name = rhs.m_member_name;
252        m_offset = rhs.m_offset;
253        m_bit_size = rhs.m_bit_size;
254        m_bit_offset = rhs.m_bit_offset;
255        m_is_base_class = rhs.m_is_base_class;
256    }
257    return *this;
258}
259
260SBTypeMember::~SBTypeMember ()
261{
262    SetName (NULL);
263}
264
265void
266SBTypeMember::SetName (const char *name)
267{
268    if (m_member_name)
269        free (m_member_name);
270    if (name && name[0])
271        m_member_name = ::strdup (name);
272    else
273        m_member_name = NULL;
274}
275
276void
277SBTypeMember::Clear()
278{
279    m_ast = NULL;
280    m_parent_type = NULL;
281    m_member_type = NULL;
282    SetName (NULL);
283    m_offset = 0;
284    m_bit_size  = 0;
285    m_bit_offset = 0;
286    m_is_base_class = false;
287}
288
289bool
290SBTypeMember::IsValid ()
291{
292    return m_member_type != NULL;
293}
294
295bool
296SBTypeMember::IsBitfield ()
297{
298    return m_bit_size != 0;
299}
300
301size_t
302SBTypeMember::GetBitfieldWidth ()
303{
304    return m_bit_size;
305}
306
307size_t
308SBTypeMember::GetBitfieldOffset ()
309{
310    return m_bit_offset;
311}
312
313bool
314SBTypeMember::IsBaseClass ()
315{
316    return m_is_base_class;
317}
318
319size_t
320SBTypeMember::GetOffset ()
321{
322    return m_offset;
323}
324
325SBType
326SBTypeMember::GetType()
327{
328    return SBType (m_ast, m_member_type);
329}
330
331SBType
332SBTypeMember::GetParentType()
333{
334    return SBType (m_ast, m_parent_type);
335}
336
337
338const char *
339SBTypeMember::GetName ()
340{
341    return m_member_name;
342}
343
344