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 233 SBType 234 SBType::GetBasicType(lldb::BasicType type) 235 { 236 237 if (!IsValid()) 238 return SBType(); 239 240 clang::CanQualType base_type_qual; 241 242 switch (type) 243 { 244 case eBasicTypeChar: 245 base_type_qual = m_opaque_sp->GetASTContext()->CharTy; 246 break; 247 case eBasicTypeSignedChar: 248 base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy; 249 break; 250 case eBasicTypeShort: 251 base_type_qual = m_opaque_sp->GetASTContext()->ShortTy; 252 break; 253 case eBasicTypeUnsignedShort: 254 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy; 255 break; 256 case eBasicTypeInt: 257 base_type_qual = m_opaque_sp->GetASTContext()->IntTy; 258 break; 259 case eBasicTypeUnsignedInt: 260 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy; 261 break; 262 case eBasicTypeLong: 263 base_type_qual = m_opaque_sp->GetASTContext()->LongTy; 264 break; 265 case eBasicTypeUnsignedLong: 266 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy; 267 break; 268 case eBasicTypeBool: 269 base_type_qual = m_opaque_sp->GetASTContext()->BoolTy; 270 break; 271 case eBasicTypeFloat: 272 base_type_qual = m_opaque_sp->GetASTContext()->FloatTy; 273 break; 274 case eBasicTypeDouble: 275 base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy; 276 break; 277 case eBasicTypeObjCID: 278 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy; 279 break; 280 case eBasicTypeVoid: 281 base_type_qual = m_opaque_sp->GetASTContext()->VoidTy; 282 break; 283 case eBasicTypeWChar: 284 base_type_qual = m_opaque_sp->GetASTContext()->WCharTy; 285 break; 286 case eBasicTypeChar16: 287 base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty; 288 break; 289 case eBasicTypeChar32: 290 base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty; 291 break; 292 case eBasicTypeLongLong: 293 base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy; 294 break; 295 case eBasicTypeUnsignedLongLong: 296 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy; 297 break; 298 case eBasicTypeInt128: 299 base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty; 300 break; 301 case eBasicTypeUnsignedInt128: 302 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty; 303 break; 304 case eBasicTypeLongDouble: 305 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy; 306 break; 307 case eBasicTypeFloatComplex: 308 base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy; 309 break; 310 case eBasicTypeDoubleComplex: 311 base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy; 312 break; 313 case eBasicTypeLongDoubleComplex: 314 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy; 315 break; 316 case eBasicTypeObjCClass: 317 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy; 318 break; 319 case eBasicTypeObjCSel: 320 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy; 321 break; 322 default: 323 return SBType(); 324 } 325 326 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr())); 327 } 328 329 uint32_t 330 SBType::GetNumberOfDirectBaseClasses () 331 { 332 if (IsValid()) 333 return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 334 return 0; 335 } 336 337 uint32_t 338 SBType::GetNumberOfVirtualBaseClasses () 339 { 340 if (IsValid()) 341 return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 342 return 0; 343 } 344 345 uint32_t 346 SBType::GetNumberOfFields () 347 { 348 if (IsValid()) 349 return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 350 return 0; 351 } 352 353 bool 354 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) 355 { 356 Stream &strm = description.ref(); 357 358 if (m_opaque_sp) 359 { 360 m_opaque_sp->GetDescription (strm, description_level); 361 } 362 else 363 strm.PutCString ("No value"); 364 365 return true; 366 } 367 368 369 370 SBTypeMember 371 SBType::GetDirectBaseClassAtIndex (uint32_t idx) 372 { 373 SBTypeMember sb_type_member; 374 if (IsValid()) 375 { 376 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 377 uint32_t bit_offset = 0; 378 clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); 379 if (clang_type) 380 { 381 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 382 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); 383 } 384 } 385 return sb_type_member; 386 387 } 388 389 SBTypeMember 390 SBType::GetVirtualBaseClassAtIndex (uint32_t idx) 391 { 392 SBTypeMember sb_type_member; 393 if (IsValid()) 394 { 395 uint32_t bit_offset = 0; 396 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 397 clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); 398 if (clang_type) 399 { 400 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 401 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); 402 } 403 } 404 return sb_type_member; 405 } 406 407 SBTypeMember 408 SBType::GetFieldAtIndex (uint32_t idx) 409 { 410 SBTypeMember sb_type_member; 411 if (IsValid()) 412 { 413 uint64_t bit_offset = 0; 414 uint32_t bitfield_bit_size = 0; 415 bool is_bitfield = false; 416 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 417 std::string name_sstr; 418 clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield); 419 if (clang_type) 420 { 421 ConstString name; 422 if (!name_sstr.empty()) 423 name.SetCString(name_sstr.c_str()); 424 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 425 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name, bitfield_bit_size, is_bitfield)); 426 } 427 } 428 return sb_type_member; 429 } 430 431 bool 432 SBType::IsTypeComplete() 433 { 434 if (!IsValid()) 435 return false; 436 437 return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 438 } 439 440 const char* 441 SBType::GetName() 442 { 443 if (!IsValid()) 444 return ""; 445 446 return ClangASTType::GetConstTypeName(m_opaque_sp->GetASTContext(), 447 m_opaque_sp->GetOpaqueQualType()).GetCString(); 448 } 449 450 lldb::TypeClass 451 SBType::GetTypeClass () 452 { 453 if (IsValid()) 454 return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(), 455 m_opaque_sp->GetOpaqueQualType()); 456 return lldb::eTypeClassInvalid; 457 } 458 459 uint32_t 460 SBType::GetNumberOfTemplateArguments () 461 { 462 if (IsValid()) 463 { 464 return ClangASTContext::GetNumTemplateArguments (m_opaque_sp->GetASTContext(), 465 m_opaque_sp->GetOpaqueQualType()); 466 } 467 return 0; 468 } 469 470 lldb::SBType 471 SBType::GetTemplateArgumentType (uint32_t idx) 472 { 473 if (IsValid()) 474 { 475 TemplateArgumentKind kind = eTemplateArgumentKindNull; 476 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 477 ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), 478 m_opaque_sp->GetOpaqueQualType(), 479 idx, 480 kind))); 481 } 482 return SBType(); 483 } 484 485 486 lldb::TemplateArgumentKind 487 SBType::GetTemplateArgumentKind (uint32_t idx) 488 { 489 TemplateArgumentKind kind = eTemplateArgumentKindNull; 490 if (IsValid()) 491 { 492 ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), 493 m_opaque_sp->GetOpaqueQualType(), 494 idx, 495 kind); 496 } 497 return kind; 498 } 499 500 501 502 503 SBTypeList::SBTypeList() : 504 m_opaque_ap(new TypeListImpl()) 505 { 506 } 507 508 SBTypeList::SBTypeList(const SBTypeList& rhs) : 509 m_opaque_ap(new TypeListImpl()) 510 { 511 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 512 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 513 } 514 515 bool 516 SBTypeList::IsValid () 517 { 518 return (m_opaque_ap.get() != NULL); 519 } 520 521 SBTypeList& 522 SBTypeList::operator = (const SBTypeList& rhs) 523 { 524 if (this != &rhs) 525 { 526 m_opaque_ap.reset (new TypeListImpl()); 527 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 528 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 529 } 530 return *this; 531 } 532 533 void 534 SBTypeList::Append (SBType type) 535 { 536 if (type.IsValid()) 537 m_opaque_ap->Append (type.m_opaque_sp); 538 } 539 540 SBType 541 SBTypeList::GetTypeAtIndex(uint32_t index) 542 { 543 if (m_opaque_ap.get()) 544 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 545 return SBType(); 546 } 547 548 uint32_t 549 SBTypeList::GetSize() 550 { 551 return m_opaque_ap->GetSize(); 552 } 553 554 SBTypeList::~SBTypeList() 555 { 556 } 557 558 bool 559 SBType::IsPointerType (void *opaque_type) 560 { 561 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 562 563 bool ret_value = ClangASTContext::IsPointerType (opaque_type); 564 565 if (log) 566 log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false")); 567 568 return ret_value; 569 } 570 571 572 SBTypeMember::SBTypeMember() : 573 m_opaque_ap() 574 { 575 } 576 577 SBTypeMember::~SBTypeMember() 578 { 579 } 580 581 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : 582 m_opaque_ap() 583 { 584 if (this != &rhs) 585 { 586 if (rhs.IsValid()) 587 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 588 } 589 } 590 591 lldb::SBTypeMember& 592 SBTypeMember::operator = (const lldb::SBTypeMember& rhs) 593 { 594 if (this != &rhs) 595 { 596 if (rhs.IsValid()) 597 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 598 } 599 return *this; 600 } 601 602 bool 603 SBTypeMember::IsValid() const 604 { 605 return m_opaque_ap.get(); 606 } 607 608 const char * 609 SBTypeMember::GetName () 610 { 611 if (m_opaque_ap.get()) 612 return m_opaque_ap->GetName().GetCString(); 613 return NULL; 614 } 615 616 SBType 617 SBTypeMember::GetType () 618 { 619 SBType sb_type; 620 if (m_opaque_ap.get()) 621 { 622 sb_type.SetSP (m_opaque_ap->GetTypeImpl()); 623 } 624 return sb_type; 625 626 } 627 628 uint64_t 629 SBTypeMember::GetOffsetInBytes() 630 { 631 if (m_opaque_ap.get()) 632 return m_opaque_ap->GetBitOffset() / 8u; 633 return 0; 634 } 635 636 uint64_t 637 SBTypeMember::GetOffsetInBits() 638 { 639 if (m_opaque_ap.get()) 640 return m_opaque_ap->GetBitOffset(); 641 return 0; 642 } 643 644 bool 645 SBTypeMember::IsBitfield() 646 { 647 if (m_opaque_ap.get()) 648 return m_opaque_ap->GetIsBitfield(); 649 return false; 650 } 651 652 uint32_t 653 SBTypeMember::GetBitfieldSizeInBits() 654 { 655 if (m_opaque_ap.get()) 656 return m_opaque_ap->GetBitfieldBitSize(); 657 return 0; 658 } 659 660 661 bool 662 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) 663 { 664 Stream &strm = description.ref(); 665 666 if (m_opaque_ap.get()) 667 { 668 const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); 669 const uint32_t byte_offset = bit_offset / 8u; 670 const uint32_t byte_bit_offset = bit_offset % 8u; 671 const char *name = m_opaque_ap->GetName().GetCString(); 672 if (byte_bit_offset) 673 strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset); 674 else 675 strm.Printf ("+%u: (", byte_offset); 676 677 TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl()); 678 if (type_impl_sp) 679 type_impl_sp->GetDescription(strm, description_level); 680 681 strm.Printf (") %s", name); 682 if (m_opaque_ap->GetIsBitfield()) 683 { 684 const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); 685 strm.Printf (" : %u", bitfield_bit_size); 686 } 687 } 688 else 689 { 690 strm.PutCString ("No value"); 691 } 692 return true; 693 } 694 695 696 void 697 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 698 { 699 m_opaque_ap.reset(type_member_impl); 700 } 701 702 TypeMemberImpl & 703 SBTypeMember::ref () 704 { 705 if (m_opaque_ap.get() == NULL) 706 m_opaque_ap.reset (new TypeMemberImpl()); 707 return *m_opaque_ap.get(); 708 } 709 710 const TypeMemberImpl & 711 SBTypeMember::ref () const 712 { 713 return *m_opaque_ap.get(); 714 } 715