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