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