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