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