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