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 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::SBType 278 SBType::GetCanonicalType() 279 { 280 if (IsValid()) 281 { 282 QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType())); 283 return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getCanonicalType().getAsOpaquePtr())); 284 } 285 return SBType(); 286 } 287 288 289 lldb::BasicType 290 SBType::GetBasicType() 291 { 292 if (IsValid()) 293 return ClangASTContext::GetLLDBBasicTypeEnumeration (m_opaque_sp->GetOpaqueQualType()); 294 return eBasicTypeInvalid; 295 } 296 297 SBType 298 SBType::GetBasicType(lldb::BasicType type) 299 { 300 if (IsValid()) 301 return SBType (ClangASTType::GetBasicType (m_opaque_sp->GetASTContext(), type)); 302 return SBType(); 303 } 304 305 uint32_t 306 SBType::GetNumberOfDirectBaseClasses () 307 { 308 if (IsValid()) 309 return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 310 return 0; 311 } 312 313 uint32_t 314 SBType::GetNumberOfVirtualBaseClasses () 315 { 316 if (IsValid()) 317 return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 318 return 0; 319 } 320 321 uint32_t 322 SBType::GetNumberOfFields () 323 { 324 if (IsValid()) 325 return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 326 return 0; 327 } 328 329 bool 330 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) 331 { 332 Stream &strm = description.ref(); 333 334 if (m_opaque_sp) 335 { 336 m_opaque_sp->GetDescription (strm, description_level); 337 } 338 else 339 strm.PutCString ("No value"); 340 341 return true; 342 } 343 344 345 346 SBTypeMember 347 SBType::GetDirectBaseClassAtIndex (uint32_t idx) 348 { 349 SBTypeMember sb_type_member; 350 if (IsValid()) 351 { 352 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 353 uint32_t bit_offset = 0; 354 clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); 355 if (clang_type) 356 { 357 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 358 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); 359 } 360 } 361 return sb_type_member; 362 363 } 364 365 SBTypeMember 366 SBType::GetVirtualBaseClassAtIndex (uint32_t idx) 367 { 368 SBTypeMember sb_type_member; 369 if (IsValid()) 370 { 371 uint32_t bit_offset = 0; 372 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 373 clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset); 374 if (clang_type) 375 { 376 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 377 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset)); 378 } 379 } 380 return sb_type_member; 381 } 382 383 SBTypeMember 384 SBType::GetFieldAtIndex (uint32_t idx) 385 { 386 SBTypeMember sb_type_member; 387 if (IsValid()) 388 { 389 uint64_t bit_offset = 0; 390 uint32_t bitfield_bit_size = 0; 391 bool is_bitfield = false; 392 clang::ASTContext* ast = m_opaque_sp->GetASTContext(); 393 std::string name_sstr; 394 clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield); 395 if (clang_type) 396 { 397 ConstString name; 398 if (!name_sstr.empty()) 399 name.SetCString(name_sstr.c_str()); 400 TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); 401 sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name, bitfield_bit_size, is_bitfield)); 402 } 403 } 404 return sb_type_member; 405 } 406 407 bool 408 SBType::IsTypeComplete() 409 { 410 if (!IsValid()) 411 return false; 412 413 return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); 414 } 415 416 const char* 417 SBType::GetName() 418 { 419 if (!IsValid()) 420 return ""; 421 422 return ClangASTType::GetConstTypeName(m_opaque_sp->GetASTContext(), 423 m_opaque_sp->GetOpaqueQualType()).GetCString(); 424 } 425 426 lldb::TypeClass 427 SBType::GetTypeClass () 428 { 429 if (IsValid()) 430 return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(), 431 m_opaque_sp->GetOpaqueQualType()); 432 return lldb::eTypeClassInvalid; 433 } 434 435 uint32_t 436 SBType::GetNumberOfTemplateArguments () 437 { 438 if (IsValid()) 439 { 440 return ClangASTContext::GetNumTemplateArguments (m_opaque_sp->GetASTContext(), 441 m_opaque_sp->GetOpaqueQualType()); 442 } 443 return 0; 444 } 445 446 lldb::SBType 447 SBType::GetTemplateArgumentType (uint32_t idx) 448 { 449 if (IsValid()) 450 { 451 TemplateArgumentKind kind = eTemplateArgumentKindNull; 452 return SBType(ClangASTType(m_opaque_sp->GetASTContext(), 453 ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), 454 m_opaque_sp->GetOpaqueQualType(), 455 idx, 456 kind))); 457 } 458 return SBType(); 459 } 460 461 462 lldb::TemplateArgumentKind 463 SBType::GetTemplateArgumentKind (uint32_t idx) 464 { 465 TemplateArgumentKind kind = eTemplateArgumentKindNull; 466 if (IsValid()) 467 { 468 ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(), 469 m_opaque_sp->GetOpaqueQualType(), 470 idx, 471 kind); 472 } 473 return kind; 474 } 475 476 477 478 479 SBTypeList::SBTypeList() : 480 m_opaque_ap(new TypeListImpl()) 481 { 482 } 483 484 SBTypeList::SBTypeList(const SBTypeList& rhs) : 485 m_opaque_ap(new TypeListImpl()) 486 { 487 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 488 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 489 } 490 491 bool 492 SBTypeList::IsValid () 493 { 494 return (m_opaque_ap.get() != NULL); 495 } 496 497 SBTypeList& 498 SBTypeList::operator = (const SBTypeList& rhs) 499 { 500 if (this != &rhs) 501 { 502 m_opaque_ap.reset (new TypeListImpl()); 503 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 504 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 505 } 506 return *this; 507 } 508 509 void 510 SBTypeList::Append (SBType type) 511 { 512 if (type.IsValid()) 513 m_opaque_ap->Append (type.m_opaque_sp); 514 } 515 516 SBType 517 SBTypeList::GetTypeAtIndex(uint32_t index) 518 { 519 if (m_opaque_ap.get()) 520 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 521 return SBType(); 522 } 523 524 uint32_t 525 SBTypeList::GetSize() 526 { 527 return m_opaque_ap->GetSize(); 528 } 529 530 SBTypeList::~SBTypeList() 531 { 532 } 533 534 bool 535 SBType::IsPointerType (void *opaque_type) 536 { 537 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 538 539 bool ret_value = ClangASTContext::IsPointerType (opaque_type); 540 541 if (log) 542 log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false")); 543 544 return ret_value; 545 } 546 547 548 SBTypeMember::SBTypeMember() : 549 m_opaque_ap() 550 { 551 } 552 553 SBTypeMember::~SBTypeMember() 554 { 555 } 556 557 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : 558 m_opaque_ap() 559 { 560 if (this != &rhs) 561 { 562 if (rhs.IsValid()) 563 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 564 } 565 } 566 567 lldb::SBTypeMember& 568 SBTypeMember::operator = (const lldb::SBTypeMember& rhs) 569 { 570 if (this != &rhs) 571 { 572 if (rhs.IsValid()) 573 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 574 } 575 return *this; 576 } 577 578 bool 579 SBTypeMember::IsValid() const 580 { 581 return m_opaque_ap.get(); 582 } 583 584 const char * 585 SBTypeMember::GetName () 586 { 587 if (m_opaque_ap.get()) 588 return m_opaque_ap->GetName().GetCString(); 589 return NULL; 590 } 591 592 SBType 593 SBTypeMember::GetType () 594 { 595 SBType sb_type; 596 if (m_opaque_ap.get()) 597 { 598 sb_type.SetSP (m_opaque_ap->GetTypeImpl()); 599 } 600 return sb_type; 601 602 } 603 604 uint64_t 605 SBTypeMember::GetOffsetInBytes() 606 { 607 if (m_opaque_ap.get()) 608 return m_opaque_ap->GetBitOffset() / 8u; 609 return 0; 610 } 611 612 uint64_t 613 SBTypeMember::GetOffsetInBits() 614 { 615 if (m_opaque_ap.get()) 616 return m_opaque_ap->GetBitOffset(); 617 return 0; 618 } 619 620 bool 621 SBTypeMember::IsBitfield() 622 { 623 if (m_opaque_ap.get()) 624 return m_opaque_ap->GetIsBitfield(); 625 return false; 626 } 627 628 uint32_t 629 SBTypeMember::GetBitfieldSizeInBits() 630 { 631 if (m_opaque_ap.get()) 632 return m_opaque_ap->GetBitfieldBitSize(); 633 return 0; 634 } 635 636 637 bool 638 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) 639 { 640 Stream &strm = description.ref(); 641 642 if (m_opaque_ap.get()) 643 { 644 const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); 645 const uint32_t byte_offset = bit_offset / 8u; 646 const uint32_t byte_bit_offset = bit_offset % 8u; 647 const char *name = m_opaque_ap->GetName().GetCString(); 648 if (byte_bit_offset) 649 strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset); 650 else 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 if (m_opaque_ap->GetIsBitfield()) 659 { 660 const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); 661 strm.Printf (" : %u", bitfield_bit_size); 662 } 663 } 664 else 665 { 666 strm.PutCString ("No value"); 667 } 668 return true; 669 } 670 671 672 void 673 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 674 { 675 m_opaque_ap.reset(type_member_impl); 676 } 677 678 TypeMemberImpl & 679 SBTypeMember::ref () 680 { 681 if (m_opaque_ap.get() == NULL) 682 m_opaque_ap.reset (new TypeMemberImpl()); 683 return *m_opaque_ap.get(); 684 } 685 686 const TypeMemberImpl & 687 SBTypeMember::ref () const 688 { 689 return *m_opaque_ap.get(); 690 } 691