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/SBDefines.h" 12 #include "lldb/API/SBStream.h" 13 #include "lldb/API/SBTypeEnumMember.h" 14 #include "lldb/Core/ConstString.h" 15 #include "lldb/Core/Log.h" 16 #include "lldb/Core/Mangled.h" 17 #include "lldb/Core/Stream.h" 18 #include "lldb/Symbol/CompilerType.h" 19 #include "lldb/Symbol/Type.h" 20 #include "lldb/Symbol/TypeSystem.h" 21 22 #include "llvm/ADT/APSInt.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 SBType::SBType() : m_opaque_sp() {} 28 29 SBType::SBType(const CompilerType &type) 30 : m_opaque_sp(new TypeImpl( 31 CompilerType(type.GetTypeSystem(), type.GetOpaqueQualType()))) {} 32 33 SBType::SBType(const lldb::TypeSP &type_sp) 34 : m_opaque_sp(new TypeImpl(type_sp)) {} 35 36 SBType::SBType(const lldb::TypeImplSP &type_impl_sp) 37 : m_opaque_sp(type_impl_sp) {} 38 39 SBType::SBType(const SBType &rhs) : m_opaque_sp() { 40 if (this != &rhs) { 41 m_opaque_sp = rhs.m_opaque_sp; 42 } 43 } 44 45 // SBType::SBType (TypeImpl* impl) : 46 // m_opaque_ap(impl) 47 //{} 48 // 49 bool SBType::operator==(SBType &rhs) { 50 if (IsValid() == false) 51 return !rhs.IsValid(); 52 53 if (rhs.IsValid() == false) 54 return false; 55 56 return *m_opaque_sp.get() == *rhs.m_opaque_sp.get(); 57 } 58 59 bool SBType::operator!=(SBType &rhs) { 60 if (IsValid() == false) 61 return rhs.IsValid(); 62 63 if (rhs.IsValid() == false) 64 return true; 65 66 return *m_opaque_sp.get() != *rhs.m_opaque_sp.get(); 67 } 68 69 lldb::TypeImplSP SBType::GetSP() { return m_opaque_sp; } 70 71 void SBType::SetSP(const lldb::TypeImplSP &type_impl_sp) { 72 m_opaque_sp = type_impl_sp; 73 } 74 75 SBType &SBType::operator=(const SBType &rhs) { 76 if (this != &rhs) { 77 m_opaque_sp = rhs.m_opaque_sp; 78 } 79 return *this; 80 } 81 82 SBType::~SBType() {} 83 84 TypeImpl &SBType::ref() { 85 if (m_opaque_sp.get() == NULL) 86 m_opaque_sp.reset(new TypeImpl()); 87 return *m_opaque_sp; 88 } 89 90 const TypeImpl &SBType::ref() const { 91 // "const SBAddress &addr" should already have checked "addr.IsValid()" 92 // prior to calling this function. In case you didn't we will assert 93 // and die to let you know. 94 assert(m_opaque_sp.get()); 95 return *m_opaque_sp; 96 } 97 98 bool SBType::IsValid() const { 99 if (m_opaque_sp.get() == NULL) 100 return false; 101 102 return m_opaque_sp->IsValid(); 103 } 104 105 uint64_t SBType::GetByteSize() { 106 if (!IsValid()) 107 return 0; 108 109 return m_opaque_sp->GetCompilerType(false).GetByteSize(nullptr); 110 } 111 112 bool SBType::IsPointerType() { 113 if (!IsValid()) 114 return false; 115 return m_opaque_sp->GetCompilerType(true).IsPointerType(); 116 } 117 118 bool SBType::IsArrayType() { 119 if (!IsValid()) 120 return false; 121 return m_opaque_sp->GetCompilerType(true).IsArrayType(nullptr, nullptr, 122 nullptr); 123 } 124 125 bool SBType::IsVectorType() { 126 if (!IsValid()) 127 return false; 128 return m_opaque_sp->GetCompilerType(true).IsVectorType(nullptr, nullptr); 129 } 130 131 bool SBType::IsReferenceType() { 132 if (!IsValid()) 133 return false; 134 return m_opaque_sp->GetCompilerType(true).IsReferenceType(); 135 } 136 137 SBType SBType::GetPointerType() { 138 if (!IsValid()) 139 return SBType(); 140 141 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointerType()))); 142 } 143 144 SBType SBType::GetPointeeType() { 145 if (!IsValid()) 146 return SBType(); 147 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointeeType()))); 148 } 149 150 SBType SBType::GetReferenceType() { 151 if (!IsValid()) 152 return SBType(); 153 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType()))); 154 } 155 156 SBType SBType::GetTypedefedType() { 157 if (!IsValid()) 158 return SBType(); 159 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetTypedefedType()))); 160 } 161 162 SBType SBType::GetDereferencedType() { 163 if (!IsValid()) 164 return SBType(); 165 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType()))); 166 } 167 168 SBType SBType::GetArrayElementType() { 169 if (!IsValid()) 170 return SBType(); 171 return SBType(TypeImplSP( 172 new TypeImpl(m_opaque_sp->GetCompilerType(true).GetArrayElementType()))); 173 } 174 175 SBType SBType::GetArrayType(uint64_t size) { 176 if (!IsValid()) 177 return SBType(); 178 return SBType(TypeImplSP( 179 new TypeImpl(m_opaque_sp->GetCompilerType(true).GetArrayType(size)))); 180 } 181 182 SBType SBType::GetVectorElementType() { 183 SBType type_sb; 184 if (IsValid()) { 185 CompilerType vector_element_type; 186 if (m_opaque_sp->GetCompilerType(true).IsVectorType(&vector_element_type, 187 nullptr)) 188 type_sb.SetSP(TypeImplSP(new TypeImpl(vector_element_type))); 189 } 190 return type_sb; 191 } 192 193 bool SBType::IsFunctionType() { 194 if (!IsValid()) 195 return false; 196 return m_opaque_sp->GetCompilerType(true).IsFunctionType(); 197 } 198 199 bool SBType::IsPolymorphicClass() { 200 if (!IsValid()) 201 return false; 202 return m_opaque_sp->GetCompilerType(true).IsPolymorphicClass(); 203 } 204 205 bool SBType::IsTypedefType() { 206 if (!IsValid()) 207 return false; 208 return m_opaque_sp->GetCompilerType(true).IsTypedefType(); 209 } 210 211 bool SBType::IsAnonymousType() { 212 if (!IsValid()) 213 return false; 214 return m_opaque_sp->GetCompilerType(true).IsAnonymousType(); 215 } 216 217 lldb::SBType SBType::GetFunctionReturnType() { 218 if (IsValid()) { 219 CompilerType return_type( 220 m_opaque_sp->GetCompilerType(true).GetFunctionReturnType()); 221 if (return_type.IsValid()) 222 return SBType(return_type); 223 } 224 return lldb::SBType(); 225 } 226 227 lldb::SBTypeList SBType::GetFunctionArgumentTypes() { 228 SBTypeList sb_type_list; 229 if (IsValid()) { 230 CompilerType func_type(m_opaque_sp->GetCompilerType(true)); 231 size_t count = func_type.GetNumberOfFunctionArguments(); 232 for (size_t i = 0; i < count; i++) { 233 sb_type_list.Append(SBType(func_type.GetFunctionArgumentAtIndex(i))); 234 } 235 } 236 return sb_type_list; 237 } 238 239 uint32_t SBType::GetNumberOfMemberFunctions() { 240 if (IsValid()) { 241 return m_opaque_sp->GetCompilerType(true).GetNumMemberFunctions(); 242 } 243 return 0; 244 } 245 246 lldb::SBTypeMemberFunction SBType::GetMemberFunctionAtIndex(uint32_t idx) { 247 SBTypeMemberFunction sb_func_type; 248 if (IsValid()) 249 sb_func_type.reset(new TypeMemberFunctionImpl( 250 m_opaque_sp->GetCompilerType(true).GetMemberFunctionAtIndex(idx))); 251 return sb_func_type; 252 } 253 254 lldb::SBType SBType::GetUnqualifiedType() { 255 if (!IsValid()) 256 return SBType(); 257 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType()))); 258 } 259 260 lldb::SBType SBType::GetCanonicalType() { 261 if (IsValid()) 262 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType()))); 263 return SBType(); 264 } 265 266 lldb::BasicType SBType::GetBasicType() { 267 if (IsValid()) 268 return m_opaque_sp->GetCompilerType(false).GetBasicTypeEnumeration(); 269 return eBasicTypeInvalid; 270 } 271 272 SBType SBType::GetBasicType(lldb::BasicType basic_type) { 273 if (IsValid() && m_opaque_sp->IsValid()) 274 return SBType( 275 m_opaque_sp->GetTypeSystem(false)->GetBasicTypeFromAST(basic_type)); 276 return SBType(); 277 } 278 279 uint32_t SBType::GetNumberOfDirectBaseClasses() { 280 if (IsValid()) 281 return m_opaque_sp->GetCompilerType(true).GetNumDirectBaseClasses(); 282 return 0; 283 } 284 285 uint32_t SBType::GetNumberOfVirtualBaseClasses() { 286 if (IsValid()) 287 return m_opaque_sp->GetCompilerType(true).GetNumVirtualBaseClasses(); 288 return 0; 289 } 290 291 uint32_t SBType::GetNumberOfFields() { 292 if (IsValid()) 293 return m_opaque_sp->GetCompilerType(true).GetNumFields(); 294 return 0; 295 } 296 297 bool SBType::GetDescription(SBStream &description, 298 lldb::DescriptionLevel description_level) { 299 Stream &strm = description.ref(); 300 301 if (m_opaque_sp) { 302 m_opaque_sp->GetDescription(strm, description_level); 303 } else 304 strm.PutCString("No value"); 305 306 return true; 307 } 308 309 SBTypeMember SBType::GetDirectBaseClassAtIndex(uint32_t idx) { 310 SBTypeMember sb_type_member; 311 if (IsValid()) { 312 uint32_t bit_offset = 0; 313 CompilerType base_class_type = 314 m_opaque_sp->GetCompilerType(true).GetDirectBaseClassAtIndex( 315 idx, &bit_offset); 316 if (base_class_type.IsValid()) 317 sb_type_member.reset(new TypeMemberImpl( 318 TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); 319 } 320 return sb_type_member; 321 } 322 323 SBTypeMember SBType::GetVirtualBaseClassAtIndex(uint32_t idx) { 324 SBTypeMember sb_type_member; 325 if (IsValid()) { 326 uint32_t bit_offset = 0; 327 CompilerType base_class_type = 328 m_opaque_sp->GetCompilerType(true).GetVirtualBaseClassAtIndex( 329 idx, &bit_offset); 330 if (base_class_type.IsValid()) 331 sb_type_member.reset(new TypeMemberImpl( 332 TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); 333 } 334 return sb_type_member; 335 } 336 337 SBTypeEnumMemberList SBType::GetEnumMembers() { 338 SBTypeEnumMemberList sb_enum_member_list; 339 if (IsValid()) { 340 CompilerType this_type(m_opaque_sp->GetCompilerType(true)); 341 if (this_type.IsValid()) { 342 this_type.ForEachEnumerator([&sb_enum_member_list]( 343 const CompilerType &integer_type, 344 const ConstString &name, 345 const llvm::APSInt &value) -> bool { 346 SBTypeEnumMember enum_member( 347 lldb::TypeEnumMemberImplSP(new TypeEnumMemberImpl( 348 lldb::TypeImplSP(new TypeImpl(integer_type)), name, value))); 349 sb_enum_member_list.Append(enum_member); 350 return true; // Keep iterating 351 }); 352 } 353 } 354 return sb_enum_member_list; 355 } 356 357 SBTypeMember SBType::GetFieldAtIndex(uint32_t idx) { 358 SBTypeMember sb_type_member; 359 if (IsValid()) { 360 CompilerType this_type(m_opaque_sp->GetCompilerType(false)); 361 if (this_type.IsValid()) { 362 uint64_t bit_offset = 0; 363 uint32_t bitfield_bit_size = 0; 364 bool is_bitfield = false; 365 std::string name_sstr; 366 CompilerType field_type(this_type.GetFieldAtIndex( 367 idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield)); 368 if (field_type.IsValid()) { 369 ConstString name; 370 if (!name_sstr.empty()) 371 name.SetCString(name_sstr.c_str()); 372 sb_type_member.reset( 373 new TypeMemberImpl(TypeImplSP(new TypeImpl(field_type)), bit_offset, 374 name, bitfield_bit_size, is_bitfield)); 375 } 376 } 377 } 378 return sb_type_member; 379 } 380 381 bool SBType::IsTypeComplete() { 382 if (!IsValid()) 383 return false; 384 return m_opaque_sp->GetCompilerType(false).IsCompleteType(); 385 } 386 387 uint32_t SBType::GetTypeFlags() { 388 if (!IsValid()) 389 return 0; 390 return m_opaque_sp->GetCompilerType(true).GetTypeInfo(); 391 } 392 393 const char *SBType::GetName() { 394 if (!IsValid()) 395 return ""; 396 return m_opaque_sp->GetName().GetCString(); 397 } 398 399 const char *SBType::GetDisplayTypeName() { 400 if (!IsValid()) 401 return ""; 402 return m_opaque_sp->GetDisplayTypeName().GetCString(); 403 } 404 405 lldb::TypeClass SBType::GetTypeClass() { 406 if (IsValid()) 407 return m_opaque_sp->GetCompilerType(true).GetTypeClass(); 408 return lldb::eTypeClassInvalid; 409 } 410 411 uint32_t SBType::GetNumberOfTemplateArguments() { 412 if (IsValid()) 413 return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments(); 414 return 0; 415 } 416 417 lldb::SBType SBType::GetTemplateArgumentType(uint32_t idx) { 418 if (IsValid()) { 419 TemplateArgumentKind kind = eTemplateArgumentKindNull; 420 CompilerType template_arg_type = 421 m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind); 422 if (template_arg_type.IsValid()) 423 return SBType(template_arg_type); 424 } 425 return SBType(); 426 } 427 428 lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) { 429 TemplateArgumentKind kind = eTemplateArgumentKindNull; 430 if (IsValid()) 431 m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind); 432 return kind; 433 } 434 435 SBTypeList::SBTypeList() : m_opaque_ap(new TypeListImpl()) {} 436 437 SBTypeList::SBTypeList(const SBTypeList &rhs) 438 : m_opaque_ap(new TypeListImpl()) { 439 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList &>(rhs).GetSize(); 440 i < rhs_size; i++) 441 Append(const_cast<SBTypeList &>(rhs).GetTypeAtIndex(i)); 442 } 443 444 bool SBTypeList::IsValid() { return (m_opaque_ap.get() != NULL); } 445 446 SBTypeList &SBTypeList::operator=(const SBTypeList &rhs) { 447 if (this != &rhs) { 448 m_opaque_ap.reset(new TypeListImpl()); 449 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList &>(rhs).GetSize(); 450 i < rhs_size; i++) 451 Append(const_cast<SBTypeList &>(rhs).GetTypeAtIndex(i)); 452 } 453 return *this; 454 } 455 456 void SBTypeList::Append(SBType type) { 457 if (type.IsValid()) 458 m_opaque_ap->Append(type.m_opaque_sp); 459 } 460 461 SBType SBTypeList::GetTypeAtIndex(uint32_t index) { 462 if (m_opaque_ap.get()) 463 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 464 return SBType(); 465 } 466 467 uint32_t SBTypeList::GetSize() { return m_opaque_ap->GetSize(); } 468 469 SBTypeList::~SBTypeList() {} 470 471 SBTypeMember::SBTypeMember() : m_opaque_ap() {} 472 473 SBTypeMember::~SBTypeMember() {} 474 475 SBTypeMember::SBTypeMember(const SBTypeMember &rhs) : m_opaque_ap() { 476 if (this != &rhs) { 477 if (rhs.IsValid()) 478 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 479 } 480 } 481 482 lldb::SBTypeMember &SBTypeMember::operator=(const lldb::SBTypeMember &rhs) { 483 if (this != &rhs) { 484 if (rhs.IsValid()) 485 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 486 } 487 return *this; 488 } 489 490 bool SBTypeMember::IsValid() const { return m_opaque_ap.get(); } 491 492 const char *SBTypeMember::GetName() { 493 if (m_opaque_ap.get()) 494 return m_opaque_ap->GetName().GetCString(); 495 return NULL; 496 } 497 498 SBType SBTypeMember::GetType() { 499 SBType sb_type; 500 if (m_opaque_ap.get()) { 501 sb_type.SetSP(m_opaque_ap->GetTypeImpl()); 502 } 503 return sb_type; 504 } 505 506 uint64_t SBTypeMember::GetOffsetInBytes() { 507 if (m_opaque_ap.get()) 508 return m_opaque_ap->GetBitOffset() / 8u; 509 return 0; 510 } 511 512 uint64_t SBTypeMember::GetOffsetInBits() { 513 if (m_opaque_ap.get()) 514 return m_opaque_ap->GetBitOffset(); 515 return 0; 516 } 517 518 bool SBTypeMember::IsBitfield() { 519 if (m_opaque_ap.get()) 520 return m_opaque_ap->GetIsBitfield(); 521 return false; 522 } 523 524 uint32_t SBTypeMember::GetBitfieldSizeInBits() { 525 if (m_opaque_ap.get()) 526 return m_opaque_ap->GetBitfieldBitSize(); 527 return 0; 528 } 529 530 bool SBTypeMember::GetDescription(lldb::SBStream &description, 531 lldb::DescriptionLevel description_level) { 532 Stream &strm = description.ref(); 533 534 if (m_opaque_ap.get()) { 535 const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); 536 const uint32_t byte_offset = bit_offset / 8u; 537 const uint32_t byte_bit_offset = bit_offset % 8u; 538 const char *name = m_opaque_ap->GetName().GetCString(); 539 if (byte_bit_offset) 540 strm.Printf("+%u + %u bits: (", byte_offset, byte_bit_offset); 541 else 542 strm.Printf("+%u: (", byte_offset); 543 544 TypeImplSP type_impl_sp(m_opaque_ap->GetTypeImpl()); 545 if (type_impl_sp) 546 type_impl_sp->GetDescription(strm, description_level); 547 548 strm.Printf(") %s", name); 549 if (m_opaque_ap->GetIsBitfield()) { 550 const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); 551 strm.Printf(" : %u", bitfield_bit_size); 552 } 553 } else { 554 strm.PutCString("No value"); 555 } 556 return true; 557 } 558 559 void SBTypeMember::reset(TypeMemberImpl *type_member_impl) { 560 m_opaque_ap.reset(type_member_impl); 561 } 562 563 TypeMemberImpl &SBTypeMember::ref() { 564 if (m_opaque_ap.get() == NULL) 565 m_opaque_ap.reset(new TypeMemberImpl()); 566 return *m_opaque_ap.get(); 567 } 568 569 const TypeMemberImpl &SBTypeMember::ref() const { return *m_opaque_ap.get(); } 570 571 SBTypeMemberFunction::SBTypeMemberFunction() : m_opaque_sp() {} 572 573 SBTypeMemberFunction::~SBTypeMemberFunction() {} 574 575 SBTypeMemberFunction::SBTypeMemberFunction(const SBTypeMemberFunction &rhs) 576 : m_opaque_sp(rhs.m_opaque_sp) {} 577 578 lldb::SBTypeMemberFunction &SBTypeMemberFunction:: 579 operator=(const lldb::SBTypeMemberFunction &rhs) { 580 if (this != &rhs) 581 m_opaque_sp = rhs.m_opaque_sp; 582 return *this; 583 } 584 585 bool SBTypeMemberFunction::IsValid() const { return m_opaque_sp.get(); } 586 587 const char *SBTypeMemberFunction::GetName() { 588 if (m_opaque_sp) 589 return m_opaque_sp->GetName().GetCString(); 590 return NULL; 591 } 592 593 const char *SBTypeMemberFunction::GetDemangledName() { 594 if (m_opaque_sp) { 595 ConstString mangled_str = m_opaque_sp->GetMangledName(); 596 if (mangled_str) { 597 Mangled mangled(mangled_str, true); 598 return mangled.GetDemangledName(mangled.GuessLanguage()).GetCString(); 599 } 600 } 601 return NULL; 602 } 603 604 const char *SBTypeMemberFunction::GetMangledName() { 605 if (m_opaque_sp) 606 return m_opaque_sp->GetMangledName().GetCString(); 607 return NULL; 608 } 609 610 SBType SBTypeMemberFunction::GetType() { 611 SBType sb_type; 612 if (m_opaque_sp) { 613 sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType()))); 614 } 615 return sb_type; 616 } 617 618 lldb::SBType SBTypeMemberFunction::GetReturnType() { 619 SBType sb_type; 620 if (m_opaque_sp) { 621 sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType()))); 622 } 623 return sb_type; 624 } 625 626 uint32_t SBTypeMemberFunction::GetNumberOfArguments() { 627 if (m_opaque_sp) 628 return m_opaque_sp->GetNumArguments(); 629 return 0; 630 } 631 632 lldb::SBType SBTypeMemberFunction::GetArgumentTypeAtIndex(uint32_t i) { 633 SBType sb_type; 634 if (m_opaque_sp) { 635 sb_type.SetSP( 636 lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i)))); 637 } 638 return sb_type; 639 } 640 641 lldb::MemberFunctionKind SBTypeMemberFunction::GetKind() { 642 if (m_opaque_sp) 643 return m_opaque_sp->GetKind(); 644 return lldb::eMemberFunctionKindUnknown; 645 } 646 647 bool SBTypeMemberFunction::GetDescription( 648 lldb::SBStream &description, lldb::DescriptionLevel description_level) { 649 Stream &strm = description.ref(); 650 651 if (m_opaque_sp) 652 return m_opaque_sp->GetDescription(strm); 653 654 return false; 655 } 656 657 void SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl) { 658 m_opaque_sp.reset(type_member_impl); 659 } 660 661 TypeMemberFunctionImpl &SBTypeMemberFunction::ref() { 662 if (!m_opaque_sp) 663 m_opaque_sp.reset(new TypeMemberFunctionImpl()); 664 return *m_opaque_sp.get(); 665 } 666 667 const TypeMemberFunctionImpl &SBTypeMemberFunction::ref() const { 668 return *m_opaque_sp.get(); 669 } 670