1//===-- CompilerType.cpp --------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "lldb/Symbol/CompilerType.h" 10 11#include "lldb/Core/Debugger.h" 12#include "lldb/Symbol/Type.h" 13#include "lldb/Target/ExecutionContext.h" 14#include "lldb/Target/Process.h" 15#include "lldb/Utility/ConstString.h" 16#include "lldb/Utility/DataBufferHeap.h" 17#include "lldb/Utility/DataExtractor.h" 18#include "lldb/Utility/Scalar.h" 19#include "lldb/Utility/Stream.h" 20#include "lldb/Utility/StreamString.h" 21 22#include <iterator> 23#include <mutex> 24#include <optional> 25 26using namespace lldb; 27using namespace lldb_private; 28 29// Tests 30 31bool CompilerType::IsAggregateType() const { 32 if (IsValid()) 33 if (auto type_system_sp = GetTypeSystem()) 34 return type_system_sp->IsAggregateType(m_type); 35 return false; 36} 37 38bool CompilerType::IsAnonymousType() const { 39 if (IsValid()) 40 if (auto type_system_sp = GetTypeSystem()) 41 return type_system_sp->IsAnonymousType(m_type); 42 return false; 43} 44 45bool CompilerType::IsScopedEnumerationType() const { 46 if (IsValid()) 47 if (auto type_system_sp = GetTypeSystem()) 48 return type_system_sp->IsScopedEnumerationType(m_type); 49 return false; 50} 51 52bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size, 53 bool *is_incomplete) const { 54 if (IsValid()) 55 if (auto type_system_sp = GetTypeSystem()) 56 return type_system_sp->IsArrayType(m_type, element_type_ptr, size, 57 is_incomplete); 58 59 if (element_type_ptr) 60 element_type_ptr->Clear(); 61 if (size) 62 *size = 0; 63 if (is_incomplete) 64 *is_incomplete = false; 65 return false; 66} 67 68bool CompilerType::IsVectorType(CompilerType *element_type, 69 uint64_t *size) const { 70 if (IsValid()) 71 if (auto type_system_sp = GetTypeSystem()) 72 return type_system_sp->IsVectorType(m_type, element_type, size); 73 return false; 74} 75 76bool CompilerType::IsRuntimeGeneratedType() const { 77 if (IsValid()) 78 if (auto type_system_sp = GetTypeSystem()) 79 return type_system_sp->IsRuntimeGeneratedType(m_type); 80 return false; 81} 82 83bool CompilerType::IsCharType() const { 84 if (IsValid()) 85 if (auto type_system_sp = GetTypeSystem()) 86 return type_system_sp->IsCharType(m_type); 87 return false; 88} 89 90bool CompilerType::IsCompleteType() const { 91 if (IsValid()) 92 if (auto type_system_sp = GetTypeSystem()) 93 return type_system_sp->IsCompleteType(m_type); 94 return false; 95} 96 97bool CompilerType::IsForcefullyCompleted() const { 98 if (IsValid()) 99 if (auto type_system_sp = GetTypeSystem()) 100 return type_system_sp->IsForcefullyCompleted(m_type); 101 return false; 102} 103 104bool CompilerType::IsConst() const { 105 if (IsValid()) 106 if (auto type_system_sp = GetTypeSystem()) 107 return type_system_sp->IsConst(m_type); 108 return false; 109} 110 111bool CompilerType::IsFunctionType() const { 112 if (IsValid()) 113 if (auto type_system_sp = GetTypeSystem()) 114 return type_system_sp->IsFunctionType(m_type); 115 return false; 116} 117 118// Used to detect "Homogeneous Floating-point Aggregates" 119uint32_t 120CompilerType::IsHomogeneousAggregate(CompilerType *base_type_ptr) const { 121 if (IsValid()) 122 if (auto type_system_sp = GetTypeSystem()) 123 return type_system_sp->IsHomogeneousAggregate(m_type, base_type_ptr); 124 return 0; 125} 126 127size_t CompilerType::GetNumberOfFunctionArguments() const { 128 if (IsValid()) 129 if (auto type_system_sp = GetTypeSystem()) 130 return type_system_sp->GetNumberOfFunctionArguments(m_type); 131 return 0; 132} 133 134CompilerType 135CompilerType::GetFunctionArgumentAtIndex(const size_t index) const { 136 if (IsValid()) 137 if (auto type_system_sp = GetTypeSystem()) 138 return type_system_sp->GetFunctionArgumentAtIndex(m_type, index); 139 return CompilerType(); 140} 141 142bool CompilerType::IsFunctionPointerType() const { 143 if (IsValid()) 144 if (auto type_system_sp = GetTypeSystem()) 145 return type_system_sp->IsFunctionPointerType(m_type); 146 return false; 147} 148 149bool CompilerType::IsMemberFunctionPointerType() const { 150 if (IsValid()) 151 if (auto type_system_sp = GetTypeSystem()) 152 return type_system_sp->IsMemberFunctionPointerType(m_type); 153 return false; 154} 155 156bool CompilerType::IsBlockPointerType( 157 CompilerType *function_pointer_type_ptr) const { 158 if (IsValid()) 159 if (auto type_system_sp = GetTypeSystem()) 160 return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr); 161 return false; 162} 163 164bool CompilerType::IsIntegerType(bool &is_signed) const { 165 if (IsValid()) 166 if (auto type_system_sp = GetTypeSystem()) 167 return type_system_sp->IsIntegerType(m_type, is_signed); 168 return false; 169} 170 171bool CompilerType::IsEnumerationType(bool &is_signed) const { 172 if (IsValid()) 173 if (auto type_system_sp = GetTypeSystem()) 174 return type_system_sp->IsEnumerationType(m_type, is_signed); 175 return false; 176} 177 178bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const { 179 return IsIntegerType(is_signed) || IsEnumerationType(is_signed); 180} 181 182bool CompilerType::IsPointerType(CompilerType *pointee_type) const { 183 if (IsValid()) { 184 if (auto type_system_sp = GetTypeSystem()) 185 return type_system_sp->IsPointerType(m_type, pointee_type); 186 } 187 if (pointee_type) 188 pointee_type->Clear(); 189 return false; 190} 191 192bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const { 193 if (IsValid()) { 194 if (auto type_system_sp = GetTypeSystem()) 195 return type_system_sp->IsPointerOrReferenceType(m_type, pointee_type); 196 } 197 if (pointee_type) 198 pointee_type->Clear(); 199 return false; 200} 201 202bool CompilerType::IsReferenceType(CompilerType *pointee_type, 203 bool *is_rvalue) const { 204 if (IsValid()) { 205 if (auto type_system_sp = GetTypeSystem()) 206 return type_system_sp->IsReferenceType(m_type, pointee_type, is_rvalue); 207 } 208 if (pointee_type) 209 pointee_type->Clear(); 210 return false; 211} 212 213bool CompilerType::ShouldTreatScalarValueAsAddress() const { 214 if (IsValid()) 215 if (auto type_system_sp = GetTypeSystem()) 216 return type_system_sp->ShouldTreatScalarValueAsAddress(m_type); 217 return false; 218} 219 220bool CompilerType::IsFloatingPointType(uint32_t &count, 221 bool &is_complex) const { 222 if (IsValid()) { 223 if (auto type_system_sp = GetTypeSystem()) 224 return type_system_sp->IsFloatingPointType(m_type, count, is_complex); 225 } 226 count = 0; 227 is_complex = false; 228 return false; 229} 230 231bool CompilerType::IsDefined() const { 232 if (IsValid()) 233 if (auto type_system_sp = GetTypeSystem()) 234 return type_system_sp->IsDefined(m_type); 235 return true; 236} 237 238bool CompilerType::IsPolymorphicClass() const { 239 if (IsValid()) { 240 if (auto type_system_sp = GetTypeSystem()) 241 return type_system_sp->IsPolymorphicClass(m_type); 242 } 243 return false; 244} 245 246bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type, 247 bool check_cplusplus, 248 bool check_objc) const { 249 if (IsValid()) 250 if (auto type_system_sp = GetTypeSystem()) 251 return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type, 252 check_cplusplus, check_objc); 253 return false; 254} 255 256bool CompilerType::IsScalarType() const { 257 if (IsValid()) 258 if (auto type_system_sp = GetTypeSystem()) 259 return type_system_sp->IsScalarType(m_type); 260 return false; 261} 262 263bool CompilerType::IsTemplateType() const { 264 if (IsValid()) 265 if (auto type_system_sp = GetTypeSystem()) 266 return type_system_sp->IsTemplateType(m_type); 267 return false; 268} 269 270bool CompilerType::IsTypedefType() const { 271 if (IsValid()) 272 if (auto type_system_sp = GetTypeSystem()) 273 return type_system_sp->IsTypedefType(m_type); 274 return false; 275} 276 277bool CompilerType::IsVoidType() const { 278 if (IsValid()) 279 if (auto type_system_sp = GetTypeSystem()) 280 return type_system_sp->IsVoidType(m_type); 281 return false; 282} 283 284bool CompilerType::IsPointerToScalarType() const { 285 if (!IsValid()) 286 return false; 287 288 return IsPointerType() && GetPointeeType().IsScalarType(); 289} 290 291bool CompilerType::IsArrayOfScalarType() const { 292 CompilerType element_type; 293 if (IsArrayType(&element_type)) 294 return element_type.IsScalarType(); 295 return false; 296} 297 298bool CompilerType::IsBeingDefined() const { 299 if (IsValid()) 300 if (auto type_system_sp = GetTypeSystem()) 301 return type_system_sp->IsBeingDefined(m_type); 302 return false; 303} 304 305bool CompilerType::IsInteger() const { 306 bool is_signed = false; // May be reset by the call below. 307 return IsIntegerType(is_signed); 308} 309 310bool CompilerType::IsFloat() const { 311 uint32_t count = 0; 312 bool is_complex = false; 313 return IsFloatingPointType(count, is_complex); 314} 315 316bool CompilerType::IsEnumerationType() const { 317 bool is_signed = false; // May be reset by the call below. 318 return IsEnumerationType(is_signed); 319} 320 321bool CompilerType::IsUnscopedEnumerationType() const { 322 return IsEnumerationType() && !IsScopedEnumerationType(); 323} 324 325bool CompilerType::IsIntegerOrUnscopedEnumerationType() const { 326 return IsInteger() || IsUnscopedEnumerationType(); 327} 328 329bool CompilerType::IsSigned() const { 330 return GetTypeInfo() & lldb::eTypeIsSigned; 331} 332 333bool CompilerType::IsNullPtrType() const { 334 return GetCanonicalType().GetBasicTypeEnumeration() == 335 lldb::eBasicTypeNullPtr; 336} 337 338bool CompilerType::IsBoolean() const { 339 return GetCanonicalType().GetBasicTypeEnumeration() == lldb::eBasicTypeBool; 340} 341 342bool CompilerType::IsEnumerationIntegerTypeSigned() const { 343 if (IsValid()) 344 return GetEnumerationIntegerType().GetTypeInfo() & lldb::eTypeIsSigned; 345 346 return false; 347} 348 349bool CompilerType::IsScalarOrUnscopedEnumerationType() const { 350 return IsScalarType() || IsUnscopedEnumerationType(); 351} 352 353bool CompilerType::IsPromotableIntegerType() const { 354 // Unscoped enums are always considered as promotable, even if their 355 // underlying type does not need to be promoted (e.g. "int"). 356 if (IsUnscopedEnumerationType()) 357 return true; 358 359 switch (GetCanonicalType().GetBasicTypeEnumeration()) { 360 case lldb::eBasicTypeBool: 361 case lldb::eBasicTypeChar: 362 case lldb::eBasicTypeSignedChar: 363 case lldb::eBasicTypeUnsignedChar: 364 case lldb::eBasicTypeShort: 365 case lldb::eBasicTypeUnsignedShort: 366 case lldb::eBasicTypeWChar: 367 case lldb::eBasicTypeSignedWChar: 368 case lldb::eBasicTypeUnsignedWChar: 369 case lldb::eBasicTypeChar16: 370 case lldb::eBasicTypeChar32: 371 return true; 372 373 default: 374 return false; 375 } 376 377 llvm_unreachable("All cases handled above."); 378} 379 380bool CompilerType::IsPointerToVoid() const { 381 if (!IsValid()) 382 return false; 383 384 return IsPointerType() && 385 GetPointeeType().GetBasicTypeEnumeration() == lldb::eBasicTypeVoid; 386} 387 388bool CompilerType::IsRecordType() const { 389 if (!IsValid()) 390 return false; 391 392 return GetCanonicalType().GetTypeClass() & 393 (lldb::eTypeClassClass | lldb::eTypeClassStruct | 394 lldb::eTypeClassUnion); 395} 396 397bool CompilerType::IsVirtualBase(CompilerType target_base, 398 CompilerType *virtual_base, 399 bool carry_virtual) const { 400 if (CompareTypes(target_base)) 401 return carry_virtual; 402 403 if (!carry_virtual) { 404 uint32_t num_virtual_bases = GetNumVirtualBaseClasses(); 405 for (uint32_t i = 0; i < num_virtual_bases; ++i) { 406 uint32_t bit_offset; 407 auto base = GetVirtualBaseClassAtIndex(i, &bit_offset); 408 if (base.IsVirtualBase(target_base, virtual_base, 409 /*carry_virtual*/ true)) { 410 if (virtual_base) 411 *virtual_base = base; 412 413 return true; 414 } 415 } 416 } 417 418 uint32_t num_direct_bases = GetNumDirectBaseClasses(); 419 for (uint32_t i = 0; i < num_direct_bases; ++i) { 420 uint32_t bit_offset; 421 auto base = GetDirectBaseClassAtIndex(i, &bit_offset); 422 if (base.IsVirtualBase(target_base, virtual_base, carry_virtual)) 423 return true; 424 } 425 426 return false; 427} 428 429bool CompilerType::IsContextuallyConvertibleToBool() const { 430 return IsScalarType() || IsUnscopedEnumerationType() || IsPointerType() || 431 IsNullPtrType() || IsArrayType(); 432} 433 434bool CompilerType::IsBasicType() const { 435 return GetCanonicalType().GetBasicTypeEnumeration() != 436 lldb::eBasicTypeInvalid; 437} 438 439std::string CompilerType::TypeDescription() { 440 auto name = GetTypeName(); 441 auto canonical_name = GetCanonicalType().GetTypeName(); 442 if (name.IsEmpty() || canonical_name.IsEmpty()) 443 return "''"; // Should not happen, unless the input is broken somehow. 444 445 if (name == canonical_name) 446 return llvm::formatv("'{0}'", name); 447 448 return llvm::formatv("'{0}' (canonically referred to as '{1}')", name, 449 canonical_name); 450} 451 452bool CompilerType::CompareTypes(CompilerType rhs) const { 453 if (*this == rhs) 454 return true; 455 456 const ConstString name = GetFullyUnqualifiedType().GetTypeName(); 457 const ConstString rhs_name = rhs.GetFullyUnqualifiedType().GetTypeName(); 458 return name == rhs_name; 459} 460 461const char *CompilerType::GetTypeTag() { 462 switch (GetTypeClass()) { 463 case lldb::eTypeClassClass: 464 return "class"; 465 case lldb::eTypeClassEnumeration: 466 return "enum"; 467 case lldb::eTypeClassStruct: 468 return "struct"; 469 case lldb::eTypeClassUnion: 470 return "union"; 471 default: 472 return "unknown"; 473 } 474 llvm_unreachable("All cases are covered by code above."); 475} 476 477uint32_t CompilerType::GetNumberOfNonEmptyBaseClasses() { 478 uint32_t ret = 0; 479 uint32_t num_direct_bases = GetNumDirectBaseClasses(); 480 481 for (uint32_t i = 0; i < num_direct_bases; ++i) { 482 uint32_t bit_offset; 483 CompilerType base_type = GetDirectBaseClassAtIndex(i, &bit_offset); 484 if (base_type.GetNumFields() > 0 || 485 base_type.GetNumberOfNonEmptyBaseClasses() > 0) 486 ret += 1; 487 } 488 return ret; 489} 490 491// Type Completion 492 493bool CompilerType::GetCompleteType() const { 494 if (IsValid()) 495 if (auto type_system_sp = GetTypeSystem()) 496 return type_system_sp->GetCompleteType(m_type); 497 return false; 498} 499 500// AST related queries 501size_t CompilerType::GetPointerByteSize() const { 502 if (auto type_system_sp = GetTypeSystem()) 503 return type_system_sp->GetPointerByteSize(); 504 return 0; 505} 506 507ConstString CompilerType::GetTypeName(bool BaseOnly) const { 508 if (IsValid()) { 509 if (auto type_system_sp = GetTypeSystem()) 510 return type_system_sp->GetTypeName(m_type, BaseOnly); 511 } 512 return ConstString("<invalid>"); 513} 514 515ConstString CompilerType::GetDisplayTypeName() const { 516 if (IsValid()) 517 if (auto type_system_sp = GetTypeSystem()) 518 return type_system_sp->GetDisplayTypeName(m_type); 519 return ConstString("<invalid>"); 520} 521 522uint32_t CompilerType::GetTypeInfo( 523 CompilerType *pointee_or_element_compiler_type) const { 524 if (IsValid()) 525 if (auto type_system_sp = GetTypeSystem()) 526 return type_system_sp->GetTypeInfo(m_type, 527 pointee_or_element_compiler_type); 528 return 0; 529} 530 531lldb::LanguageType CompilerType::GetMinimumLanguage() { 532 if (IsValid()) 533 if (auto type_system_sp = GetTypeSystem()) 534 return type_system_sp->GetMinimumLanguage(m_type); 535 return lldb::eLanguageTypeC; 536} 537 538lldb::TypeClass CompilerType::GetTypeClass() const { 539 if (IsValid()) 540 if (auto type_system_sp = GetTypeSystem()) 541 return type_system_sp->GetTypeClass(m_type); 542 return lldb::eTypeClassInvalid; 543} 544 545void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system, 546 lldb::opaque_compiler_type_t type) { 547 m_type_system = type_system; 548 m_type = type; 549} 550 551void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system, 552 lldb::opaque_compiler_type_t type) { 553 m_type_system = type_system.GetSharedPointer(); 554 m_type = type; 555} 556 557unsigned CompilerType::GetTypeQualifiers() const { 558 if (IsValid()) 559 if (auto type_system_sp = GetTypeSystem()) 560 return type_system_sp->GetTypeQualifiers(m_type); 561 return 0; 562} 563 564// Creating related types 565 566CompilerType 567CompilerType::GetArrayElementType(ExecutionContextScope *exe_scope) const { 568 if (IsValid()) { 569 if (auto type_system_sp = GetTypeSystem()) 570 return type_system_sp->GetArrayElementType(m_type, exe_scope); 571 } 572 return CompilerType(); 573} 574 575CompilerType CompilerType::GetArrayType(uint64_t size) const { 576 if (IsValid()) { 577 if (auto type_system_sp = GetTypeSystem()) 578 return type_system_sp->GetArrayType(m_type, size); 579 } 580 return CompilerType(); 581} 582 583CompilerType CompilerType::GetCanonicalType() const { 584 if (IsValid()) 585 if (auto type_system_sp = GetTypeSystem()) 586 return type_system_sp->GetCanonicalType(m_type); 587 return CompilerType(); 588} 589 590CompilerType CompilerType::GetFullyUnqualifiedType() const { 591 if (IsValid()) 592 if (auto type_system_sp = GetTypeSystem()) 593 return type_system_sp->GetFullyUnqualifiedType(m_type); 594 return CompilerType(); 595} 596 597CompilerType CompilerType::GetEnumerationIntegerType() const { 598 if (IsValid()) 599 if (auto type_system_sp = GetTypeSystem()) 600 return type_system_sp->GetEnumerationIntegerType(m_type); 601 return CompilerType(); 602} 603 604int CompilerType::GetFunctionArgumentCount() const { 605 if (IsValid()) { 606 if (auto type_system_sp = GetTypeSystem()) 607 return type_system_sp->GetFunctionArgumentCount(m_type); 608 } 609 return -1; 610} 611 612CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const { 613 if (IsValid()) { 614 if (auto type_system_sp = GetTypeSystem()) 615 return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx); 616 } 617 return CompilerType(); 618} 619 620CompilerType CompilerType::GetFunctionReturnType() const { 621 if (IsValid()) { 622 if (auto type_system_sp = GetTypeSystem()) 623 return type_system_sp->GetFunctionReturnType(m_type); 624 } 625 return CompilerType(); 626} 627 628size_t CompilerType::GetNumMemberFunctions() const { 629 if (IsValid()) { 630 if (auto type_system_sp = GetTypeSystem()) 631 return type_system_sp->GetNumMemberFunctions(m_type); 632 } 633 return 0; 634} 635 636TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) { 637 if (IsValid()) { 638 if (auto type_system_sp = GetTypeSystem()) 639 return type_system_sp->GetMemberFunctionAtIndex(m_type, idx); 640 } 641 return TypeMemberFunctionImpl(); 642} 643 644CompilerType CompilerType::GetNonReferenceType() const { 645 if (IsValid()) 646 if (auto type_system_sp = GetTypeSystem()) 647 return type_system_sp->GetNonReferenceType(m_type); 648 return CompilerType(); 649} 650 651CompilerType CompilerType::GetPointeeType() const { 652 if (IsValid()) { 653 if (auto type_system_sp = GetTypeSystem()) 654 return type_system_sp->GetPointeeType(m_type); 655 } 656 return CompilerType(); 657} 658 659CompilerType CompilerType::GetPointerType() const { 660 if (IsValid()) { 661 if (auto type_system_sp = GetTypeSystem()) 662 return type_system_sp->GetPointerType(m_type); 663 } 664 return CompilerType(); 665} 666 667CompilerType CompilerType::GetLValueReferenceType() const { 668 if (IsValid()) 669 if (auto type_system_sp = GetTypeSystem()) 670 return type_system_sp->GetLValueReferenceType(m_type); 671 return CompilerType(); 672} 673 674CompilerType CompilerType::GetRValueReferenceType() const { 675 if (IsValid()) 676 if (auto type_system_sp = GetTypeSystem()) 677 return type_system_sp->GetRValueReferenceType(m_type); 678 return CompilerType(); 679} 680 681CompilerType CompilerType::GetAtomicType() const { 682 if (IsValid()) 683 if (auto type_system_sp = GetTypeSystem()) 684 return type_system_sp->GetAtomicType(m_type); 685 return CompilerType(); 686} 687 688CompilerType CompilerType::AddConstModifier() const { 689 if (IsValid()) 690 if (auto type_system_sp = GetTypeSystem()) 691 return type_system_sp->AddConstModifier(m_type); 692 return CompilerType(); 693} 694 695CompilerType CompilerType::AddVolatileModifier() const { 696 if (IsValid()) 697 if (auto type_system_sp = GetTypeSystem()) 698 return type_system_sp->AddVolatileModifier(m_type); 699 return CompilerType(); 700} 701 702CompilerType CompilerType::AddRestrictModifier() const { 703 if (IsValid()) 704 if (auto type_system_sp = GetTypeSystem()) 705 return type_system_sp->AddRestrictModifier(m_type); 706 return CompilerType(); 707} 708 709CompilerType CompilerType::CreateTypedef(const char *name, 710 const CompilerDeclContext &decl_ctx, 711 uint32_t payload) const { 712 if (IsValid()) 713 if (auto type_system_sp = GetTypeSystem()) 714 return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload); 715 return CompilerType(); 716} 717 718CompilerType CompilerType::GetTypedefedType() const { 719 if (IsValid()) 720 if (auto type_system_sp = GetTypeSystem()) 721 return type_system_sp->GetTypedefedType(m_type); 722 return CompilerType(); 723} 724 725// Create related types using the current type's AST 726 727CompilerType 728CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const { 729 if (IsValid()) 730 if (auto type_system_sp = GetTypeSystem()) 731 return type_system_sp->GetBasicTypeFromAST(basic_type); 732 return CompilerType(); 733} 734// Exploring the type 735 736std::optional<uint64_t> 737CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const { 738 if (IsValid()) 739 if (auto type_system_sp = GetTypeSystem()) 740 return type_system_sp->GetBitSize(m_type, exe_scope); 741 return {}; 742} 743 744std::optional<uint64_t> 745CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const { 746 if (std::optional<uint64_t> bit_size = GetBitSize(exe_scope)) 747 return (*bit_size + 7) / 8; 748 return {}; 749} 750 751std::optional<size_t> 752CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const { 753 if (IsValid()) 754 if (auto type_system_sp = GetTypeSystem()) 755 return type_system_sp->GetTypeBitAlign(m_type, exe_scope); 756 return {}; 757} 758 759lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const { 760 if (IsValid()) 761 if (auto type_system_sp = GetTypeSystem()) 762 return type_system_sp->GetEncoding(m_type, count); 763 return lldb::eEncodingInvalid; 764} 765 766lldb::Format CompilerType::GetFormat() const { 767 if (IsValid()) 768 if (auto type_system_sp = GetTypeSystem()) 769 return type_system_sp->GetFormat(m_type); 770 return lldb::eFormatDefault; 771} 772 773uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes, 774 const ExecutionContext *exe_ctx) const { 775 if (IsValid()) 776 if (auto type_system_sp = GetTypeSystem()) 777 return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes, 778 exe_ctx); 779 return 0; 780} 781 782lldb::BasicType CompilerType::GetBasicTypeEnumeration() const { 783 if (IsValid()) 784 if (auto type_system_sp = GetTypeSystem()) 785 return type_system_sp->GetBasicTypeEnumeration(m_type); 786 return eBasicTypeInvalid; 787} 788 789void CompilerType::ForEachEnumerator( 790 std::function<bool(const CompilerType &integer_type, 791 ConstString name, 792 const llvm::APSInt &value)> const &callback) const { 793 if (IsValid()) 794 if (auto type_system_sp = GetTypeSystem()) 795 return type_system_sp->ForEachEnumerator(m_type, callback); 796} 797 798uint32_t CompilerType::GetNumFields() const { 799 if (IsValid()) 800 if (auto type_system_sp = GetTypeSystem()) 801 return type_system_sp->GetNumFields(m_type); 802 return 0; 803} 804 805CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name, 806 uint64_t *bit_offset_ptr, 807 uint32_t *bitfield_bit_size_ptr, 808 bool *is_bitfield_ptr) const { 809 if (IsValid()) 810 if (auto type_system_sp = GetTypeSystem()) 811 return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr, 812 bitfield_bit_size_ptr, is_bitfield_ptr); 813 return CompilerType(); 814} 815 816uint32_t CompilerType::GetNumDirectBaseClasses() const { 817 if (IsValid()) 818 if (auto type_system_sp = GetTypeSystem()) 819 return type_system_sp->GetNumDirectBaseClasses(m_type); 820 return 0; 821} 822 823uint32_t CompilerType::GetNumVirtualBaseClasses() const { 824 if (IsValid()) 825 if (auto type_system_sp = GetTypeSystem()) 826 return type_system_sp->GetNumVirtualBaseClasses(m_type); 827 return 0; 828} 829 830CompilerType 831CompilerType::GetDirectBaseClassAtIndex(size_t idx, 832 uint32_t *bit_offset_ptr) const { 833 if (IsValid()) 834 if (auto type_system_sp = GetTypeSystem()) 835 return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx, 836 bit_offset_ptr); 837 return CompilerType(); 838} 839 840CompilerType 841CompilerType::GetVirtualBaseClassAtIndex(size_t idx, 842 uint32_t *bit_offset_ptr) const { 843 if (IsValid()) 844 if (auto type_system_sp = GetTypeSystem()) 845 return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx, 846 bit_offset_ptr); 847 return CompilerType(); 848} 849 850uint32_t CompilerType::GetIndexOfFieldWithName( 851 const char *name, CompilerType *field_compiler_type_ptr, 852 uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, 853 bool *is_bitfield_ptr) const { 854 unsigned count = GetNumFields(); 855 std::string field_name; 856 for (unsigned index = 0; index < count; index++) { 857 CompilerType field_compiler_type( 858 GetFieldAtIndex(index, field_name, bit_offset_ptr, 859 bitfield_bit_size_ptr, is_bitfield_ptr)); 860 if (strcmp(field_name.c_str(), name) == 0) { 861 if (field_compiler_type_ptr) 862 *field_compiler_type_ptr = field_compiler_type; 863 return index; 864 } 865 } 866 return UINT32_MAX; 867} 868 869CompilerType CompilerType::GetChildCompilerTypeAtIndex( 870 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, 871 bool omit_empty_base_classes, bool ignore_array_bounds, 872 std::string &child_name, uint32_t &child_byte_size, 873 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, 874 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, 875 bool &child_is_deref_of_parent, ValueObject *valobj, 876 uint64_t &language_flags) const { 877 if (IsValid()) 878 if (auto type_system_sp = GetTypeSystem()) 879 return type_system_sp->GetChildCompilerTypeAtIndex( 880 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes, 881 ignore_array_bounds, child_name, child_byte_size, child_byte_offset, 882 child_bitfield_bit_size, child_bitfield_bit_offset, 883 child_is_base_class, child_is_deref_of_parent, valobj, 884 language_flags); 885 return CompilerType(); 886} 887 888// Look for a child member (doesn't include base classes, but it does include 889// their members) in the type hierarchy. Returns an index path into 890// "clang_type" on how to reach the appropriate member. 891// 892// class A 893// { 894// public: 895// int m_a; 896// int m_b; 897// }; 898// 899// class B 900// { 901// }; 902// 903// class C : 904// public B, 905// public A 906// { 907// }; 908// 909// If we have a clang type that describes "class C", and we wanted to looked 910// "m_b" in it: 911// 912// With omit_empty_base_classes == false we would get an integer array back 913// with: { 1, 1 } The first index 1 is the child index for "class A" within 914// class C The second index 1 is the child index for "m_b" within class A 915// 916// With omit_empty_base_classes == true we would get an integer array back 917// with: { 0, 1 } The first index 0 is the child index for "class A" within 918// class C (since class B doesn't have any members it doesn't count) The second 919// index 1 is the child index for "m_b" within class A 920 921size_t CompilerType::GetIndexOfChildMemberWithName( 922 llvm::StringRef name, bool omit_empty_base_classes, 923 std::vector<uint32_t> &child_indexes) const { 924 if (IsValid() && !name.empty()) { 925 if (auto type_system_sp = GetTypeSystem()) 926 return type_system_sp->GetIndexOfChildMemberWithName( 927 m_type, name, omit_empty_base_classes, child_indexes); 928 } 929 return 0; 930} 931 932size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const { 933 if (IsValid()) { 934 if (auto type_system_sp = GetTypeSystem()) 935 return type_system_sp->GetNumTemplateArguments(m_type, expand_pack); 936 } 937 return 0; 938} 939 940TemplateArgumentKind 941CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const { 942 if (IsValid()) 943 if (auto type_system_sp = GetTypeSystem()) 944 return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack); 945 return eTemplateArgumentKindNull; 946} 947 948CompilerType CompilerType::GetTypeTemplateArgument(size_t idx, 949 bool expand_pack) const { 950 if (IsValid()) { 951 if (auto type_system_sp = GetTypeSystem()) 952 return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack); 953 } 954 return CompilerType(); 955} 956 957std::optional<CompilerType::IntegralTemplateArgument> 958CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const { 959 if (IsValid()) 960 if (auto type_system_sp = GetTypeSystem()) 961 return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack); 962 return std::nullopt; 963} 964 965CompilerType CompilerType::GetTypeForFormatters() const { 966 if (IsValid()) 967 if (auto type_system_sp = GetTypeSystem()) 968 return type_system_sp->GetTypeForFormatters(m_type); 969 return CompilerType(); 970} 971 972LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const { 973 if (IsValid()) 974 if (auto type_system_sp = GetTypeSystem()) 975 return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj); 976 return eLazyBoolCalculate; 977} 978 979bool CompilerType::IsMeaninglessWithoutDynamicResolution() const { 980 if (IsValid()) 981 if (auto type_system_sp = GetTypeSystem()) 982 return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type); 983 return false; 984} 985 986// Get the index of the child of "clang_type" whose name matches. This function 987// doesn't descend into the children, but only looks one level deep and name 988// matches can include base class names. 989 990uint32_t 991CompilerType::GetIndexOfChildWithName(llvm::StringRef name, 992 bool omit_empty_base_classes) const { 993 if (IsValid() && !name.empty()) { 994 if (auto type_system_sp = GetTypeSystem()) 995 return type_system_sp->GetIndexOfChildWithName(m_type, name, 996 omit_empty_base_classes); 997 } 998 return UINT32_MAX; 999} 1000 1001// Dumping types 1002 1003bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format, 1004 const DataExtractor &data, 1005 lldb::offset_t byte_offset, size_t byte_size, 1006 uint32_t bitfield_bit_size, 1007 uint32_t bitfield_bit_offset, 1008 ExecutionContextScope *exe_scope) { 1009 if (IsValid()) 1010 if (auto type_system_sp = GetTypeSystem()) 1011 return type_system_sp->DumpTypeValue( 1012 m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size, 1013 bitfield_bit_offset, exe_scope); 1014 return false; 1015} 1016 1017void CompilerType::DumpTypeDescription(lldb::DescriptionLevel level) const { 1018 if (IsValid()) 1019 if (auto type_system_sp = GetTypeSystem()) 1020 type_system_sp->DumpTypeDescription(m_type, level); 1021} 1022 1023void CompilerType::DumpTypeDescription(Stream *s, 1024 lldb::DescriptionLevel level) const { 1025 if (IsValid()) 1026 if (auto type_system_sp = GetTypeSystem()) 1027 type_system_sp->DumpTypeDescription(m_type, *s, level); 1028} 1029 1030#ifndef NDEBUG 1031LLVM_DUMP_METHOD void CompilerType::dump() const { 1032 if (IsValid()) 1033 if (auto type_system_sp = GetTypeSystem()) 1034 return type_system_sp->dump(m_type); 1035 llvm::errs() << "<invalid>\n"; 1036} 1037#endif 1038 1039bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, 1040 lldb::offset_t data_byte_offset, 1041 size_t data_byte_size, Scalar &value, 1042 ExecutionContextScope *exe_scope) const { 1043 if (!IsValid()) 1044 return false; 1045 1046 if (IsAggregateType()) { 1047 return false; // Aggregate types don't have scalar values 1048 } else { 1049 uint64_t count = 0; 1050 lldb::Encoding encoding = GetEncoding(count); 1051 1052 if (encoding == lldb::eEncodingInvalid || count != 1) 1053 return false; 1054 1055 std::optional<uint64_t> byte_size = GetByteSize(exe_scope); 1056 if (!byte_size) 1057 return false; 1058 lldb::offset_t offset = data_byte_offset; 1059 switch (encoding) { 1060 case lldb::eEncodingInvalid: 1061 break; 1062 case lldb::eEncodingVector: 1063 break; 1064 case lldb::eEncodingUint: 1065 if (*byte_size <= sizeof(unsigned long long)) { 1066 uint64_t uval64 = data.GetMaxU64(&offset, *byte_size); 1067 if (*byte_size <= sizeof(unsigned int)) { 1068 value = (unsigned int)uval64; 1069 return true; 1070 } else if (*byte_size <= sizeof(unsigned long)) { 1071 value = (unsigned long)uval64; 1072 return true; 1073 } else if (*byte_size <= sizeof(unsigned long long)) { 1074 value = (unsigned long long)uval64; 1075 return true; 1076 } else 1077 value.Clear(); 1078 } 1079 break; 1080 1081 case lldb::eEncodingSint: 1082 if (*byte_size <= sizeof(long long)) { 1083 int64_t sval64 = data.GetMaxS64(&offset, *byte_size); 1084 if (*byte_size <= sizeof(int)) { 1085 value = (int)sval64; 1086 return true; 1087 } else if (*byte_size <= sizeof(long)) { 1088 value = (long)sval64; 1089 return true; 1090 } else if (*byte_size <= sizeof(long long)) { 1091 value = (long long)sval64; 1092 return true; 1093 } else 1094 value.Clear(); 1095 } 1096 break; 1097 1098 case lldb::eEncodingIEEE754: 1099 if (*byte_size <= sizeof(long double)) { 1100 uint32_t u32; 1101 uint64_t u64; 1102 if (*byte_size == sizeof(float)) { 1103 if (sizeof(float) == sizeof(uint32_t)) { 1104 u32 = data.GetU32(&offset); 1105 value = *((float *)&u32); 1106 return true; 1107 } else if (sizeof(float) == sizeof(uint64_t)) { 1108 u64 = data.GetU64(&offset); 1109 value = *((float *)&u64); 1110 return true; 1111 } 1112 } else if (*byte_size == sizeof(double)) { 1113 if (sizeof(double) == sizeof(uint32_t)) { 1114 u32 = data.GetU32(&offset); 1115 value = *((double *)&u32); 1116 return true; 1117 } else if (sizeof(double) == sizeof(uint64_t)) { 1118 u64 = data.GetU64(&offset); 1119 value = *((double *)&u64); 1120 return true; 1121 } 1122 } else if (*byte_size == sizeof(long double)) { 1123 if (sizeof(long double) == sizeof(uint32_t)) { 1124 u32 = data.GetU32(&offset); 1125 value = *((long double *)&u32); 1126 return true; 1127 } else if (sizeof(long double) == sizeof(uint64_t)) { 1128 u64 = data.GetU64(&offset); 1129 value = *((long double *)&u64); 1130 return true; 1131 } 1132 } 1133 } 1134 break; 1135 } 1136 } 1137 return false; 1138} 1139 1140CompilerType::CompilerType(CompilerType::TypeSystemSPWrapper type_system, 1141 lldb::opaque_compiler_type_t type) 1142 : m_type_system(type_system.GetSharedPointer()), m_type(type) { 1143 assert(Verify() && "verification failed"); 1144} 1145 1146CompilerType::CompilerType(lldb::TypeSystemWP type_system, 1147 lldb::opaque_compiler_type_t type) 1148 : m_type_system(type_system), m_type(type) { 1149 assert(Verify() && "verification failed"); 1150} 1151 1152#ifndef NDEBUG 1153bool CompilerType::Verify() const { 1154 if (!IsValid()) 1155 return true; 1156 if (auto type_system_sp = GetTypeSystem()) 1157 return type_system_sp->Verify(m_type); 1158 return true; 1159} 1160#endif 1161 1162CompilerType::TypeSystemSPWrapper CompilerType::GetTypeSystem() const { 1163 return {m_type_system.lock()}; 1164} 1165 1166bool CompilerType::TypeSystemSPWrapper::operator==( 1167 const CompilerType::TypeSystemSPWrapper &other) const { 1168 if (!m_typesystem_sp && !other.m_typesystem_sp) 1169 return true; 1170 if (m_typesystem_sp && other.m_typesystem_sp) 1171 return m_typesystem_sp.get() == other.m_typesystem_sp.get(); 1172 return false; 1173} 1174 1175TypeSystem *CompilerType::TypeSystemSPWrapper::operator->() const { 1176 assert(m_typesystem_sp); 1177 return m_typesystem_sp.get(); 1178} 1179 1180bool lldb_private::operator==(const lldb_private::CompilerType &lhs, 1181 const lldb_private::CompilerType &rhs) { 1182 return lhs.GetTypeSystem() == rhs.GetTypeSystem() && 1183 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType(); 1184} 1185 1186bool lldb_private::operator!=(const lldb_private::CompilerType &lhs, 1187 const lldb_private::CompilerType &rhs) { 1188 return !(lhs == rhs); 1189} 1190