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 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 
23 bool
24 SBType::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 
40 SBType::SBType (void *ast, void *clang_type) :
41     m_ast (ast),
42     m_type (clang_type)
43 {
44 }
45 
46 SBType::SBType (const SBType &rhs) :
47     m_ast (rhs.m_ast),
48     m_type (rhs.m_type)
49 {
50 }
51 
52 const SBType &
53 SBType::operator =(const SBType &rhs)
54 {
55     m_ast = rhs.m_ast;
56     m_type = rhs.m_type;
57     return *this;
58 }
59 
60 SBType::~SBType ()
61 {
62 }
63 
64 bool
65 SBType::IsValid ()
66 {
67     return m_ast != NULL && m_type != NULL;
68 }
69 
70 const char *
71 SBType::GetName ()
72 {
73     if (IsValid ())
74         return ClangASTType::GetClangTypeName (m_type).AsCString(NULL);
75     return NULL;
76 }
77 
78 uint64_t
79 SBType::GetByteSize()
80 {
81     if (IsValid ())
82         return ClangASTType::GetClangTypeBitWidth (static_cast<clang::ASTContext *>(m_ast), m_type);
83     return NULL;
84 }
85 
86 Encoding
87 SBType::GetEncoding (uint32_t &count)
88 {
89     if (IsValid ())
90         return ClangASTType::GetEncoding (m_type, count);
91     count = 0;
92     return eEncodingInvalid;
93 }
94 
95 uint64_t
96 SBType::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 
104 bool
105 SBType::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 
152 uint32_t
153 SBType::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 
161 bool
162 SBType::IsPointerType ()
163 {
164     return ClangASTContext::IsPointerType (m_type);
165 }
166 
167 SBType
168 SBType::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 
178 bool
179 SBType::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 
218 SBTypeMember::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 
231 SBTypeMember::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 
243 const SBTypeMember&
244 SBTypeMember::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 
260 SBTypeMember::~SBTypeMember ()
261 {
262     SetName (NULL);
263 }
264 
265 void
266 SBTypeMember::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 
276 void
277 SBTypeMember::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 
289 bool
290 SBTypeMember::IsValid ()
291 {
292     return m_member_type != NULL;
293 }
294 
295 bool
296 SBTypeMember::IsBitfield ()
297 {
298     return m_bit_size != 0;
299 }
300 
301 size_t
302 SBTypeMember::GetBitfieldWidth ()
303 {
304     return m_bit_size;
305 }
306 
307 size_t
308 SBTypeMember::GetBitfieldOffset ()
309 {
310     return m_bit_offset;
311 }
312 
313 bool
314 SBTypeMember::IsBaseClass ()
315 {
316     return m_is_base_class;
317 }
318 
319 size_t
320 SBTypeMember::GetOffset ()
321 {
322     return m_offset;
323 }
324 
325 SBType
326 SBTypeMember::GetType()
327 {
328     return SBType (m_ast, m_member_type);
329 }
330 
331 SBType
332 SBTypeMember::GetParentType()
333 {
334     return SBType (m_ast, m_parent_type);
335 }
336 
337 
338 const char *
339 SBTypeMember::GetName ()
340 {
341     return m_member_name;
342 }
343 
344