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 "clang/AST/ASTContext.h" 13 #include "clang/AST/TemplateBase.h" 14 #include "clang/AST/Type.h" 15 16 #include "lldb/API/SBDefines.h" 17 #include "lldb/API/SBType.h" 18 #include "lldb/API/SBStream.h" 19 #include "lldb/Core/ConstString.h" 20 #include "lldb/Core/Log.h" 21 #include "lldb/Symbol/ClangASTContext.h" 22 #include "lldb/Symbol/ClangASTType.h" 23 #include "lldb/Symbol/Type.h" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 using namespace clang; 28 29 SBType::SBType() : 30 m_opaque_sp() 31 { 32 } 33 34 SBType::SBType (const ClangASTType &type) : 35 m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(), 36 type.GetOpaqueQualType()))) 37 { 38 } 39 40 SBType::SBType (const lldb::TypeSP &type_sp) : 41 m_opaque_sp(new TypeImpl(type_sp)) 42 { 43 } 44 45 SBType::SBType (const lldb::TypeImplSP &type_impl_sp) : 46 m_opaque_sp(type_impl_sp) 47 { 48 } 49 50 51 SBType::SBType (const SBType &rhs) : 52 m_opaque_sp() 53 { 54 if (this != &rhs) 55 { 56 m_opaque_sp = rhs.m_opaque_sp; 57 } 58 } 59 60 61 //SBType::SBType (TypeImpl* impl) : 62 // m_opaque_ap(impl) 63 //{} 64 // 65 bool 66 SBType::operator == (SBType &rhs) 67 { 68 if (IsValid() == false) 69 return !rhs.IsValid(); 70 71 return (rhs.m_opaque_sp->GetASTContext() == m_opaque_sp->GetASTContext()) && 72 (rhs.m_opaque_sp->GetOpaqueQualType() == m_opaque_sp->GetOpaqueQualType()); 73 } 74 75 bool 76 SBType::operator != (SBType &rhs) 77 { 78 if (IsValid() == false) 79 return rhs.IsValid(); 80 81 return (rhs.m_opaque_sp->GetASTContext() != m_opaque_sp->GetASTContext()) || 82 (rhs.m_opaque_sp->GetOpaqueQualType() != m_opaque_sp->GetOpaqueQualType()); 83 } 84 85 void 86 SBType::reset(const lldb::TypeImplSP &type_impl_sp) 87 { 88 m_opaque_sp = type_impl_sp; 89 } 90 91 SBType & 92 SBType::operator = (const SBType &rhs) 93 { 94 if (this != &rhs) 95 { 96 m_opaque_sp = rhs.m_opaque_sp; 97 } 98 return *this; 99 } 100 101 SBType::~SBType () 102 {} 103 104 TypeImpl & 105 SBType::ref () 106 { 107 if (m_opaque_sp.get() == NULL) 108 m_opaque_sp.reset (new TypeImpl()); 109 return *m_opaque_sp; 110 } 111 112 const TypeImpl & 113 SBType::ref () const 114 { 115 // "const SBAddress &addr" should already have checked "addr.IsValid()" 116 // prior to calling this function. In case you didn't we will assert 117 // and die to let you know. 118 assert (m_opaque_sp.get()); 119 return *m_opaque_sp; 120 } 121 122 bool 123 SBType::IsValid() const 124 { 125 if (m_opaque_sp.get() == NULL) 126 return false; 127 128 return m_opaque_sp->IsValid(); 129 } 130 131 size_t 132 SBType::GetByteSize() 133 { 134 if (!IsValid()) 135 return 0; 136 137 return ClangASTType::GetTypeByteSize(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 138 139 } 140 141 bool 142 SBType::IsPointerType() 143 { 144 if (!IsValid()) 145 return false; 146 147 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 148 const clang::Type* typePtr = qt.getTypePtrOrNull(); 149 150 if (typePtr) 151 return typePtr->isAnyPointerType(); 152 return false; 153 } 154 155 bool 156 SBType::IsReferenceType() 157 { 158 if (!IsValid()) 159 return false; 160 161 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 162 const clang::Type* typePtr = qt.getTypePtrOrNull(); 163 164 if (typePtr) 165 return typePtr->isReferenceType(); 166 return false; 167 } 168 169 SBType 170 SBType::GetPointerType() 171 { 172 if (!IsValid()) 173 return SBType(); 174 175 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 176 ClangASTContext::CreatePointerType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()))); 177 } 178 179 SBType 180 SBType::GetPointeeType() 181 { 182 if (!IsValid()) 183 return SBType(); 184 185 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 186 const clang::Type* typePtr = qt.getTypePtrOrNull(); 187 188 if (typePtr) 189 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr())); 190 return SBType(); 191 } 192 193 SBType 194 SBType::GetReferenceType() 195 { 196 if (!IsValid()) 197 return SBType(); 198 199 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 200 ClangASTContext::CreateLValueReferenceType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()))); 201 } 202 203 SBType 204 SBType::GetDereferencedType() 205 { 206 if (!IsValid()) 207 return SBType(); 208 209 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 210 211 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr())); 212 } 213 214 SBType 215 SBType::GetBasicType(lldb::BasicType type) 216 { 217 218 if (!IsValid()) 219 return SBType(); 220 221 clang::CanQualType base_type_qual; 222 223 switch (type) 224 { 225 case eBasicTypeChar: 226 base_type_qual = m_opaque_sp->GetASTContext()->CharTy; 227 break; 228 case eBasicTypeSignedChar: 229 base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy; 230 break; 231 case eBasicTypeShort: 232 base_type_qual = m_opaque_sp->GetASTContext()->ShortTy; 233 break; 234 case eBasicTypeUnsignedShort: 235 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy; 236 break; 237 case eBasicTypeInt: 238 base_type_qual = m_opaque_sp->GetASTContext()->IntTy; 239 break; 240 case eBasicTypeUnsignedInt: 241 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy; 242 break; 243 case eBasicTypeLong: 244 base_type_qual = m_opaque_sp->GetASTContext()->LongTy; 245 break; 246 case eBasicTypeUnsignedLong: 247 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy; 248 break; 249 case eBasicTypeBool: 250 base_type_qual = m_opaque_sp->GetASTContext()->BoolTy; 251 break; 252 case eBasicTypeFloat: 253 base_type_qual = m_opaque_sp->GetASTContext()->FloatTy; 254 break; 255 case eBasicTypeDouble: 256 base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy; 257 break; 258 case eBasicTypeObjCID: 259 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy; 260 break; 261 case eBasicTypeVoid: 262 base_type_qual = m_opaque_sp->GetASTContext()->VoidTy; 263 break; 264 case eBasicTypeWChar: 265 base_type_qual = m_opaque_sp->GetASTContext()->WCharTy; 266 break; 267 case eBasicTypeChar16: 268 base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty; 269 break; 270 case eBasicTypeChar32: 271 base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty; 272 break; 273 case eBasicTypeLongLong: 274 base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy; 275 break; 276 case eBasicTypeUnsignedLongLong: 277 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy; 278 break; 279 case eBasicTypeInt128: 280 base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty; 281 break; 282 case eBasicTypeUnsignedInt128: 283 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty; 284 break; 285 case eBasicTypeLongDouble: 286 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy; 287 break; 288 case eBasicTypeFloatComplex: 289 base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy; 290 break; 291 case eBasicTypeDoubleComplex: 292 base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy; 293 break; 294 case eBasicTypeLongDoubleComplex: 295 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy; 296 break; 297 case eBasicTypeObjCClass: 298 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy; 299 break; 300 case eBasicTypeObjCSel: 301 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy; 302 break; 303 default: 304 return SBType(); 305 } 306 307 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr())); 308 } 309 310 uint32_t 311 SBType::GetNumberOfDirectBaseClasses () 312 { 313 if (IsValid()) 314 return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 315 return 0; 316 } 317 318 uint32_t 319 SBType::GetNumberOfVirtualBaseClasses () 320 { 321 if (IsValid()) 322 return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 323 return 0; 324 } 325 326 uint32_t 327 SBType::GetNumberOfFields () 328 { 329 if (IsValid()) 330 return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 331 return 0; 332 } 333 334 SBTypeMember 335 SBType::GetDirectBaseClassAtIndex (uint32_t idx) 336 { 337 SBTypeMember sb_type_member; 338 if (IsValid()) 339 { 340 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 341 uint32_t byte_offset = 0; 342 clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &byte_offset); 343 if (clang_type) 344 { 345 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 346 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset)); 347 } 348 } 349 return sb_type_member; 350 351 } 352 353 SBTypeMember 354 SBType::GetVirtualBaseClassAtIndex (uint32_t idx) 355 { 356 SBTypeMember sb_type_member; 357 if (IsValid()) 358 { 359 uint32_t byte_offset = 0; 360 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 361 clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &byte_offset); 362 if (clang_type) 363 { 364 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 365 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset)); 366 } 367 } 368 return sb_type_member; 369 } 370 371 SBTypeMember 372 SBType::GetFieldAtIndex (uint32_t idx) 373 { 374 SBTypeMember sb_type_member; 375 if (IsValid()) 376 { 377 uint32_t byte_offset = 0; 378 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 379 std::string name_sstr; 380 clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &byte_offset); 381 if (clang_type) 382 { 383 ConstString name; 384 if (!name_sstr.empty()) 385 name.SetCString(name_sstr.c_str()); 386 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 387 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset, name)); 388 } 389 } 390 return sb_type_member; 391 } 392 393 const char* 394 SBType::GetName() 395 { 396 if (!IsValid()) 397 return ""; 398 399 return ClangASTType::GetConstTypeName(m_opaque_sp->GetOpaqueQualType()).GetCString(); 400 } 401 402 lldb::TypeClass 403 SBType::GetTypeClass () 404 { 405 if (IsValid()) 406 return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(), 407 m_opaque_sp->GetOpaqueQualType()); 408 return lldb::eTypeClassInvalid; 409 } 410 411 SBTypeList::SBTypeList() : 412 m_opaque_ap(new TypeListImpl()) 413 { 414 } 415 416 SBTypeList::SBTypeList(const SBTypeList& rhs) : 417 m_opaque_ap(new TypeListImpl()) 418 { 419 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 420 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 421 } 422 423 bool 424 SBTypeList::IsValid () 425 { 426 return (m_opaque_ap.get() != NULL); 427 } 428 429 SBTypeList& 430 SBTypeList::operator = (const SBTypeList& rhs) 431 { 432 if (this != &rhs) 433 { 434 m_opaque_ap.reset (new TypeListImpl()); 435 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 436 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 437 } 438 return *this; 439 } 440 441 void 442 SBTypeList::Append (SBType type) 443 { 444 if (type.IsValid()) 445 m_opaque_ap->Append (type.m_opaque_sp); 446 } 447 448 SBType 449 SBTypeList::GetTypeAtIndex(uint32_t index) 450 { 451 if (m_opaque_ap.get()) 452 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 453 return SBType(); 454 } 455 456 uint32_t 457 SBTypeList::GetSize() 458 { 459 return m_opaque_ap->GetSize(); 460 } 461 462 SBTypeList::~SBTypeList() 463 { 464 } 465 466 bool 467 SBType::IsPointerType (void *opaque_type) 468 { 469 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 470 471 bool ret_value = ClangASTContext::IsPointerType (opaque_type); 472 473 if (log) 474 log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false")); 475 476 return ret_value; 477 } 478 479 480 SBTypeMember::SBTypeMember() : 481 m_opaque_ap() 482 { 483 } 484 485 SBTypeMember::~SBTypeMember() 486 { 487 } 488 489 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : 490 m_opaque_ap() 491 { 492 if (this != &rhs) 493 { 494 if (rhs.IsValid()) 495 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 496 } 497 } 498 499 lldb::SBTypeMember& 500 SBTypeMember::operator = (const lldb::SBTypeMember& rhs) 501 { 502 if (this != &rhs) 503 { 504 if (rhs.IsValid()) 505 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 506 } 507 return *this; 508 } 509 510 bool 511 SBTypeMember::IsValid() const 512 { 513 return m_opaque_ap.get(); 514 } 515 516 const char * 517 SBTypeMember::GetName () 518 { 519 if (m_opaque_ap.get()) 520 return m_opaque_ap->GetName().GetCString(); 521 return NULL; 522 } 523 524 SBType 525 SBTypeMember::GetType () 526 { 527 SBType sb_type; 528 if (m_opaque_ap.get()) 529 { 530 sb_type.reset (m_opaque_ap->GetTypeImpl()); 531 } 532 return sb_type; 533 534 } 535 536 uint64_t 537 SBTypeMember::GetOffsetByteSize() 538 { 539 if (m_opaque_ap.get()) 540 return (m_opaque_ap->GetBitOffset() + 7) / 8u; 541 return 0; 542 } 543 544 void 545 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 546 { 547 m_opaque_ap.reset(type_member_impl); 548 } 549 550 TypeMemberImpl & 551 SBTypeMember::ref () 552 { 553 if (m_opaque_ap.get() == NULL) 554 m_opaque_ap.reset (new TypeMemberImpl()); 555 return *m_opaque_ap.get(); 556 } 557 558 const TypeMemberImpl & 559 SBTypeMember::ref () const 560 { 561 return *m_opaque_ap.get(); 562 } 563 564