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::GetDereferencedType() 190 { 191 if (!IsValid()) 192 return SBType(); 193 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType()))); 194 } 195 196 bool 197 SBType::IsFunctionType () 198 { 199 if (!IsValid()) 200 return false; 201 return m_opaque_sp->GetClangASTType(true).IsFunctionType(); 202 } 203 204 bool 205 SBType::IsPolymorphicClass () 206 { 207 if (!IsValid()) 208 return false; 209 return m_opaque_sp->GetClangASTType(true).IsPolymorphicClass(); 210 } 211 212 213 214 lldb::SBType 215 SBType::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 226 lldb::SBTypeList 227 SBType::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 244 lldb::SBType 245 SBType::GetUnqualifiedType() 246 { 247 if (!IsValid()) 248 return SBType(); 249 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType()))); 250 } 251 252 lldb::SBType 253 SBType::GetCanonicalType() 254 { 255 if (IsValid()) 256 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType()))); 257 return SBType(); 258 } 259 260 261 lldb::BasicType 262 SBType::GetBasicType() 263 { 264 if (IsValid()) 265 return m_opaque_sp->GetClangASTType(false).GetBasicTypeEnumeration (); 266 return eBasicTypeInvalid; 267 } 268 269 SBType 270 SBType::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 277 uint32_t 278 SBType::GetNumberOfDirectBaseClasses () 279 { 280 if (IsValid()) 281 return m_opaque_sp->GetClangASTType(true).GetNumDirectBaseClasses(); 282 return 0; 283 } 284 285 uint32_t 286 SBType::GetNumberOfVirtualBaseClasses () 287 { 288 if (IsValid()) 289 return m_opaque_sp->GetClangASTType(true).GetNumVirtualBaseClasses(); 290 return 0; 291 } 292 293 uint32_t 294 SBType::GetNumberOfFields () 295 { 296 if (IsValid()) 297 return m_opaque_sp->GetClangASTType(false).GetNumFields(); 298 return 0; 299 } 300 301 bool 302 SBType::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 318 SBTypeMember 319 SBType::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 339 SBTypeMember 340 SBType::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 359 SBTypeMember 360 SBType::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 393 bool 394 SBType::IsTypeComplete() 395 { 396 if (!IsValid()) 397 return false; 398 return m_opaque_sp->GetClangASTType(false).IsCompleteType(); 399 } 400 401 const char* 402 SBType::GetName() 403 { 404 if (!IsValid()) 405 return ""; 406 return m_opaque_sp->GetName().GetCString(); 407 } 408 409 lldb::TypeClass 410 SBType::GetTypeClass () 411 { 412 if (IsValid()) 413 return m_opaque_sp->GetClangASTType(false).GetTypeClass(); 414 return lldb::eTypeClassInvalid; 415 } 416 417 uint32_t 418 SBType::GetNumberOfTemplateArguments () 419 { 420 if (IsValid()) 421 return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments(); 422 return 0; 423 } 424 425 lldb::SBType 426 SBType::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 439 lldb::TemplateArgumentKind 440 SBType::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 449 SBTypeList::SBTypeList() : 450 m_opaque_ap(new TypeListImpl()) 451 { 452 } 453 454 SBTypeList::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 461 bool 462 SBTypeList::IsValid () 463 { 464 return (m_opaque_ap.get() != NULL); 465 } 466 467 SBTypeList& 468 SBTypeList::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 479 void 480 SBTypeList::Append (SBType type) 481 { 482 if (type.IsValid()) 483 m_opaque_ap->Append (type.m_opaque_sp); 484 } 485 486 SBType 487 SBTypeList::GetTypeAtIndex(uint32_t index) 488 { 489 if (m_opaque_ap.get()) 490 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 491 return SBType(); 492 } 493 494 uint32_t 495 SBTypeList::GetSize() 496 { 497 return m_opaque_ap->GetSize(); 498 } 499 500 SBTypeList::~SBTypeList() 501 { 502 } 503 504 SBTypeMember::SBTypeMember() : 505 m_opaque_ap() 506 { 507 } 508 509 SBTypeMember::~SBTypeMember() 510 { 511 } 512 513 SBTypeMember::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 523 lldb::SBTypeMember& 524 SBTypeMember::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 534 bool 535 SBTypeMember::IsValid() const 536 { 537 return m_opaque_ap.get(); 538 } 539 540 const char * 541 SBTypeMember::GetName () 542 { 543 if (m_opaque_ap.get()) 544 return m_opaque_ap->GetName().GetCString(); 545 return NULL; 546 } 547 548 SBType 549 SBTypeMember::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 560 uint64_t 561 SBTypeMember::GetOffsetInBytes() 562 { 563 if (m_opaque_ap.get()) 564 return m_opaque_ap->GetBitOffset() / 8u; 565 return 0; 566 } 567 568 uint64_t 569 SBTypeMember::GetOffsetInBits() 570 { 571 if (m_opaque_ap.get()) 572 return m_opaque_ap->GetBitOffset(); 573 return 0; 574 } 575 576 bool 577 SBTypeMember::IsBitfield() 578 { 579 if (m_opaque_ap.get()) 580 return m_opaque_ap->GetIsBitfield(); 581 return false; 582 } 583 584 uint32_t 585 SBTypeMember::GetBitfieldSizeInBits() 586 { 587 if (m_opaque_ap.get()) 588 return m_opaque_ap->GetBitfieldBitSize(); 589 return 0; 590 } 591 592 593 bool 594 SBTypeMember::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 628 void 629 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 630 { 631 m_opaque_ap.reset(type_member_impl); 632 } 633 634 TypeMemberImpl & 635 SBTypeMember::ref () 636 { 637 if (m_opaque_ap.get() == NULL) 638 m_opaque_ap.reset (new TypeMemberImpl()); 639 return *m_opaque_ap.get(); 640 } 641 642 const TypeMemberImpl & 643 SBTypeMember::ref () const 644 { 645 return *m_opaque_ap.get(); 646 } 647