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