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 lldb::TypeClass 418 SBType::GetTypeClass () 419 { 420 if (IsValid()) 421 return m_opaque_sp->GetClangASTType(false).GetTypeClass(); 422 return lldb::eTypeClassInvalid; 423 } 424 425 uint32_t 426 SBType::GetNumberOfTemplateArguments () 427 { 428 if (IsValid()) 429 return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments(); 430 return 0; 431 } 432 433 lldb::SBType 434 SBType::GetTemplateArgumentType (uint32_t idx) 435 { 436 if (IsValid()) 437 { 438 TemplateArgumentKind kind = eTemplateArgumentKindNull; 439 ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind); 440 if (template_arg_type.IsValid()) 441 return SBType(template_arg_type); 442 } 443 return SBType(); 444 } 445 446 447 lldb::TemplateArgumentKind 448 SBType::GetTemplateArgumentKind (uint32_t idx) 449 { 450 TemplateArgumentKind kind = eTemplateArgumentKindNull; 451 if (IsValid()) 452 m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind); 453 return kind; 454 } 455 456 457 SBTypeList::SBTypeList() : 458 m_opaque_ap(new TypeListImpl()) 459 { 460 } 461 462 SBTypeList::SBTypeList(const SBTypeList& rhs) : 463 m_opaque_ap(new TypeListImpl()) 464 { 465 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 466 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 467 } 468 469 bool 470 SBTypeList::IsValid () 471 { 472 return (m_opaque_ap.get() != NULL); 473 } 474 475 SBTypeList& 476 SBTypeList::operator = (const SBTypeList& rhs) 477 { 478 if (this != &rhs) 479 { 480 m_opaque_ap.reset (new TypeListImpl()); 481 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 482 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 483 } 484 return *this; 485 } 486 487 void 488 SBTypeList::Append (SBType type) 489 { 490 if (type.IsValid()) 491 m_opaque_ap->Append (type.m_opaque_sp); 492 } 493 494 SBType 495 SBTypeList::GetTypeAtIndex(uint32_t index) 496 { 497 if (m_opaque_ap.get()) 498 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 499 return SBType(); 500 } 501 502 uint32_t 503 SBTypeList::GetSize() 504 { 505 return m_opaque_ap->GetSize(); 506 } 507 508 SBTypeList::~SBTypeList() 509 { 510 } 511 512 SBTypeMember::SBTypeMember() : 513 m_opaque_ap() 514 { 515 } 516 517 SBTypeMember::~SBTypeMember() 518 { 519 } 520 521 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : 522 m_opaque_ap() 523 { 524 if (this != &rhs) 525 { 526 if (rhs.IsValid()) 527 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 528 } 529 } 530 531 lldb::SBTypeMember& 532 SBTypeMember::operator = (const lldb::SBTypeMember& rhs) 533 { 534 if (this != &rhs) 535 { 536 if (rhs.IsValid()) 537 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 538 } 539 return *this; 540 } 541 542 bool 543 SBTypeMember::IsValid() const 544 { 545 return m_opaque_ap.get(); 546 } 547 548 const char * 549 SBTypeMember::GetName () 550 { 551 if (m_opaque_ap.get()) 552 return m_opaque_ap->GetName().GetCString(); 553 return NULL; 554 } 555 556 SBType 557 SBTypeMember::GetType () 558 { 559 SBType sb_type; 560 if (m_opaque_ap.get()) 561 { 562 sb_type.SetSP (m_opaque_ap->GetTypeImpl()); 563 } 564 return sb_type; 565 566 } 567 568 uint64_t 569 SBTypeMember::GetOffsetInBytes() 570 { 571 if (m_opaque_ap.get()) 572 return m_opaque_ap->GetBitOffset() / 8u; 573 return 0; 574 } 575 576 uint64_t 577 SBTypeMember::GetOffsetInBits() 578 { 579 if (m_opaque_ap.get()) 580 return m_opaque_ap->GetBitOffset(); 581 return 0; 582 } 583 584 bool 585 SBTypeMember::IsBitfield() 586 { 587 if (m_opaque_ap.get()) 588 return m_opaque_ap->GetIsBitfield(); 589 return false; 590 } 591 592 uint32_t 593 SBTypeMember::GetBitfieldSizeInBits() 594 { 595 if (m_opaque_ap.get()) 596 return m_opaque_ap->GetBitfieldBitSize(); 597 return 0; 598 } 599 600 601 bool 602 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) 603 { 604 Stream &strm = description.ref(); 605 606 if (m_opaque_ap.get()) 607 { 608 const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); 609 const uint32_t byte_offset = bit_offset / 8u; 610 const uint32_t byte_bit_offset = bit_offset % 8u; 611 const char *name = m_opaque_ap->GetName().GetCString(); 612 if (byte_bit_offset) 613 strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset); 614 else 615 strm.Printf ("+%u: (", byte_offset); 616 617 TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl()); 618 if (type_impl_sp) 619 type_impl_sp->GetDescription(strm, description_level); 620 621 strm.Printf (") %s", name); 622 if (m_opaque_ap->GetIsBitfield()) 623 { 624 const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); 625 strm.Printf (" : %u", bitfield_bit_size); 626 } 627 } 628 else 629 { 630 strm.PutCString ("No value"); 631 } 632 return true; 633 } 634 635 636 void 637 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 638 { 639 m_opaque_ap.reset(type_member_impl); 640 } 641 642 TypeMemberImpl & 643 SBTypeMember::ref () 644 { 645 if (m_opaque_ap.get() == NULL) 646 m_opaque_ap.reset (new TypeMemberImpl()); 647 return *m_opaque_ap.get(); 648 } 649 650 const TypeMemberImpl & 651 SBTypeMember::ref () const 652 { 653 return *m_opaque_ap.get(); 654 } 655