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 size_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 lldb::SBType 223 SBType::GetUnqualifiedType() 224 { 225 if (!IsValid()) 226 return SBType(); 227 228 QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType())); 229 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getUnqualifiedType().getAsOpaquePtr())); 230 } 231 232 233 SBType 234 SBType::GetBasicType(lldb::BasicType type) 235 { 236 237 if (!IsValid()) 238 return SBType(); 239 240 clang::CanQualType base_type_qual; 241 242 switch (type) 243 { 244 case eBasicTypeChar: 245 base_type_qual = m_opaque_sp->GetASTContext()->CharTy; 246 break; 247 case eBasicTypeSignedChar: 248 base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy; 249 break; 250 case eBasicTypeShort: 251 base_type_qual = m_opaque_sp->GetASTContext()->ShortTy; 252 break; 253 case eBasicTypeUnsignedShort: 254 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy; 255 break; 256 case eBasicTypeInt: 257 base_type_qual = m_opaque_sp->GetASTContext()->IntTy; 258 break; 259 case eBasicTypeUnsignedInt: 260 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy; 261 break; 262 case eBasicTypeLong: 263 base_type_qual = m_opaque_sp->GetASTContext()->LongTy; 264 break; 265 case eBasicTypeUnsignedLong: 266 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy; 267 break; 268 case eBasicTypeBool: 269 base_type_qual = m_opaque_sp->GetASTContext()->BoolTy; 270 break; 271 case eBasicTypeFloat: 272 base_type_qual = m_opaque_sp->GetASTContext()->FloatTy; 273 break; 274 case eBasicTypeDouble: 275 base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy; 276 break; 277 case eBasicTypeObjCID: 278 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy; 279 break; 280 case eBasicTypeVoid: 281 base_type_qual = m_opaque_sp->GetASTContext()->VoidTy; 282 break; 283 case eBasicTypeWChar: 284 base_type_qual = m_opaque_sp->GetASTContext()->WCharTy; 285 break; 286 case eBasicTypeChar16: 287 base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty; 288 break; 289 case eBasicTypeChar32: 290 base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty; 291 break; 292 case eBasicTypeLongLong: 293 base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy; 294 break; 295 case eBasicTypeUnsignedLongLong: 296 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy; 297 break; 298 case eBasicTypeInt128: 299 base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty; 300 break; 301 case eBasicTypeUnsignedInt128: 302 base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty; 303 break; 304 case eBasicTypeLongDouble: 305 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy; 306 break; 307 case eBasicTypeFloatComplex: 308 base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy; 309 break; 310 case eBasicTypeDoubleComplex: 311 base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy; 312 break; 313 case eBasicTypeLongDoubleComplex: 314 base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy; 315 break; 316 case eBasicTypeObjCClass: 317 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy; 318 break; 319 case eBasicTypeObjCSel: 320 base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy; 321 break; 322 default: 323 return SBType(); 324 } 325 326 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr())); 327 } 328 329 uint32_t 330 SBType::GetNumberOfDirectBaseClasses () 331 { 332 if (IsValid()) 333 return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 334 return 0; 335 } 336 337 uint32_t 338 SBType::GetNumberOfVirtualBaseClasses () 339 { 340 if (IsValid()) 341 return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 342 return 0; 343 } 344 345 uint32_t 346 SBType::GetNumberOfFields () 347 { 348 if (IsValid()) 349 return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 350 return 0; 351 } 352 353 bool 354 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) 355 { 356 Stream &strm = description.ref(); 357 358 if (m_opaque_sp) 359 { 360 m_opaque_sp->GetDescription (strm, description_level); 361 } 362 else 363 strm.PutCString ("No value"); 364 365 return true; 366 } 367 368 369 370 SBTypeMember 371 SBType::GetDirectBaseClassAtIndex (uint32_t idx) 372 { 373 SBTypeMember sb_type_member; 374 if (IsValid()) 375 { 376 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 377 uint32_t bit_offset = 0; 378 clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); 379 if (clang_type) 380 { 381 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 382 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); 383 } 384 } 385 return sb_type_member; 386 387 } 388 389 SBTypeMember 390 SBType::GetVirtualBaseClassAtIndex (uint32_t idx) 391 { 392 SBTypeMember sb_type_member; 393 if (IsValid()) 394 { 395 uint32_t bit_offset = 0; 396 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 397 clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); 398 if (clang_type) 399 { 400 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 401 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); 402 } 403 } 404 return sb_type_member; 405 } 406 407 SBTypeMember 408 SBType::GetFieldAtIndex (uint32_t idx) 409 { 410 SBTypeMember sb_type_member; 411 if (IsValid()) 412 { 413 uint32_t bit_offset = 0; 414 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 415 std::string name_sstr; 416 clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset); 417 if (clang_type) 418 { 419 ConstString name; 420 if (!name_sstr.empty()) 421 name.SetCString(name_sstr.c_str()); 422 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 423 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name)); 424 } 425 } 426 return sb_type_member; 427 } 428 429 bool 430 SBType::IsTypeComplete() 431 { 432 if (!IsValid()) 433 return false; 434 435 return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 436 } 437 438 const char* 439 SBType::GetName() 440 { 441 if (!IsValid()) 442 return ""; 443 444 return ClangASTType::GetConstTypeName(m_opaque_sp->GetASTContext(), 445 m_opaque_sp->GetOpaqueQualType()).GetCString(); 446 } 447 448 lldb::TypeClass 449 SBType::GetTypeClass () 450 { 451 if (IsValid()) 452 return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(), 453 m_opaque_sp->GetOpaqueQualType()); 454 return lldb::eTypeClassInvalid; 455 } 456 457 uint32_t 458 SBType::GetNumberOfTemplateArguments () 459 { 460 if (IsValid()) 461 { 462 return ClangASTContext::GetNumTemplateArguments (m_opaque_sp->GetASTContext(), 463 m_opaque_sp->GetOpaqueQualType()); 464 } 465 return 0; 466 } 467 468 lldb::SBType 469 SBType::GetTemplateArgumentType (uint32_t idx) 470 { 471 if (IsValid()) 472 { 473 TemplateArgumentKind kind = eTemplateArgumentKindNull; 474 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 475 ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), 476 m_opaque_sp->GetOpaqueQualType(), 477 idx, 478 kind))); 479 } 480 return SBType(); 481 } 482 483 484 lldb::TemplateArgumentKind 485 SBType::GetTemplateArgumentKind (uint32_t idx) 486 { 487 TemplateArgumentKind kind = eTemplateArgumentKindNull; 488 if (IsValid()) 489 { 490 ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), 491 m_opaque_sp->GetOpaqueQualType(), 492 idx, 493 kind); 494 } 495 return kind; 496 } 497 498 499 500 501 SBTypeList::SBTypeList() : 502 m_opaque_ap(new TypeListImpl()) 503 { 504 } 505 506 SBTypeList::SBTypeList(const SBTypeList& rhs) : 507 m_opaque_ap(new TypeListImpl()) 508 { 509 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 510 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 511 } 512 513 bool 514 SBTypeList::IsValid () 515 { 516 return (m_opaque_ap.get() != NULL); 517 } 518 519 SBTypeList& 520 SBTypeList::operator = (const SBTypeList& rhs) 521 { 522 if (this != &rhs) 523 { 524 m_opaque_ap.reset (new TypeListImpl()); 525 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 526 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 527 } 528 return *this; 529 } 530 531 void 532 SBTypeList::Append (SBType type) 533 { 534 if (type.IsValid()) 535 m_opaque_ap->Append (type.m_opaque_sp); 536 } 537 538 SBType 539 SBTypeList::GetTypeAtIndex(uint32_t index) 540 { 541 if (m_opaque_ap.get()) 542 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 543 return SBType(); 544 } 545 546 uint32_t 547 SBTypeList::GetSize() 548 { 549 return m_opaque_ap->GetSize(); 550 } 551 552 SBTypeList::~SBTypeList() 553 { 554 } 555 556 bool 557 SBType::IsPointerType (void *opaque_type) 558 { 559 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 560 561 bool ret_value = ClangASTContext::IsPointerType (opaque_type); 562 563 if (log) 564 log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false")); 565 566 return ret_value; 567 } 568 569 570 SBTypeMember::SBTypeMember() : 571 m_opaque_ap() 572 { 573 } 574 575 SBTypeMember::~SBTypeMember() 576 { 577 } 578 579 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : 580 m_opaque_ap() 581 { 582 if (this != &rhs) 583 { 584 if (rhs.IsValid()) 585 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 586 } 587 } 588 589 lldb::SBTypeMember& 590 SBTypeMember::operator = (const lldb::SBTypeMember& rhs) 591 { 592 if (this != &rhs) 593 { 594 if (rhs.IsValid()) 595 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 596 } 597 return *this; 598 } 599 600 bool 601 SBTypeMember::IsValid() const 602 { 603 return m_opaque_ap.get(); 604 } 605 606 const char * 607 SBTypeMember::GetName () 608 { 609 if (m_opaque_ap.get()) 610 return m_opaque_ap->GetName().GetCString(); 611 return NULL; 612 } 613 614 SBType 615 SBTypeMember::GetType () 616 { 617 SBType sb_type; 618 if (m_opaque_ap.get()) 619 { 620 sb_type.SetSP (m_opaque_ap->GetTypeImpl()); 621 } 622 return sb_type; 623 624 } 625 626 uint64_t 627 SBTypeMember::GetOffsetInBytes() 628 { 629 if (m_opaque_ap.get()) 630 return (m_opaque_ap->GetBitOffset() + 7) / 8u; 631 return 0; 632 } 633 634 uint64_t 635 SBTypeMember::GetOffsetInBits() 636 { 637 if (m_opaque_ap.get()) 638 return m_opaque_ap->GetBitOffset(); 639 return 0; 640 } 641 642 bool 643 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) 644 { 645 Stream &strm = description.ref(); 646 647 if (m_opaque_ap.get()) 648 { 649 const uint32_t byte_offset = (m_opaque_ap->GetBitOffset() + 7) / 8u; 650 const char *name = m_opaque_ap->GetName().GetCString(); 651 strm.Printf ("+%u: (", byte_offset); 652 653 TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl()); 654 if (type_impl_sp) 655 type_impl_sp->GetDescription(strm, description_level); 656 657 strm.Printf (") %s", name); 658 } 659 else 660 { 661 strm.PutCString ("No value"); 662 } 663 return true; 664 } 665 666 667 void 668 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 669 { 670 m_opaque_ap.reset(type_member_impl); 671 } 672 673 TypeMemberImpl & 674 SBTypeMember::ref () 675 { 676 if (m_opaque_ap.get() == NULL) 677 m_opaque_ap.reset (new TypeMemberImpl()); 678 return *m_opaque_ap.get(); 679 } 680 681 const TypeMemberImpl & 682 SBTypeMember::ref () const 683 { 684 return *m_opaque_ap.get(); 685 } 686