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