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/Core/Stream.h" 22 #include "lldb/Symbol/ClangASTContext.h" 23 #include "lldb/Symbol/ClangASTType.h" 24 #include "lldb/Symbol/Type.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 using namespace clang; 29 30 SBType::SBType() : 31 m_opaque_sp() 32 { 33 } 34 35 SBType::SBType (const ClangASTType &type) : 36 m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(), 37 type.GetOpaqueQualType()))) 38 { 39 } 40 41 SBType::SBType (const lldb::TypeSP &type_sp) : 42 m_opaque_sp(new TypeImpl(type_sp)) 43 { 44 } 45 46 SBType::SBType (const lldb::TypeImplSP &type_impl_sp) : 47 m_opaque_sp(type_impl_sp) 48 { 49 } 50 51 52 SBType::SBType (const SBType &rhs) : 53 m_opaque_sp() 54 { 55 if (this != &rhs) 56 { 57 m_opaque_sp = rhs.m_opaque_sp; 58 } 59 } 60 61 62 //SBType::SBType (TypeImpl* impl) : 63 // m_opaque_ap(impl) 64 //{} 65 // 66 bool 67 SBType::operator == (SBType &rhs) 68 { 69 if (IsValid() == false) 70 return !rhs.IsValid(); 71 72 return (rhs.m_opaque_sp->GetASTContext() == m_opaque_sp->GetASTContext()) && 73 (rhs.m_opaque_sp->GetOpaqueQualType() == m_opaque_sp->GetOpaqueQualType()); 74 } 75 76 bool 77 SBType::operator != (SBType &rhs) 78 { 79 if (IsValid() == false) 80 return rhs.IsValid(); 81 82 return (rhs.m_opaque_sp->GetASTContext() != m_opaque_sp->GetASTContext()) || 83 (rhs.m_opaque_sp->GetOpaqueQualType() != m_opaque_sp->GetOpaqueQualType()); 84 } 85 86 lldb::TypeImplSP 87 SBType::GetSP () 88 { 89 return m_opaque_sp; 90 } 91 92 93 void 94 SBType::SetSP (const lldb::TypeImplSP &type_impl_sp) 95 { 96 m_opaque_sp = type_impl_sp; 97 } 98 99 SBType & 100 SBType::operator = (const SBType &rhs) 101 { 102 if (this != &rhs) 103 { 104 m_opaque_sp = rhs.m_opaque_sp; 105 } 106 return *this; 107 } 108 109 SBType::~SBType () 110 {} 111 112 TypeImpl & 113 SBType::ref () 114 { 115 if (m_opaque_sp.get() == NULL) 116 m_opaque_sp.reset (new TypeImpl()); 117 return *m_opaque_sp; 118 } 119 120 const TypeImpl & 121 SBType::ref () const 122 { 123 // "const SBAddress &addr" should already have checked "addr.IsValid()" 124 // prior to calling this function. In case you didn't we will assert 125 // and die to let you know. 126 assert (m_opaque_sp.get()); 127 return *m_opaque_sp; 128 } 129 130 bool 131 SBType::IsValid() const 132 { 133 if (m_opaque_sp.get() == NULL) 134 return false; 135 136 return m_opaque_sp->IsValid(); 137 } 138 139 size_t 140 SBType::GetByteSize() 141 { 142 if (!IsValid()) 143 return 0; 144 145 return ClangASTType::GetTypeByteSize(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 146 147 } 148 149 bool 150 SBType::IsPointerType() 151 { 152 if (!IsValid()) 153 return false; 154 155 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 156 const clang::Type* typePtr = qt.getTypePtrOrNull(); 157 158 if (typePtr) 159 return typePtr->isAnyPointerType(); 160 return false; 161 } 162 163 bool 164 SBType::IsReferenceType() 165 { 166 if (!IsValid()) 167 return false; 168 169 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 170 const clang::Type* typePtr = qt.getTypePtrOrNull(); 171 172 if (typePtr) 173 return typePtr->isReferenceType(); 174 return false; 175 } 176 177 SBType 178 SBType::GetPointerType() 179 { 180 if (!IsValid()) 181 return SBType(); 182 183 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 184 ClangASTContext::CreatePointerType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()))); 185 } 186 187 SBType 188 SBType::GetPointeeType() 189 { 190 if (!IsValid()) 191 return SBType(); 192 193 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 194 const clang::Type* typePtr = qt.getTypePtrOrNull(); 195 196 if (typePtr) 197 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr())); 198 return SBType(); 199 } 200 201 SBType 202 SBType::GetReferenceType() 203 { 204 if (!IsValid()) 205 return SBType(); 206 207 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 208 ClangASTContext::CreateLValueReferenceType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()))); 209 } 210 211 SBType 212 SBType::GetDereferencedType() 213 { 214 if (!IsValid()) 215 return SBType(); 216 217 QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()); 218 219 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr())); 220 } 221 222 lldb::SBType 223 SBType::GetUnqualifiedType() 224 { 225 if (!IsValid()) 226 return SBType(); 227 228 QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType())); 229 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getUnqualifiedType().getAsOpaquePtr())); 230 } 231 232 lldb::BasicType 233 SBType::GetBasicType() 234 { 235 if (IsValid()) 236 return ClangASTContext::GetLLDBBasicTypeEnumeration (m_opaque_sp->GetOpaqueQualType()); 237 return eBasicTypeInvalid; 238 } 239 240 SBType 241 SBType::GetBasicType(lldb::BasicType type) 242 { 243 if (!IsValid()) 244 return SBType(); 245 246 clang::QualType base_type_qual; 247 248 switch (type) 249 { 250 case eBasicTypeVoid: 251 base_type_qual = m_opaque_sp->GetASTContext()->VoidTy; 252 break; 253 case eBasicTypeChar: 254 base_type_qual = m_opaque_sp->GetASTContext()->CharTy; 255 break; 256 case eBasicTypeSignedChar: 257 base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy; 258 break; 259 case eBasicTypeUnsignedChar: 260 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedCharTy; 261 break; 262 case eBasicTypeWChar: 263 base_type_qual = m_opaque_sp->GetASTContext()->getWCharType(); 264 break; 265 case eBasicTypeSignedWChar: 266 base_type_qual = m_opaque_sp->GetASTContext()->getSignedWCharType(); 267 break; 268 case eBasicTypeUnsignedWChar: 269 base_type_qual = m_opaque_sp->GetASTContext()->getUnsignedWCharType(); 270 break; 271 case eBasicTypeChar16: 272 base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty; 273 break; 274 case eBasicTypeChar32: 275 base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty; 276 break; 277 case eBasicTypeShort: 278 base_type_qual = m_opaque_sp->GetASTContext()->ShortTy; 279 break; 280 case eBasicTypeUnsignedShort: 281 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy; 282 break; 283 case eBasicTypeInt: 284 base_type_qual = m_opaque_sp->GetASTContext()->IntTy; 285 break; 286 case eBasicTypeUnsignedInt: 287 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy; 288 break; 289 case eBasicTypeLong: 290 base_type_qual = m_opaque_sp->GetASTContext()->LongTy; 291 break; 292 case eBasicTypeUnsignedLong: 293 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy; 294 break; 295 case eBasicTypeLongLong: 296 base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy; 297 break; 298 case eBasicTypeUnsignedLongLong: 299 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy; 300 break; 301 case eBasicTypeInt128: 302 base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty; 303 break; 304 case eBasicTypeUnsignedInt128: 305 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty; 306 break; 307 case eBasicTypeBool: 308 base_type_qual = m_opaque_sp->GetASTContext()->BoolTy; 309 break; 310 case eBasicTypeHalf: 311 base_type_qual = m_opaque_sp->GetASTContext()->HalfTy; 312 break; 313 case eBasicTypeFloat: 314 base_type_qual = m_opaque_sp->GetASTContext()->FloatTy; 315 break; 316 case eBasicTypeDouble: 317 base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy; 318 break; 319 case eBasicTypeLongDouble: 320 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy; 321 break; 322 case eBasicTypeFloatComplex: 323 base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy; 324 break; 325 case eBasicTypeDoubleComplex: 326 base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy; 327 break; 328 case eBasicTypeLongDoubleComplex: 329 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy; 330 break; 331 case eBasicTypeObjCID: 332 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy; 333 break; 334 case eBasicTypeObjCClass: 335 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy; 336 break; 337 case eBasicTypeObjCSel: 338 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy; 339 break; 340 case eBasicTypeNullPtr: 341 base_type_qual = m_opaque_sp->GetASTContext()->NullPtrTy; 342 break; 343 default: 344 return SBType(); 345 } 346 347 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr())); 348 } 349 350 uint32_t 351 SBType::GetNumberOfDirectBaseClasses () 352 { 353 if (IsValid()) 354 return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 355 return 0; 356 } 357 358 uint32_t 359 SBType::GetNumberOfVirtualBaseClasses () 360 { 361 if (IsValid()) 362 return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 363 return 0; 364 } 365 366 uint32_t 367 SBType::GetNumberOfFields () 368 { 369 if (IsValid()) 370 return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 371 return 0; 372 } 373 374 bool 375 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) 376 { 377 Stream &strm = description.ref(); 378 379 if (m_opaque_sp) 380 { 381 m_opaque_sp->GetDescription (strm, description_level); 382 } 383 else 384 strm.PutCString ("No value"); 385 386 return true; 387 } 388 389 390 391 SBTypeMember 392 SBType::GetDirectBaseClassAtIndex (uint32_t idx) 393 { 394 SBTypeMember sb_type_member; 395 if (IsValid()) 396 { 397 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 398 uint32_t bit_offset = 0; 399 clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); 400 if (clang_type) 401 { 402 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 403 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); 404 } 405 } 406 return sb_type_member; 407 408 } 409 410 SBTypeMember 411 SBType::GetVirtualBaseClassAtIndex (uint32_t idx) 412 { 413 SBTypeMember sb_type_member; 414 if (IsValid()) 415 { 416 uint32_t bit_offset = 0; 417 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 418 clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); 419 if (clang_type) 420 { 421 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 422 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); 423 } 424 } 425 return sb_type_member; 426 } 427 428 SBTypeMember 429 SBType::GetFieldAtIndex (uint32_t idx) 430 { 431 SBTypeMember sb_type_member; 432 if (IsValid()) 433 { 434 uint64_t bit_offset = 0; 435 uint32_t bitfield_bit_size = 0; 436 bool is_bitfield = false; 437 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 438 std::string name_sstr; 439 clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield); 440 if (clang_type) 441 { 442 ConstString name; 443 if (!name_sstr.empty()) 444 name.SetCString(name_sstr.c_str()); 445 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 446 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name, bitfield_bit_size, is_bitfield)); 447 } 448 } 449 return sb_type_member; 450 } 451 452 bool 453 SBType::IsTypeComplete() 454 { 455 if (!IsValid()) 456 return false; 457 458 return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 459 } 460 461 const char* 462 SBType::GetName() 463 { 464 if (!IsValid()) 465 return ""; 466 467 return ClangASTType::GetConstTypeName(m_opaque_sp->GetASTContext(), 468 m_opaque_sp->GetOpaqueQualType()).GetCString(); 469 } 470 471 lldb::TypeClass 472 SBType::GetTypeClass () 473 { 474 if (IsValid()) 475 return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(), 476 m_opaque_sp->GetOpaqueQualType()); 477 return lldb::eTypeClassInvalid; 478 } 479 480 uint32_t 481 SBType::GetNumberOfTemplateArguments () 482 { 483 if (IsValid()) 484 { 485 return ClangASTContext::GetNumTemplateArguments (m_opaque_sp->GetASTContext(), 486 m_opaque_sp->GetOpaqueQualType()); 487 } 488 return 0; 489 } 490 491 lldb::SBType 492 SBType::GetTemplateArgumentType (uint32_t idx) 493 { 494 if (IsValid()) 495 { 496 TemplateArgumentKind kind = eTemplateArgumentKindNull; 497 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 498 ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), 499 m_opaque_sp->GetOpaqueQualType(), 500 idx, 501 kind))); 502 } 503 return SBType(); 504 } 505 506 507 lldb::TemplateArgumentKind 508 SBType::GetTemplateArgumentKind (uint32_t idx) 509 { 510 TemplateArgumentKind kind = eTemplateArgumentKindNull; 511 if (IsValid()) 512 { 513 ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), 514 m_opaque_sp->GetOpaqueQualType(), 515 idx, 516 kind); 517 } 518 return kind; 519 } 520 521 522 523 524 SBTypeList::SBTypeList() : 525 m_opaque_ap(new TypeListImpl()) 526 { 527 } 528 529 SBTypeList::SBTypeList(const SBTypeList& rhs) : 530 m_opaque_ap(new TypeListImpl()) 531 { 532 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 533 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 534 } 535 536 bool 537 SBTypeList::IsValid () 538 { 539 return (m_opaque_ap.get() != NULL); 540 } 541 542 SBTypeList& 543 SBTypeList::operator = (const SBTypeList& rhs) 544 { 545 if (this != &rhs) 546 { 547 m_opaque_ap.reset (new TypeListImpl()); 548 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 549 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 550 } 551 return *this; 552 } 553 554 void 555 SBTypeList::Append (SBType type) 556 { 557 if (type.IsValid()) 558 m_opaque_ap->Append (type.m_opaque_sp); 559 } 560 561 SBType 562 SBTypeList::GetTypeAtIndex(uint32_t index) 563 { 564 if (m_opaque_ap.get()) 565 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 566 return SBType(); 567 } 568 569 uint32_t 570 SBTypeList::GetSize() 571 { 572 return m_opaque_ap->GetSize(); 573 } 574 575 SBTypeList::~SBTypeList() 576 { 577 } 578 579 bool 580 SBType::IsPointerType (void *opaque_type) 581 { 582 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 583 584 bool ret_value = ClangASTContext::IsPointerType (opaque_type); 585 586 if (log) 587 log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false")); 588 589 return ret_value; 590 } 591 592 593 SBTypeMember::SBTypeMember() : 594 m_opaque_ap() 595 { 596 } 597 598 SBTypeMember::~SBTypeMember() 599 { 600 } 601 602 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : 603 m_opaque_ap() 604 { 605 if (this != &rhs) 606 { 607 if (rhs.IsValid()) 608 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 609 } 610 } 611 612 lldb::SBTypeMember& 613 SBTypeMember::operator = (const lldb::SBTypeMember& rhs) 614 { 615 if (this != &rhs) 616 { 617 if (rhs.IsValid()) 618 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 619 } 620 return *this; 621 } 622 623 bool 624 SBTypeMember::IsValid() const 625 { 626 return m_opaque_ap.get(); 627 } 628 629 const char * 630 SBTypeMember::GetName () 631 { 632 if (m_opaque_ap.get()) 633 return m_opaque_ap->GetName().GetCString(); 634 return NULL; 635 } 636 637 SBType 638 SBTypeMember::GetType () 639 { 640 SBType sb_type; 641 if (m_opaque_ap.get()) 642 { 643 sb_type.SetSP (m_opaque_ap->GetTypeImpl()); 644 } 645 return sb_type; 646 647 } 648 649 uint64_t 650 SBTypeMember::GetOffsetInBytes() 651 { 652 if (m_opaque_ap.get()) 653 return m_opaque_ap->GetBitOffset() / 8u; 654 return 0; 655 } 656 657 uint64_t 658 SBTypeMember::GetOffsetInBits() 659 { 660 if (m_opaque_ap.get()) 661 return m_opaque_ap->GetBitOffset(); 662 return 0; 663 } 664 665 bool 666 SBTypeMember::IsBitfield() 667 { 668 if (m_opaque_ap.get()) 669 return m_opaque_ap->GetIsBitfield(); 670 return false; 671 } 672 673 uint32_t 674 SBTypeMember::GetBitfieldSizeInBits() 675 { 676 if (m_opaque_ap.get()) 677 return m_opaque_ap->GetBitfieldBitSize(); 678 return 0; 679 } 680 681 682 bool 683 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) 684 { 685 Stream &strm = description.ref(); 686 687 if (m_opaque_ap.get()) 688 { 689 const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); 690 const uint32_t byte_offset = bit_offset / 8u; 691 const uint32_t byte_bit_offset = bit_offset % 8u; 692 const char *name = m_opaque_ap->GetName().GetCString(); 693 if (byte_bit_offset) 694 strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset); 695 else 696 strm.Printf ("+%u: (", byte_offset); 697 698 TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl()); 699 if (type_impl_sp) 700 type_impl_sp->GetDescription(strm, description_level); 701 702 strm.Printf (") %s", name); 703 if (m_opaque_ap->GetIsBitfield()) 704 { 705 const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); 706 strm.Printf (" : %u", bitfield_bit_size); 707 } 708 } 709 else 710 { 711 strm.PutCString ("No value"); 712 } 713 return true; 714 } 715 716 717 void 718 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 719 { 720 m_opaque_ap.reset(type_member_impl); 721 } 722 723 TypeMemberImpl & 724 SBTypeMember::ref () 725 { 726 if (m_opaque_ap.get() == NULL) 727 m_opaque_ap.reset (new TypeMemberImpl()); 728 return *m_opaque_ap.get(); 729 } 730 731 const TypeMemberImpl & 732 SBTypeMember::ref () const 733 { 734 return *m_opaque_ap.get(); 735 } 736