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::AddConstModifier() const { 431 if (IsValid()) 432 return m_type_system->AddConstModifier(m_type); 433 else 434 return CompilerType(); 435 } 436 437 CompilerType CompilerType::AddVolatileModifier() const { 438 if (IsValid()) 439 return m_type_system->AddVolatileModifier(m_type); 440 else 441 return CompilerType(); 442 } 443 444 CompilerType CompilerType::AddRestrictModifier() const { 445 if (IsValid()) 446 return m_type_system->AddRestrictModifier(m_type); 447 else 448 return CompilerType(); 449 } 450 451 CompilerType 452 CompilerType::CreateTypedef(const char *name, 453 const CompilerDeclContext &decl_ctx) const { 454 if (IsValid()) 455 return m_type_system->CreateTypedef(m_type, name, decl_ctx); 456 else 457 return CompilerType(); 458 } 459 460 CompilerType CompilerType::GetTypedefedType() const { 461 if (IsValid()) 462 return m_type_system->GetTypedefedType(m_type); 463 else 464 return CompilerType(); 465 } 466 467 // Create related types using the current type's AST 468 469 CompilerType 470 CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const { 471 if (IsValid()) 472 return m_type_system->GetBasicTypeFromAST(basic_type); 473 return CompilerType(); 474 } 475 // Exploring the type 476 477 llvm::Optional<uint64_t> 478 CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const { 479 if (IsValid()) 480 return m_type_system->GetBitSize(m_type, exe_scope); 481 return {}; 482 } 483 484 llvm::Optional<uint64_t> 485 CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const { 486 if (llvm::Optional<uint64_t> bit_size = GetBitSize(exe_scope)) 487 return (*bit_size + 7) / 8; 488 return {}; 489 } 490 491 llvm::Optional<size_t> CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const { 492 if (IsValid()) 493 return m_type_system->GetTypeBitAlign(m_type, exe_scope); 494 return {}; 495 } 496 497 lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const { 498 if (!IsValid()) 499 return lldb::eEncodingInvalid; 500 501 return m_type_system->GetEncoding(m_type, count); 502 } 503 504 lldb::Format CompilerType::GetFormat() const { 505 if (!IsValid()) 506 return lldb::eFormatDefault; 507 508 return m_type_system->GetFormat(m_type); 509 } 510 511 uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes, 512 const ExecutionContext *exe_ctx) const { 513 if (!IsValid()) 514 return 0; 515 return m_type_system->GetNumChildren(m_type, omit_empty_base_classes, 516 exe_ctx); 517 } 518 519 lldb::BasicType CompilerType::GetBasicTypeEnumeration() const { 520 if (IsValid()) 521 return m_type_system->GetBasicTypeEnumeration(m_type); 522 return eBasicTypeInvalid; 523 } 524 525 void CompilerType::ForEachEnumerator( 526 std::function<bool(const CompilerType &integer_type, 527 ConstString name, 528 const llvm::APSInt &value)> const &callback) const { 529 if (IsValid()) 530 return m_type_system->ForEachEnumerator(m_type, callback); 531 } 532 533 uint32_t CompilerType::GetNumFields() const { 534 if (!IsValid()) 535 return 0; 536 return m_type_system->GetNumFields(m_type); 537 } 538 539 CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name, 540 uint64_t *bit_offset_ptr, 541 uint32_t *bitfield_bit_size_ptr, 542 bool *is_bitfield_ptr) const { 543 if (!IsValid()) 544 return CompilerType(); 545 return m_type_system->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr, 546 bitfield_bit_size_ptr, is_bitfield_ptr); 547 } 548 549 uint32_t CompilerType::GetNumDirectBaseClasses() const { 550 if (IsValid()) 551 return m_type_system->GetNumDirectBaseClasses(m_type); 552 return 0; 553 } 554 555 uint32_t CompilerType::GetNumVirtualBaseClasses() const { 556 if (IsValid()) 557 return m_type_system->GetNumVirtualBaseClasses(m_type); 558 return 0; 559 } 560 561 CompilerType 562 CompilerType::GetDirectBaseClassAtIndex(size_t idx, 563 uint32_t *bit_offset_ptr) const { 564 if (IsValid()) 565 return m_type_system->GetDirectBaseClassAtIndex(m_type, idx, 566 bit_offset_ptr); 567 return CompilerType(); 568 } 569 570 CompilerType 571 CompilerType::GetVirtualBaseClassAtIndex(size_t idx, 572 uint32_t *bit_offset_ptr) const { 573 if (IsValid()) 574 return m_type_system->GetVirtualBaseClassAtIndex(m_type, idx, 575 bit_offset_ptr); 576 return CompilerType(); 577 } 578 579 uint32_t CompilerType::GetIndexOfFieldWithName( 580 const char *name, CompilerType *field_compiler_type_ptr, 581 uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, 582 bool *is_bitfield_ptr) const { 583 unsigned count = GetNumFields(); 584 std::string field_name; 585 for (unsigned index = 0; index < count; index++) { 586 CompilerType field_compiler_type( 587 GetFieldAtIndex(index, field_name, bit_offset_ptr, 588 bitfield_bit_size_ptr, is_bitfield_ptr)); 589 if (strcmp(field_name.c_str(), name) == 0) { 590 if (field_compiler_type_ptr) 591 *field_compiler_type_ptr = field_compiler_type; 592 return index; 593 } 594 } 595 return UINT32_MAX; 596 } 597 598 CompilerType CompilerType::GetChildCompilerTypeAtIndex( 599 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, 600 bool omit_empty_base_classes, bool ignore_array_bounds, 601 std::string &child_name, uint32_t &child_byte_size, 602 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, 603 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, 604 bool &child_is_deref_of_parent, ValueObject *valobj, 605 uint64_t &language_flags) const { 606 if (!IsValid()) 607 return CompilerType(); 608 return m_type_system->GetChildCompilerTypeAtIndex( 609 m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes, 610 ignore_array_bounds, child_name, child_byte_size, child_byte_offset, 611 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, 612 child_is_deref_of_parent, valobj, language_flags); 613 } 614 615 // Look for a child member (doesn't include base classes, but it does include 616 // their members) in the type hierarchy. Returns an index path into 617 // "clang_type" on how to reach the appropriate member. 618 // 619 // class A 620 // { 621 // public: 622 // int m_a; 623 // int m_b; 624 // }; 625 // 626 // class B 627 // { 628 // }; 629 // 630 // class C : 631 // public B, 632 // public A 633 // { 634 // }; 635 // 636 // If we have a clang type that describes "class C", and we wanted to looked 637 // "m_b" in it: 638 // 639 // With omit_empty_base_classes == false we would get an integer array back 640 // with: { 1, 1 } The first index 1 is the child index for "class A" within 641 // class C The second index 1 is the child index for "m_b" within class A 642 // 643 // With omit_empty_base_classes == true we would get an integer array back 644 // with: { 0, 1 } The first index 0 is the child index for "class A" within 645 // class C (since class B doesn't have any members it doesn't count) The second 646 // index 1 is the child index for "m_b" within class A 647 648 size_t CompilerType::GetIndexOfChildMemberWithName( 649 const char *name, bool omit_empty_base_classes, 650 std::vector<uint32_t> &child_indexes) const { 651 if (IsValid() && name && name[0]) { 652 return m_type_system->GetIndexOfChildMemberWithName( 653 m_type, name, omit_empty_base_classes, child_indexes); 654 } 655 return 0; 656 } 657 658 size_t CompilerType::GetNumTemplateArguments() const { 659 if (IsValid()) { 660 return m_type_system->GetNumTemplateArguments(m_type); 661 } 662 return 0; 663 } 664 665 TemplateArgumentKind CompilerType::GetTemplateArgumentKind(size_t idx) const { 666 if (IsValid()) 667 return m_type_system->GetTemplateArgumentKind(m_type, idx); 668 return eTemplateArgumentKindNull; 669 } 670 671 CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const { 672 if (IsValid()) { 673 return m_type_system->GetTypeTemplateArgument(m_type, idx); 674 } 675 return CompilerType(); 676 } 677 678 llvm::Optional<CompilerType::IntegralTemplateArgument> 679 CompilerType::GetIntegralTemplateArgument(size_t idx) const { 680 if (IsValid()) 681 return m_type_system->GetIntegralTemplateArgument(m_type, idx); 682 return llvm::None; 683 } 684 685 CompilerType CompilerType::GetTypeForFormatters() const { 686 if (IsValid()) 687 return m_type_system->GetTypeForFormatters(m_type); 688 return CompilerType(); 689 } 690 691 LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const { 692 if (IsValid()) 693 return m_type_system->ShouldPrintAsOneLiner(m_type, valobj); 694 return eLazyBoolCalculate; 695 } 696 697 bool CompilerType::IsMeaninglessWithoutDynamicResolution() const { 698 if (IsValid()) 699 return m_type_system->IsMeaninglessWithoutDynamicResolution(m_type); 700 return false; 701 } 702 703 // Get the index of the child of "clang_type" whose name matches. This function 704 // doesn't descend into the children, but only looks one level deep and name 705 // matches can include base class names. 706 707 uint32_t 708 CompilerType::GetIndexOfChildWithName(const char *name, 709 bool omit_empty_base_classes) const { 710 if (IsValid() && name && name[0]) { 711 return m_type_system->GetIndexOfChildWithName(m_type, name, 712 omit_empty_base_classes); 713 } 714 return UINT32_MAX; 715 } 716 717 // Dumping types 718 #define DEPTH_INCREMENT 2 719 720 void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s, 721 lldb::Format format, const DataExtractor &data, 722 lldb::offset_t data_byte_offset, 723 size_t data_byte_size, uint32_t bitfield_bit_size, 724 uint32_t bitfield_bit_offset, bool show_types, 725 bool show_summary, bool verbose, uint32_t depth) { 726 if (!IsValid()) 727 return; 728 m_type_system->DumpValue(m_type, exe_ctx, s, format, data, data_byte_offset, 729 data_byte_size, bitfield_bit_size, 730 bitfield_bit_offset, show_types, show_summary, 731 verbose, depth); 732 } 733 734 bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format, 735 const DataExtractor &data, 736 lldb::offset_t byte_offset, size_t byte_size, 737 uint32_t bitfield_bit_size, 738 uint32_t bitfield_bit_offset, 739 ExecutionContextScope *exe_scope) { 740 if (!IsValid()) 741 return false; 742 return m_type_system->DumpTypeValue(m_type, s, format, data, byte_offset, 743 byte_size, bitfield_bit_size, 744 bitfield_bit_offset, exe_scope); 745 } 746 747 void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s, 748 const DataExtractor &data, 749 lldb::offset_t data_byte_offset, 750 size_t data_byte_size) { 751 if (IsValid()) 752 m_type_system->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset, 753 data_byte_size); 754 } 755 756 void CompilerType::DumpTypeDescription() const { 757 if (IsValid()) 758 m_type_system->DumpTypeDescription(m_type); 759 } 760 761 void CompilerType::DumpTypeDescription(Stream *s) const { 762 if (IsValid()) { 763 m_type_system->DumpTypeDescription(m_type, s); 764 } 765 } 766 767 #ifndef NDEBUG 768 LLVM_DUMP_METHOD void CompilerType::dump() const { 769 if (IsValid()) 770 m_type_system->dump(m_type); 771 else 772 llvm::errs() << "<invalid>\n"; 773 } 774 #endif 775 776 bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, 777 lldb::offset_t data_byte_offset, 778 size_t data_byte_size, 779 Scalar &value) const { 780 if (!IsValid()) 781 return false; 782 783 if (IsAggregateType()) { 784 return false; // Aggregate types don't have scalar values 785 } else { 786 uint64_t count = 0; 787 lldb::Encoding encoding = GetEncoding(count); 788 789 if (encoding == lldb::eEncodingInvalid || count != 1) 790 return false; 791 792 llvm::Optional<uint64_t> byte_size = GetByteSize(nullptr); 793 if (!byte_size) 794 return false; 795 lldb::offset_t offset = data_byte_offset; 796 switch (encoding) { 797 case lldb::eEncodingInvalid: 798 break; 799 case lldb::eEncodingVector: 800 break; 801 case lldb::eEncodingUint: 802 if (*byte_size <= sizeof(unsigned long long)) { 803 uint64_t uval64 = data.GetMaxU64(&offset, *byte_size); 804 if (*byte_size <= sizeof(unsigned int)) { 805 value = (unsigned int)uval64; 806 return true; 807 } else if (*byte_size <= sizeof(unsigned long)) { 808 value = (unsigned long)uval64; 809 return true; 810 } else if (*byte_size <= sizeof(unsigned long long)) { 811 value = (unsigned long long)uval64; 812 return true; 813 } else 814 value.Clear(); 815 } 816 break; 817 818 case lldb::eEncodingSint: 819 if (*byte_size <= sizeof(long long)) { 820 int64_t sval64 = data.GetMaxS64(&offset, *byte_size); 821 if (*byte_size <= sizeof(int)) { 822 value = (int)sval64; 823 return true; 824 } else if (*byte_size <= sizeof(long)) { 825 value = (long)sval64; 826 return true; 827 } else if (*byte_size <= sizeof(long long)) { 828 value = (long long)sval64; 829 return true; 830 } else 831 value.Clear(); 832 } 833 break; 834 835 case lldb::eEncodingIEEE754: 836 if (*byte_size <= sizeof(long double)) { 837 uint32_t u32; 838 uint64_t u64; 839 if (*byte_size == sizeof(float)) { 840 if (sizeof(float) == sizeof(uint32_t)) { 841 u32 = data.GetU32(&offset); 842 value = *((float *)&u32); 843 return true; 844 } else if (sizeof(float) == sizeof(uint64_t)) { 845 u64 = data.GetU64(&offset); 846 value = *((float *)&u64); 847 return true; 848 } 849 } else if (*byte_size == sizeof(double)) { 850 if (sizeof(double) == sizeof(uint32_t)) { 851 u32 = data.GetU32(&offset); 852 value = *((double *)&u32); 853 return true; 854 } else if (sizeof(double) == sizeof(uint64_t)) { 855 u64 = data.GetU64(&offset); 856 value = *((double *)&u64); 857 return true; 858 } 859 } else if (*byte_size == sizeof(long double)) { 860 if (sizeof(long double) == sizeof(uint32_t)) { 861 u32 = data.GetU32(&offset); 862 value = *((long double *)&u32); 863 return true; 864 } else if (sizeof(long double) == sizeof(uint64_t)) { 865 u64 = data.GetU64(&offset); 866 value = *((long double *)&u64); 867 return true; 868 } 869 } 870 } 871 break; 872 } 873 } 874 return false; 875 } 876 877 bool CompilerType::SetValueFromScalar(const Scalar &value, Stream &strm) { 878 if (!IsValid()) 879 return false; 880 881 // Aggregate types don't have scalar values 882 if (!IsAggregateType()) { 883 strm.GetFlags().Set(Stream::eBinary); 884 uint64_t count = 0; 885 lldb::Encoding encoding = GetEncoding(count); 886 887 if (encoding == lldb::eEncodingInvalid || count != 1) 888 return false; 889 890 llvm::Optional<uint64_t> bit_width = GetBitSize(nullptr); 891 if (!bit_width) 892 return false; 893 894 // This function doesn't currently handle non-byte aligned assignments 895 if ((*bit_width % 8) != 0) 896 return false; 897 898 const uint64_t byte_size = (*bit_width + 7) / 8; 899 switch (encoding) { 900 case lldb::eEncodingInvalid: 901 break; 902 case lldb::eEncodingVector: 903 break; 904 case lldb::eEncodingUint: 905 switch (byte_size) { 906 case 1: 907 strm.PutHex8(value.UInt()); 908 return true; 909 case 2: 910 strm.PutHex16(value.UInt()); 911 return true; 912 case 4: 913 strm.PutHex32(value.UInt()); 914 return true; 915 case 8: 916 strm.PutHex64(value.ULongLong()); 917 return true; 918 default: 919 break; 920 } 921 break; 922 923 case lldb::eEncodingSint: 924 switch (byte_size) { 925 case 1: 926 strm.PutHex8(value.SInt()); 927 return true; 928 case 2: 929 strm.PutHex16(value.SInt()); 930 return true; 931 case 4: 932 strm.PutHex32(value.SInt()); 933 return true; 934 case 8: 935 strm.PutHex64(value.SLongLong()); 936 return true; 937 default: 938 break; 939 } 940 break; 941 942 case lldb::eEncodingIEEE754: 943 if (byte_size <= sizeof(long double)) { 944 if (byte_size == sizeof(float)) { 945 strm.PutFloat(value.Float()); 946 return true; 947 } else if (byte_size == sizeof(double)) { 948 strm.PutDouble(value.Double()); 949 return true; 950 } else if (byte_size == sizeof(long double)) { 951 strm.PutDouble(value.LongDouble()); 952 return true; 953 } 954 } 955 break; 956 } 957 } 958 return false; 959 } 960 961 bool CompilerType::ReadFromMemory(lldb_private::ExecutionContext *exe_ctx, 962 lldb::addr_t addr, AddressType address_type, 963 lldb_private::DataExtractor &data) { 964 if (!IsValid()) 965 return false; 966 967 // Can't convert a file address to anything valid without more context (which 968 // Module it came from) 969 if (address_type == eAddressTypeFile) 970 return false; 971 972 if (!GetCompleteType()) 973 return false; 974 975 auto byte_size = 976 GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); 977 if (!byte_size) 978 return false; 979 980 if (data.GetByteSize() < *byte_size) { 981 lldb::DataBufferSP data_sp(new DataBufferHeap(*byte_size, '\0')); 982 data.SetData(data_sp); 983 } 984 985 uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, *byte_size)); 986 if (dst != nullptr) { 987 if (address_type == eAddressTypeHost) { 988 if (addr == 0) 989 return false; 990 // The address is an address in this process, so just copy it 991 memcpy(dst, reinterpret_cast<uint8_t *>(addr), *byte_size); 992 return true; 993 } else { 994 Process *process = nullptr; 995 if (exe_ctx) 996 process = exe_ctx->GetProcessPtr(); 997 if (process) { 998 Status error; 999 return process->ReadMemory(addr, dst, *byte_size, error) == *byte_size; 1000 } 1001 } 1002 } 1003 return false; 1004 } 1005 1006 bool CompilerType::WriteToMemory(lldb_private::ExecutionContext *exe_ctx, 1007 lldb::addr_t addr, AddressType address_type, 1008 StreamString &new_value) { 1009 if (!IsValid()) 1010 return false; 1011 1012 // Can't convert a file address to anything valid without more context (which 1013 // Module it came from) 1014 if (address_type == eAddressTypeFile) 1015 return false; 1016 1017 if (!GetCompleteType()) 1018 return false; 1019 1020 auto byte_size = 1021 GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); 1022 if (!byte_size) 1023 return false; 1024 1025 if (*byte_size > 0) { 1026 if (address_type == eAddressTypeHost) { 1027 // The address is an address in this process, so just copy it 1028 memcpy((void *)addr, new_value.GetData(), *byte_size); 1029 return true; 1030 } else { 1031 Process *process = nullptr; 1032 if (exe_ctx) 1033 process = exe_ctx->GetProcessPtr(); 1034 if (process) { 1035 Status error; 1036 return process->WriteMemory(addr, new_value.GetData(), *byte_size, 1037 error) == *byte_size; 1038 } 1039 } 1040 } 1041 return false; 1042 } 1043 1044 bool lldb_private::operator==(const lldb_private::CompilerType &lhs, 1045 const lldb_private::CompilerType &rhs) { 1046 return lhs.GetTypeSystem() == rhs.GetTypeSystem() && 1047 lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType(); 1048 } 1049 1050 bool lldb_private::operator!=(const lldb_private::CompilerType &lhs, 1051 const lldb_private::CompilerType &rhs) { 1052 return !(lhs == rhs); 1053 } 1054