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