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