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