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