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