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