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