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