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 const char* 430 SBType::GetName() 431 { 432 if (!IsValid()) 433 return ""; 434 435 return ClangASTType::GetConstTypeName(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 LogSP 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() + 7) / 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::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) 634 { 635 Stream &strm = description.ref(); 636 637 if (m_opaque_ap.get()) 638 { 639 const uint32_t byte_offset = (m_opaque_ap->GetBitOffset() + 7) / 8u; 640 const char *name = m_opaque_ap->GetName().GetCString(); 641 strm.Printf ("+%u: (", byte_offset); 642 643 TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl()); 644 if (type_impl_sp) 645 type_impl_sp->GetDescription(strm, description_level); 646 647 strm.Printf (") %s", name); 648 } 649 else 650 { 651 strm.PutCString ("No value"); 652 } 653 return true; 654 } 655 656 657 void 658 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 659 { 660 m_opaque_ap.reset(type_member_impl); 661 } 662 663 TypeMemberImpl & 664 SBTypeMember::ref () 665 { 666 if (m_opaque_ap.get() == NULL) 667 m_opaque_ap.reset (new TypeMemberImpl()); 668 return *m_opaque_ap.get(); 669 } 670 671 const TypeMemberImpl & 672 SBTypeMember::ref () const 673 { 674 return *m_opaque_ap.get(); 675 } 676