brintos

brintos / llvm-project-archived public Read only

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