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 m_opaque_sp->GetClangASTType().GetByteSize(); 146 147 } 148 149 bool 150 SBType::IsPointerType() 151 { 152 if (!IsValid()) 153 return false; 154 return m_opaque_sp->GetClangASTType().IsPointerType(); 155 } 156 157 bool 158 SBType::IsReferenceType() 159 { 160 if (!IsValid()) 161 return false; 162 return m_opaque_sp->GetClangASTType().IsReferenceType(); 163 } 164 165 SBType 166 SBType::GetPointerType() 167 { 168 if (!IsValid()) 169 return SBType(); 170 171 return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointerType())); 172 } 173 174 SBType 175 SBType::GetPointeeType() 176 { 177 if (!IsValid()) 178 return SBType(); 179 return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointeeType())); 180 } 181 182 SBType 183 SBType::GetReferenceType() 184 { 185 if (!IsValid()) 186 return SBType(); 187 return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetLValueReferenceType())); 188 } 189 190 SBType 191 SBType::GetDereferencedType() 192 { 193 if (!IsValid()) 194 return SBType(); 195 return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetNonReferenceType())); 196 } 197 198 bool 199 SBType::IsFunctionType () 200 { 201 if (!IsValid()) 202 return false; 203 return m_opaque_sp->GetClangASTType().IsFunctionType(); 204 } 205 206 bool 207 SBType::IsPolymorphicClass () 208 { 209 if (!IsValid()) 210 return false; 211 return m_opaque_sp->GetClangASTType().IsPolymorphicClass(); 212 } 213 214 215 216 lldb::SBType 217 SBType::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 228 lldb::SBTypeList 229 SBType::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 246 lldb::SBType 247 SBType::GetUnqualifiedType() 248 { 249 if (!IsValid()) 250 return SBType(); 251 return SBType(m_opaque_sp->GetClangASTType().GetFullyUnqualifiedType()); 252 } 253 254 lldb::SBType 255 SBType::GetCanonicalType() 256 { 257 if (IsValid()) 258 return SBType(m_opaque_sp->GetClangASTType().GetCanonicalType()); 259 return SBType(); 260 } 261 262 263 lldb::BasicType 264 SBType::GetBasicType() 265 { 266 if (IsValid()) 267 return m_opaque_sp->GetClangASTType().GetBasicTypeEnumeration (); 268 return eBasicTypeInvalid; 269 } 270 271 SBType 272 SBType::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 279 uint32_t 280 SBType::GetNumberOfDirectBaseClasses () 281 { 282 if (IsValid()) 283 return m_opaque_sp->GetClangASTType().GetNumDirectBaseClasses(); 284 return 0; 285 } 286 287 uint32_t 288 SBType::GetNumberOfVirtualBaseClasses () 289 { 290 if (IsValid()) 291 return m_opaque_sp->GetClangASTType().GetNumVirtualBaseClasses(); 292 return 0; 293 } 294 295 uint32_t 296 SBType::GetNumberOfFields () 297 { 298 if (IsValid()) 299 return m_opaque_sp->GetClangASTType().GetNumFields(); 300 return 0; 301 } 302 303 bool 304 SBType::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 320 SBTypeMember 321 SBType::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 341 SBTypeMember 342 SBType::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 361 SBTypeMember 362 SBType::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 395 bool 396 SBType::IsTypeComplete() 397 { 398 if (!IsValid()) 399 return false; 400 return m_opaque_sp->GetClangASTType().IsCompleteType(); 401 } 402 403 const char* 404 SBType::GetName() 405 { 406 if (!IsValid()) 407 return ""; 408 return m_opaque_sp->GetClangASTType().GetConstTypeName().GetCString(); 409 } 410 411 lldb::TypeClass 412 SBType::GetTypeClass () 413 { 414 if (IsValid()) 415 return m_opaque_sp->GetClangASTType().GetTypeClass(); 416 return lldb::eTypeClassInvalid; 417 } 418 419 uint32_t 420 SBType::GetNumberOfTemplateArguments () 421 { 422 if (IsValid()) 423 return m_opaque_sp->GetClangASTType().GetNumTemplateArguments(); 424 return 0; 425 } 426 427 lldb::SBType 428 SBType::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 441 lldb::TemplateArgumentKind 442 SBType::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 451 SBTypeList::SBTypeList() : 452 m_opaque_ap(new TypeListImpl()) 453 { 454 } 455 456 SBTypeList::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 463 bool 464 SBTypeList::IsValid () 465 { 466 return (m_opaque_ap.get() != NULL); 467 } 468 469 SBTypeList& 470 SBTypeList::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 481 void 482 SBTypeList::Append (SBType type) 483 { 484 if (type.IsValid()) 485 m_opaque_ap->Append (type.m_opaque_sp); 486 } 487 488 SBType 489 SBTypeList::GetTypeAtIndex(uint32_t index) 490 { 491 if (m_opaque_ap.get()) 492 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 493 return SBType(); 494 } 495 496 uint32_t 497 SBTypeList::GetSize() 498 { 499 return m_opaque_ap->GetSize(); 500 } 501 502 SBTypeList::~SBTypeList() 503 { 504 } 505 506 SBTypeMember::SBTypeMember() : 507 m_opaque_ap() 508 { 509 } 510 511 SBTypeMember::~SBTypeMember() 512 { 513 } 514 515 SBTypeMember::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 525 lldb::SBTypeMember& 526 SBTypeMember::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 536 bool 537 SBTypeMember::IsValid() const 538 { 539 return m_opaque_ap.get(); 540 } 541 542 const char * 543 SBTypeMember::GetName () 544 { 545 if (m_opaque_ap.get()) 546 return m_opaque_ap->GetName().GetCString(); 547 return NULL; 548 } 549 550 SBType 551 SBTypeMember::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 562 uint64_t 563 SBTypeMember::GetOffsetInBytes() 564 { 565 if (m_opaque_ap.get()) 566 return m_opaque_ap->GetBitOffset() / 8u; 567 return 0; 568 } 569 570 uint64_t 571 SBTypeMember::GetOffsetInBits() 572 { 573 if (m_opaque_ap.get()) 574 return m_opaque_ap->GetBitOffset(); 575 return 0; 576 } 577 578 bool 579 SBTypeMember::IsBitfield() 580 { 581 if (m_opaque_ap.get()) 582 return m_opaque_ap->GetIsBitfield(); 583 return false; 584 } 585 586 uint32_t 587 SBTypeMember::GetBitfieldSizeInBits() 588 { 589 if (m_opaque_ap.get()) 590 return m_opaque_ap->GetBitfieldBitSize(); 591 return 0; 592 } 593 594 595 bool 596 SBTypeMember::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 630 void 631 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 632 { 633 m_opaque_ap.reset(type_member_impl); 634 } 635 636 TypeMemberImpl & 637 SBTypeMember::ref () 638 { 639 if (m_opaque_ap.get() == NULL) 640 m_opaque_ap.reset (new TypeMemberImpl()); 641 return *m_opaque_ap.get(); 642 } 643 644 const TypeMemberImpl & 645 SBTypeMember::ref () const 646 { 647 return *m_opaque_ap.get(); 648 } 649