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