1 //===-- CompilerType.cpp ----------------------------------------*- C++ -*-===// 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/Core/StreamFile.h" 13 #include "lldb/Symbol/Type.h" 14 #include "lldb/Target/ExecutionContext.h" 15 #include "lldb/Target/Process.h" 16 #include "lldb/Utility/ConstString.h" 17 #include "lldb/Utility/DataBufferHeap.h" 18 #include "lldb/Utility/DataExtractor.h" 19 #include "lldb/Utility/Scalar.h" 20 #include "lldb/Utility/Stream.h" 21 #include "lldb/Utility/StreamString.h" 22 23 #include <iterator> 24 #include <mutex> 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 CompilerType::CompilerType(TypeSystem *type_system, 30 lldb::opaque_compiler_type_t type) 31 : m_type(type), m_type_system(type_system) {} 32 33 CompilerType::~CompilerType() {} 34 35 // Tests 36 37 bool CompilerType::IsAggregateType() const { 38 if (IsValid()) 39 return m_type_system->IsAggregateType(m_type); 40 return false; 41 } 42 43 bool CompilerType::IsAnonymousType() const { 44 if (IsValid()) 45 return m_type_system->IsAnonymousType(m_type); 46 return false; 47 } 48 49 bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size, 50 bool *is_incomplete) const { 51 if (IsValid()) 52 return m_type_system->IsArrayType(m_type, element_type_ptr, size, 53 is_incomplete); 54 55 if (element_type_ptr) 56 element_type_ptr->Clear(); 57 if (size) 58 *size = 0; 59 if (is_incomplete) 60 *is_incomplete = false; 61 return false; 62 } 63 64 bool CompilerType::IsVectorType(CompilerType *element_type, 65 uint64_t *size) const { 66 if (IsValid()) 67 return m_type_system->IsVectorType(m_type, element_type, size); 68 return false; 69 } 70 71 bool CompilerType::IsRuntimeGeneratedType() const { 72 if (IsValid()) 73 return m_type_system->IsRuntimeGeneratedType(m_type); 74 return false; 75 } 76 77 bool CompilerType::IsCharType() const { 78 if (IsValid()) 79 return m_type_system->IsCharType(m_type); 80 return false; 81 } 82 83 bool CompilerType::IsCompleteType() const { 84 if (IsValid()) 85 return m_type_system->IsCompleteType(m_type); 86 return false; 87 } 88 89 bool CompilerType::IsConst() const { 90 if (IsValid()) 91 return m_type_system->IsConst(m_type); 92 return false; 93 } 94 95 bool CompilerType::IsCStringType(uint32_t &length) const { 96 if (IsValid()) 97 return m_type_system->IsCStringType(m_type, length); 98 return false; 99 } 100 101 bool CompilerType::IsFunctionType(bool *is_variadic_ptr) const { 102 if (IsValid()) 103 return m_type_system->IsFunctionType(m_type, is_variadic_ptr); 104 return false; 105 } 106 107 // Used to detect "Homogeneous Floating-point Aggregates" 108 uint32_t 109 CompilerType::IsHomogeneousAggregate(CompilerType *base_type_ptr) const { 110 if (IsValid()) 111 return m_type_system->IsHomogeneousAggregate(m_type, base_type_ptr); 112 return 0; 113 } 114 115 size_t CompilerType::GetNumberOfFunctionArguments() const { 116 if (IsValid()) 117 return m_type_system->GetNumberOfFunctionArguments(m_type); 118 return 0; 119 } 120 121 CompilerType 122 CompilerType::GetFunctionArgumentAtIndex(const size_t index) const { 123 if (IsValid()) 124 return m_type_system->GetFunctionArgumentAtIndex(m_type, index); 125 return CompilerType(); 126 } 127 128 bool CompilerType::IsFunctionPointerType() const { 129 if (IsValid()) 130 return m_type_system->IsFunctionPointerType(m_type); 131 return false; 132 } 133 134 bool CompilerType::IsBlockPointerType( 135 CompilerType *function_pointer_type_ptr) const { 136 if (IsValid()) 137 return m_type_system->IsBlockPointerType(m_type, function_pointer_type_ptr); 138 return false; 139 } 140 141 bool CompilerType::IsIntegerType(bool &is_signed) const { 142 if (IsValid()) 143 return m_type_system->IsIntegerType(m_type, is_signed); 144 return false; 145 } 146 147 bool CompilerType::IsEnumerationType(bool &is_signed) const { 148 if (IsValid()) 149 return m_type_system->IsEnumerationType(m_type, is_signed); 150 return false; 151 } 152 153 bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const { 154 return IsIntegerType(is_signed) || IsEnumerationType(is_signed); 155 } 156 157 bool CompilerType::IsPointerType(CompilerType *pointee_type) const { 158 if (IsValid()) { 159 return m_type_system->IsPointerType(m_type, pointee_type); 160 } 161 if (pointee_type) 162 pointee_type->Clear(); 163 return false; 164 } 165 166 bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const { 167 if (IsValid()) { 168 return m_type_system->IsPointerOrReferenceType(m_type, pointee_type); 169 } 170 if (pointee_type) 171 pointee_type->Clear(); 172 return false; 173 } 174 175 bool CompilerType::IsReferenceType(CompilerType *pointee_type, 176 bool *is_rvalue) const { 177 if (IsValid()) { 178 return m_type_system->IsReferenceType(m_type, pointee_type, is_rvalue); 179 } 180 if (pointee_type) 181 pointee_type->Clear(); 182 return false; 183 } 184 185 bool CompilerType::ShouldTreatScalarValueAsAddress() const { 186 if (IsValid()) 187 return m_type_system->ShouldTreatScalarValueAsAddress(m_type); 188 return false; 189 } 190 191 bool CompilerType::IsFloatingPointType(uint32_t &count, 192 bool &is_complex) const { 193 if (IsValid()) { 194 return m_type_system->IsFloatingPointType(m_type, count, is_complex); 195 } 196 count = 0; 197 is_complex = false; 198 return false; 199 } 200 201 bool CompilerType::IsDefined() const { 202 if (IsValid()) 203 return m_type_system->IsDefined(m_type); 204 return true; 205 } 206 207 bool CompilerType::IsPolymorphicClass() const { 208 if (IsValid()) { 209 return m_type_system->IsPolymorphicClass(m_type); 210 } 211 return false; 212 } 213 214 bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type, 215 bool check_cplusplus, 216 bool check_objc) const { 217 if (IsValid()) 218 return m_type_system->IsPossibleDynamicType(m_type, dynamic_pointee_type, 219 check_cplusplus, check_objc); 220 return false; 221 } 222 223 bool CompilerType::IsScalarType() const { 224 if (!IsValid()) 225 return false; 226 227 return m_type_system->IsScalarType(m_type); 228 } 229 230 bool CompilerType::IsTypedefType() const { 231 if (!IsValid()) 232 return false; 233 return m_type_system->IsTypedefType(m_type); 234 } 235 236 bool CompilerType::IsVoidType() const { 237 if (!IsValid()) 238 return false; 239 return m_type_system->IsVoidType(m_type); 240 } 241 242 bool CompilerType::IsPointerToScalarType() const { 243 if (!IsValid()) 244 return false; 245 246 return IsPointerType() && GetPointeeType().IsScalarType(); 247 } 248 249 bool CompilerType::IsArrayOfScalarType() const { 250 CompilerType element_type; 251 if (IsArrayType(&element_type, nullptr, nullptr)) 252 return element_type.IsScalarType(); 253 return false; 254 } 255 256 bool CompilerType::IsBeingDefined() const { 257 if (!IsValid()) 258 return false; 259 return m_type_system->IsBeingDefined(m_type); 260 } 261 262 // Type Completion 263 264 bool CompilerType::GetCompleteType() const { 265 if (!IsValid()) 266 return false; 267 return m_type_system->GetCompleteType(m_type); 268 } 269 270 // AST related queries 271 size_t CompilerType::GetPointerByteSize() const { 272 if (m_type_system) 273 return m_type_system->GetPointerByteSize(); 274 return 0; 275 } 276 277 ConstString CompilerType::GetConstQualifiedTypeName() const { 278 return GetConstTypeName(); 279 } 280 281 ConstString CompilerType::GetConstTypeName() const { 282 if (IsValid()) { 283 ConstString type_name(GetTypeName()); 284 if (type_name) 285 return type_name; 286 } 287 return ConstString("<invalid>"); 288 } 289 290 ConstString CompilerType::GetTypeName() const { 291 if (IsValid()) { 292 return m_type_system->GetTypeName(m_type); 293 } 294 return ConstString("<invalid>"); 295 } 296 297 ConstString CompilerType::GetDisplayTypeName() const { return GetTypeName(); } 298 299 uint32_t CompilerType::GetTypeInfo( 300 CompilerType *pointee_or_element_compiler_type) const { 301 if (!IsValid()) 302 return 0; 303 304 return m_type_system->GetTypeInfo(m_type, pointee_or_element_compiler_type); 305 } 306 307 lldb::LanguageType CompilerType::GetMinimumLanguage() { 308 if (!IsValid()) 309 return lldb::eLanguageTypeC; 310 311 return m_type_system->GetMinimumLanguage(m_type); 312 } 313 314 lldb::TypeClass CompilerType::GetTypeClass() const { 315 if (!IsValid()) 316 return lldb::eTypeClassInvalid; 317 318 return m_type_system->GetTypeClass(m_type); 319 } 320 321 void CompilerType::SetCompilerType(TypeSystem *type_system, 322 lldb::opaque_compiler_type_t type) { 323 m_type_system = type_system; 324 m_type = type; 325 } 326 327 unsigned CompilerType::GetTypeQualifiers() const { 328 if (IsValid()) 329 return m_type_system->GetTypeQualifiers(m_type); 330 return 0; 331 } 332 333 // Creating related types 334 335 CompilerType CompilerType::GetArrayElementType(uint64_t *stride) const { 336 if (IsValid()) { 337 return m_type_system->GetArrayElementType(m_type, stride); 338 } 339 return CompilerType(); 340 } 341 342 CompilerType CompilerType::GetArrayType(uint64_t size) const { 343 if (IsValid()) { 344 return m_type_system->GetArrayType(m_type, size); 345 } 346 return CompilerType(); 347 } 348 349 CompilerType CompilerType::GetCanonicalType() const { 350 if (IsValid()) 351 return m_type_system->GetCanonicalType(m_type); 352 return CompilerType(); 353 } 354 355 CompilerType CompilerType::GetFullyUnqualifiedType() const { 356 if (IsValid()) 357 return m_type_system->GetFullyUnqualifiedType(m_type); 358 return CompilerType(); 359 } 360 361 int CompilerType::GetFunctionArgumentCount() const { 362 if (IsValid()) { 363 return m_type_system->GetFunctionArgumentCount(m_type); 364 } 365 return -1; 366 } 367 368 CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const { 369 if (IsValid()) { 370 return m_type_system->GetFunctionArgumentTypeAtIndex(m_type, idx); 371 } 372 return CompilerType(); 373 } 374 375 CompilerType CompilerType::GetFunctionReturnType() const { 376 if (IsValid()) { 377 return m_type_system->GetFunctionReturnType(m_type); 378 } 379 return CompilerType(); 380 } 381 382 size_t CompilerType::GetNumMemberFunctions() const { 383 if (IsValid()) { 384 return m_type_system->GetNumMemberFunctions(m_type); 385 } 386 return 0; 387 } 388 389 TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) { 390 if (IsValid()) { 391 return m_type_system->GetMemberFunctionAtIndex(m_type, idx); 392 } 393 return TypeMemberFunctionImpl(); 394 } 395 396 CompilerType CompilerType::GetNonReferenceType() const { 397 if (IsValid()) 398 return m_type_system->GetNonReferenceType(m_type); 399 return CompilerType(); 400 } 401 402 CompilerType CompilerType::GetPointeeType() const { 403 if (IsValid()) { 404 return m_type_system->GetPointeeType(m_type); 405 } 406 return CompilerType(); 407 } 408 409 CompilerType CompilerType::GetPointerType() const { 410 if (IsValid()) { 411 return m_type_system->GetPointerType(m_type); 412 } 413 return CompilerType(); 414 } 415 416 CompilerType CompilerType::GetLValueReferenceType() const { 417 if (IsValid()) 418 return m_type_system->GetLValueReferenceType(m_type); 419 else 420 return CompilerType(); 421 } 422 423 CompilerType CompilerType::GetRValueReferenceType() const { 424 if (IsValid()) 425 return m_type_system->GetRValueReferenceType(m_type); 426 else 427 return CompilerType(); 428 } 429 430 CompilerType CompilerType::GetAtomicType() const { 431 if (IsValid()) 432 return m_type_system->GetAtomicType(m_type); 433 return CompilerType(); 434 } 435 436 CompilerType CompilerType::AddConstModifier() const { 437 if (IsValid()) 438 return m_type_system->AddConstModifier(m_type); 439 else 440 return CompilerType(); 441 } 442 443 CompilerType CompilerType::AddVolatileModifier() const { 444 if (IsValid()) 445 return m_type_system->AddVolatileModifier(m_type); 446 else 447 return CompilerType(); 448 } 449 450 CompilerType CompilerType::AddRestrictModifier() const { 451 if (IsValid()) 452 return m_type_system->AddRestrictModifier(m_type); 453 else 454 return CompilerType(); 455 } 456 457 CompilerType 458 CompilerType::CreateTypedef(const char *name, 459 const CompilerDeclContext &decl_ctx) const { 460 if (IsValid()) 461 return m_type_system->CreateTypedef(m_type, name, decl_ctx); 462 else 463 return CompilerType(); 464 } 465 466 CompilerType CompilerType::GetTypedefedType() const { 467 if (IsValid()) 468 return m_type_system->GetTypedefedType(m_type); 469 else 470 return CompilerType(); 471 } 472 473 // Create related types using the current type's AST 474 475 CompilerType 476 CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const { 477 if (IsValid()) 478 return m_type_system->GetBasicTypeFromAST(basic_type); 479 return CompilerType(); 480 } 481 // Exploring the type 482 483 llvm::Optional<uint64_t> 484 CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const { 485 if (IsValid()) 486 return m_type_system->GetBitSize(m_type, exe_scope); 487 return {}; 488 } 489 490 llvm::Optional<uint64_t> 491 CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const { 492 if (llvm::Optional<uint64_t> bit_size = GetBitSize(exe_scope)) 493 return (*bit_size + 7) / 8; 494 return {}; 495 } 496 497 llvm::Optional<size_t> CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const { 498 if (IsValid()) 499 return m_type_system->GetTypeBitAlign(m_type, exe_scope); 500 return {}; 501 } 502 503 lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const { 504 if (!IsValid()) 505 return lldb::eEncodingInvalid; 506 507 return m_type_system->GetEncoding(m_type, count); 508 } 509 510 lldb::Format CompilerType::GetFormat() const { 511 if (!IsValid()) 512 return lldb::eFormatDefault; 513 514 return m_type_system->GetFormat(m_type); 515 } 516 517 uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes, 518 const ExecutionContext *exe_ctx) const { 519 if (!IsValid()) 520 return 0; 521 return m_type_system->GetNumChildren(m_type, omit_empty_base_classes, 522 exe_ctx); 523 } 524 525 lldb::BasicType CompilerType::GetBasicTypeEnumeration() const { 526 if (IsValid()) 527 return m_type_system->GetBasicTypeEnumeration(m_type); 528 return eBasicTypeInvalid; 529 } 530 531 void CompilerType::ForEachEnumerator( 532 std::function<bool(const CompilerType &integer_type, 533 ConstString name, 534 const llvm::APSInt &value)> const &callback) const { 535 if (IsValid()) 536 return m_type_system->ForEachEnumerator(m_type, callback); 537 } 538 539 uint32_t CompilerType::GetNumFields() const { 540 if (!IsValid()) 541 return 0; 542 return m_type_system->GetNumFields(m_type); 543 } 544 545 CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name, 546 uint64_t *bit_offset_ptr, 547 uint32_t *bitfield_bit_size_ptr, 548 bool *is_bitfield_ptr) const { 549 if (!IsValid()) 550 return CompilerType(); 551 return m_type_system->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr, 552 bitfield_bit_size_ptr, is_bitfield_ptr); 553 } 554 555 uint32_t CompilerType::GetNumDirectBaseClasses() const { 556 if (IsValid()) 557 return m_type_system->GetNumDirectBaseClasses(m_type); 558 return 0; 559 } 560 561 uint32_t CompilerType::GetNumVirtualBaseClasses() const { 562 if (IsValid()) 563 return m_type_system->GetNumVirtualBaseClasses(m_type); 564 return 0; 565 } 566 567 CompilerType 568 CompilerType::GetDirectBaseClassAtIndex(size_t idx, 569 uint32_t *bit_offset_ptr) const { 570 if (IsValid()) 571 return m_type_system->GetDirectBaseClassAtIndex(m_type, idx, 572 bit_offset_ptr); 573 return CompilerType(); 574 } 575 576 CompilerType 577 CompilerType::GetVirtualBaseClassAtIndex(size_t idx, 578 uint32_t *bit_offset_ptr) const { 579 if (IsValid()) 580 return m_type_system->GetVirtualBaseClassAtIndex(m_type, idx, 581 bit_offset_ptr); 582 return CompilerType(); 583 } 584 585 uint32_t CompilerType::GetIndexOfFieldWithName( 586 const char *name, CompilerType *field_compiler_type_ptr, 587 uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, 588 bool *is_bitfield_ptr) const { 589 unsigned count = GetNumFields(); 590 std::string field_name; 591 for (unsigned index = 0; index < count; index++) { 592 CompilerType field_compiler_type( 593 GetFieldAtIndex(index, field_name, bit_offset_ptr, 594 bitfield_bit_size_ptr, is_bitfield_ptr)); 595 if (strcmp(field_name.c_str(), name) == 0) { 596 if (field_compiler_type_ptr) 597 *field_compiler_type_ptr = field_compiler_type; 598 return index; 599 } 600 } 601 return UINT32_MAX; 602 } 603 604 CompilerType CompilerType::GetChildCompilerTypeAtIndex( 605 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, 606 bool omit_empty_base_classes, bool ignore_array_bounds, 607 std::string &child_name, uint32_t &child_byte_size, 608 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, 609 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, 610 bool &child_is_deref_of_parent, ValueObject *valobj, 611 uint64_t &language_flags) const { 612 if (!IsValid()) 613 return CompilerType(); 614 return m_type_system->GetChildCompilerTypeAtIndex( 615 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes, 616 ignore_array_bounds, child_name, child_byte_size, child_byte_offset, 617 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, 618 child_is_deref_of_parent, valobj, language_flags); 619 } 620 621 // Look for a child member (doesn't include base classes, but it does include 622 // their members) in the type hierarchy. Returns an index path into 623 // "clang_type" on how to reach the appropriate member. 624 // 625 // class A 626 // { 627 // public: 628 // int m_a; 629 // int m_b; 630 // }; 631 // 632 // class B 633 // { 634 // }; 635 // 636 // class C : 637 // public B, 638 // public A 639 // { 640 // }; 641 // 642 // If we have a clang type that describes "class C", and we wanted to looked 643 // "m_b" in it: 644 // 645 // With omit_empty_base_classes == false we would get an integer array back 646 // with: { 1, 1 } The first index 1 is the child index for "class A" within 647 // class C The second index 1 is the child index for "m_b" within class A 648 // 649 // With omit_empty_base_classes == true we would get an integer array back 650 // with: { 0, 1 } The first index 0 is the child index for "class A" within 651 // class C (since class B doesn't have any members it doesn't count) The second 652 // index 1 is the child index for "m_b" within class A 653 654 size_t CompilerType::GetIndexOfChildMemberWithName( 655 const char *name, bool omit_empty_base_classes, 656 std::vector<uint32_t> &child_indexes) const { 657 if (IsValid() && name && name[0]) { 658 return m_type_system->GetIndexOfChildMemberWithName( 659 m_type, name, omit_empty_base_classes, child_indexes); 660 } 661 return 0; 662 } 663 664 size_t CompilerType::GetNumTemplateArguments() const { 665 if (IsValid()) { 666 return m_type_system->GetNumTemplateArguments(m_type); 667 } 668 return 0; 669 } 670 671 TemplateArgumentKind CompilerType::GetTemplateArgumentKind(size_t idx) const { 672 if (IsValid()) 673 return m_type_system->GetTemplateArgumentKind(m_type, idx); 674 return eTemplateArgumentKindNull; 675 } 676 677 CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const { 678 if (IsValid()) { 679 return m_type_system->GetTypeTemplateArgument(m_type, idx); 680 } 681 return CompilerType(); 682 } 683 684 llvm::Optional<CompilerType::IntegralTemplateArgument> 685 CompilerType::GetIntegralTemplateArgument(size_t idx) const { 686 if (IsValid()) 687 return m_type_system->GetIntegralTemplateArgument(m_type, idx); 688 return llvm::None; 689 } 690 691 CompilerType CompilerType::GetTypeForFormatters() const { 692 if (IsValid()) 693 return m_type_system->GetTypeForFormatters(m_type); 694 return CompilerType(); 695 } 696 697 LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const { 698 if (IsValid()) 699 return m_type_system->ShouldPrintAsOneLiner(m_type, valobj); 700 return eLazyBoolCalculate; 701 } 702 703 bool CompilerType::IsMeaninglessWithoutDynamicResolution() const { 704 if (IsValid()) 705 return m_type_system->IsMeaninglessWithoutDynamicResolution(m_type); 706 return false; 707 } 708 709 // Get the index of the child of "clang_type" whose name matches. This function 710 // doesn't descend into the children, but only looks one level deep and name 711 // matches can include base class names. 712 713 uint32_t 714 CompilerType::GetIndexOfChildWithName(const char *name, 715 bool omit_empty_base_classes) const { 716 if (IsValid() && name && name[0]) { 717 return m_type_system->GetIndexOfChildWithName(m_type, name, 718 omit_empty_base_classes); 719 } 720 return UINT32_MAX; 721 } 722 723 // Dumping types 724 #define DEPTH_INCREMENT 2 725 726 void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s, 727 lldb::Format format, const DataExtractor &data, 728 lldb::offset_t data_byte_offset, 729 size_t data_byte_size, uint32_t bitfield_bit_size, 730 uint32_t bitfield_bit_offset, bool show_types, 731 bool show_summary, bool verbose, uint32_t depth) { 732 if (!IsValid()) 733 return; 734 m_type_system->DumpValue(m_type, exe_ctx, s, format, data, data_byte_offset, 735 data_byte_size, bitfield_bit_size, 736 bitfield_bit_offset, show_types, show_summary, 737 verbose, depth); 738 } 739 740 bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format, 741 const DataExtractor &data, 742 lldb::offset_t byte_offset, size_t byte_size, 743 uint32_t bitfield_bit_size, 744 uint32_t bitfield_bit_offset, 745 ExecutionContextScope *exe_scope) { 746 if (!IsValid()) 747 return false; 748 return m_type_system->DumpTypeValue(m_type, s, format, data, byte_offset, 749 byte_size, bitfield_bit_size, 750 bitfield_bit_offset, exe_scope); 751 } 752 753 void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s, 754 const DataExtractor &data, 755 lldb::offset_t data_byte_offset, 756 size_t data_byte_size) { 757 if (IsValid()) 758 m_type_system->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset, 759 data_byte_size); 760 } 761 762 void CompilerType::DumpTypeDescription() const { 763 if (IsValid()) 764 m_type_system->DumpTypeDescription(m_type); 765 } 766 767 void CompilerType::DumpTypeDescription(Stream *s) const { 768 if (IsValid()) { 769 m_type_system->DumpTypeDescription(m_type, s); 770 } 771 } 772 773 #ifndef NDEBUG 774 LLVM_DUMP_METHOD void CompilerType::dump() const { 775 if (IsValid()) 776 m_type_system->dump(m_type); 777 else 778 llvm::errs() << "<invalid>\n"; 779 } 780 #endif 781 782 bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, 783 lldb::offset_t data_byte_offset, 784 size_t data_byte_size, 785 Scalar &value) const { 786 if (!IsValid()) 787 return false; 788 789 if (IsAggregateType()) { 790 return false; // Aggregate types don't have scalar values 791 } else { 792 uint64_t count = 0; 793 lldb::Encoding encoding = GetEncoding(count); 794 795 if (encoding == lldb::eEncodingInvalid || count != 1) 796 return false; 797 798 llvm::Optional<uint64_t> byte_size = GetByteSize(nullptr); 799 if (!byte_size) 800 return false; 801 lldb::offset_t offset = data_byte_offset; 802 switch (encoding) { 803 case lldb::eEncodingInvalid: 804 break; 805 case lldb::eEncodingVector: 806 break; 807 case lldb::eEncodingUint: 808 if (*byte_size <= sizeof(unsigned long long)) { 809 uint64_t uval64 = data.GetMaxU64(&offset, *byte_size); 810 if (*byte_size <= sizeof(unsigned int)) { 811 value = (unsigned int)uval64; 812 return true; 813 } else if (*byte_size <= sizeof(unsigned long)) { 814 value = (unsigned long)uval64; 815 return true; 816 } else if (*byte_size <= sizeof(unsigned long long)) { 817 value = (unsigned long long)uval64; 818 return true; 819 } else 820 value.Clear(); 821 } 822 break; 823 824 case lldb::eEncodingSint: 825 if (*byte_size <= sizeof(long long)) { 826 int64_t sval64 = data.GetMaxS64(&offset, *byte_size); 827 if (*byte_size <= sizeof(int)) { 828 value = (int)sval64; 829 return true; 830 } else if (*byte_size <= sizeof(long)) { 831 value = (long)sval64; 832 return true; 833 } else if (*byte_size <= sizeof(long long)) { 834 value = (long long)sval64; 835 return true; 836 } else 837 value.Clear(); 838 } 839 break; 840 841 case lldb::eEncodingIEEE754: 842 if (*byte_size <= sizeof(long double)) { 843 uint32_t u32; 844 uint64_t u64; 845 if (*byte_size == sizeof(float)) { 846 if (sizeof(float) == sizeof(uint32_t)) { 847 u32 = data.GetU32(&offset); 848 value = *((float *)&u32); 849 return true; 850 } else if (sizeof(float) == sizeof(uint64_t)) { 851 u64 = data.GetU64(&offset); 852 value = *((float *)&u64); 853 return true; 854 } 855 } else if (*byte_size == sizeof(double)) { 856 if (sizeof(double) == sizeof(uint32_t)) { 857 u32 = data.GetU32(&offset); 858 value = *((double *)&u32); 859 return true; 860 } else if (sizeof(double) == sizeof(uint64_t)) { 861 u64 = data.GetU64(&offset); 862 value = *((double *)&u64); 863 return true; 864 } 865 } else if (*byte_size == sizeof(long double)) { 866 if (sizeof(long double) == sizeof(uint32_t)) { 867 u32 = data.GetU32(&offset); 868 value = *((long double *)&u32); 869 return true; 870 } else if (sizeof(long double) == sizeof(uint64_t)) { 871 u64 = data.GetU64(&offset); 872 value = *((long double *)&u64); 873 return true; 874 } 875 } 876 } 877 break; 878 } 879 } 880 return false; 881 } 882 883 bool lldb_private::operator==(const lldb_private::CompilerType &lhs, 884 const lldb_private::CompilerType &rhs) { 885 return lhs.GetTypeSystem() == rhs.GetTypeSystem() && 886 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType(); 887 } 888 889 bool lldb_private::operator!=(const lldb_private::CompilerType &lhs, 890 const lldb_private::CompilerType &rhs) { 891 return !(lhs == rhs); 892 } 893