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 (static_cast<clang::ASTContext *>(m_ast),
100                                                 m_type,
101                                                 omit_empty_base_classes);
102     return 0;
103 }
104 
105 
106 bool
107 SBType::GetChildAtIndex (bool omit_empty_base_classes, uint32_t idx, SBTypeMember &member)
108 {
109     void *child_clang_type = NULL;
110     std::string child_name;
111     uint32_t child_byte_size = 0;
112     int32_t child_byte_offset = 0;
113     uint32_t child_bitfield_bit_size = 0;
114     uint32_t child_bitfield_bit_offset = 0;
115     bool child_is_base_class = false;
116     bool child_is_deref_of_parent = false;
117 
118     if (IsValid ())
119     {
120 
121         child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (static_cast<clang::ASTContext *>(m_ast),
122                                                                       NULL,
123                                                                       m_type,
124                                                                       idx,
125                                                                       false, // transparent pointers
126                                                                       omit_empty_base_classes,
127                                                                       child_name,
128                                                                       child_byte_size,
129                                                                       child_byte_offset,
130                                                                       child_bitfield_bit_size,
131                                                                       child_bitfield_bit_offset,
132                                                                       child_is_base_class,
133                                                                       child_is_deref_of_parent);
134 
135     }
136 
137     if (child_clang_type)
138     {
139         member.m_ast = m_ast;
140         member.m_parent_type = m_type;
141         member.m_member_type = child_clang_type,
142         member.SetName (child_name.c_str());
143         member.m_offset = child_byte_offset;
144         member.m_bit_size = child_bitfield_bit_size;
145         member.m_bit_offset = child_bitfield_bit_offset;
146         member.m_is_base_class = child_is_base_class;
147         member.m_is_deref_of_paremt = child_is_deref_of_parent;
148     }
149     else
150     {
151         member.Clear();
152     }
153 
154     return child_clang_type != NULL;
155 }
156 
157 uint32_t
158 SBType::GetChildIndexForName (bool omit_empty_base_classes, const char *name)
159 {
160     return ClangASTContext::GetIndexOfChildWithName (static_cast<clang::ASTContext *>(m_ast),
161                                                      m_type,
162                                                      name,
163                                                      omit_empty_base_classes);
164 }
165 
166 bool
167 SBType::IsPointerType ()
168 {
169     return ClangASTContext::IsPointerType (m_type);
170 }
171 
172 SBType
173 SBType::GetPointeeType ()
174 {
175     void *pointee_type = NULL;
176     if (IsPointerType ())
177     {
178         pointee_type = ClangASTType::GetPointeeType (m_type);
179     }
180     return SBType (pointee_type ? m_ast : NULL, pointee_type);
181 }
182 
183 bool
184 SBType::GetDescription (SBStream &description)
185 {
186     const char *name = GetName();
187     uint64_t byte_size = GetByteSize();
188     uint64_t num_children = GetNumberChildren (true);
189     bool is_ptr = IsPointerType ();
190 
191     description.Printf ("type_name: %s, size: %d bytes", (name != NULL ? name : "<unknown type name>"), byte_size);
192     if (is_ptr)
193     {
194         SBType pointee_type = GetPointeeType();
195         const char *pointee_name = pointee_type.GetName();
196         description.Printf (", (* %s)", (pointee_name != NULL ? pointee_name : "<unknown type name>"));
197     }
198     else if (num_children > 0)
199     {
200         description.Printf (", %d members:\n", num_children);
201         for (uint32_t i = 0; i < num_children; ++i)
202         {
203             SBTypeMember field;
204             GetChildAtIndex (true, i, field);
205             const char *field_name = field.GetName();
206             SBType field_type = field.GetType();
207             const char *field_type_name = field_type.GetName();
208 
209             description.Printf ("     %s (type: %s", (field_name != NULL ? field_name : "<unknown member name>"),
210                                 (field_type_name != NULL ? field_type_name : "<unknown type name>"));
211 
212             if (field.IsBitfield())
213             {
214                 size_t width = field.GetBitfieldWidth ();
215                 description.Printf (" , %d bits", (int) width);
216             }
217             description.Printf (")\n");
218         }
219     }
220     return true;
221 }
222 
223 SBTypeMember::SBTypeMember () :
224     m_ast (NULL),
225     m_parent_type (NULL),
226     m_member_type (NULL),
227     m_member_name (NULL),
228     m_offset (0),
229     m_bit_size (0),
230     m_bit_offset (0),
231     m_is_base_class (false)
232 
233 {
234 }
235 
236 SBTypeMember::SBTypeMember (const SBTypeMember &rhs) :
237     m_ast (rhs.m_ast),
238     m_parent_type (rhs.m_parent_type),
239     m_member_type (rhs.m_member_type),
240     m_member_name (rhs.m_member_name),
241     m_offset (rhs.m_offset),
242     m_bit_size (rhs.m_bit_size),
243     m_bit_offset (rhs.m_bit_offset),
244     m_is_base_class (rhs.m_is_base_class)
245 {
246 }
247 
248 const SBTypeMember&
249 SBTypeMember::operator =(const SBTypeMember &rhs)
250 {
251     if (this != &rhs)
252     {
253         m_ast = rhs.m_ast;
254         m_parent_type = rhs.m_parent_type;
255         m_member_type = rhs.m_member_type;
256         m_member_name = rhs.m_member_name;
257         m_offset = rhs.m_offset;
258         m_bit_size = rhs.m_bit_size;
259         m_bit_offset = rhs.m_bit_offset;
260         m_is_base_class = rhs.m_is_base_class;
261     }
262     return *this;
263 }
264 
265 SBTypeMember::~SBTypeMember ()
266 {
267     SetName (NULL);
268 }
269 
270 void
271 SBTypeMember::SetName (const char *name)
272 {
273     if (m_member_name)
274         free (m_member_name);
275     if (name && name[0])
276         m_member_name = ::strdup (name);
277     else
278         m_member_name = NULL;
279 }
280 
281 void
282 SBTypeMember::Clear()
283 {
284     m_ast = NULL;
285     m_parent_type = NULL;
286     m_member_type = NULL;
287     SetName (NULL);
288     m_offset = 0;
289     m_bit_size  = 0;
290     m_bit_offset = 0;
291     m_is_base_class = false;
292 }
293 
294 bool
295 SBTypeMember::IsValid ()
296 {
297     return m_member_type != NULL;
298 }
299 
300 bool
301 SBTypeMember::IsBitfield ()
302 {
303     return m_bit_size != 0;
304 }
305 
306 size_t
307 SBTypeMember::GetBitfieldWidth ()
308 {
309     return m_bit_size;
310 }
311 
312 size_t
313 SBTypeMember::GetBitfieldOffset ()
314 {
315     return m_bit_offset;
316 }
317 
318 bool
319 SBTypeMember::IsBaseClass ()
320 {
321     return m_is_base_class;
322 }
323 
324 size_t
325 SBTypeMember::GetOffset ()
326 {
327     return m_offset;
328 }
329 
330 SBType
331 SBTypeMember::GetType()
332 {
333     return SBType (m_ast, m_member_type);
334 }
335 
336 SBType
337 SBTypeMember::GetParentType()
338 {
339     return SBType (m_ast, m_parent_type);
340 }
341 
342 
343 const char *
344 SBTypeMember::GetName ()
345 {
346     return m_member_name;
347 }
348 
349