brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.8 KiB · 0c3246d Raw
1280 lines · cpp
1//===-- Type.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 <algorithm>10#include <cstdio>11#include <iterator>12#include <memory>13#include <optional>14 15#include "lldb/Core/Module.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/StreamString.h"22 23#include "lldb/Symbol/CompilerType.h"24#include "lldb/Symbol/ObjectFile.h"25#include "lldb/Symbol/SymbolContextScope.h"26#include "lldb/Symbol/SymbolFile.h"27#include "lldb/Symbol/SymbolVendor.h"28#include "lldb/Symbol/Type.h"29#include "lldb/Symbol/TypeList.h"30#include "lldb/Symbol/TypeSystem.h"31 32#include "lldb/Target/ExecutionContext.h"33#include "lldb/Target/Process.h"34#include "lldb/Target/Target.h"35#include "lldb/lldb-enumerations.h"36#include "lldb/lldb-private-enumerations.h"37 38#include "llvm/ADT/StringRef.h"39 40using namespace lldb;41using namespace lldb_private;42 43llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &os,44                                            const CompilerContext &rhs) {45  StreamString lldb_stream;46  rhs.Dump(lldb_stream);47  return os << lldb_stream.GetString();48}49 50static CompilerContextKind ConvertTypeClass(lldb::TypeClass type_class) {51  if (type_class == eTypeClassAny)52    return CompilerContextKind::AnyType;53  CompilerContextKind result = {};54  if (type_class & (lldb::eTypeClassClass | lldb::eTypeClassStruct))55    result |= CompilerContextKind::ClassOrStruct;56  if (type_class & lldb::eTypeClassUnion)57    result |= CompilerContextKind::Union;58  if (type_class & lldb::eTypeClassEnumeration)59    result |= CompilerContextKind::Enum;60  if (type_class & lldb::eTypeClassFunction)61    result |= CompilerContextKind::Function;62  if (type_class & lldb::eTypeClassTypedef)63    result |= CompilerContextKind::Typedef;64  return result;65}66 67TypeQuery::TypeQuery(llvm::StringRef name, TypeQueryOptions options)68    : m_options(options) {69  if (std::optional<Type::ParsedName> parsed_name =70          Type::GetTypeScopeAndBasename(name)) {71    llvm::ArrayRef scope = parsed_name->scope;72    if (!scope.empty()) {73      if (scope[0] == "::") {74        m_options |= e_exact_match;75        scope = scope.drop_front();76      }77      for (llvm::StringRef s : scope) {78        m_context.push_back(79            {CompilerContextKind::AnyDeclContext, ConstString(s)});80      }81    }82    m_context.push_back({ConvertTypeClass(parsed_name->type_class),83                         ConstString(parsed_name->basename)});84  } else {85    m_context.push_back({CompilerContextKind::AnyType, ConstString(name)});86  }87}88 89TypeQuery::TypeQuery(const CompilerDeclContext &decl_ctx,90                     ConstString type_basename, TypeQueryOptions options)91    : m_options(options) {92  // Always use an exact match if we are looking for a type in compiler context.93  m_options |= e_exact_match;94  m_context = decl_ctx.GetCompilerContext();95  m_context.push_back({CompilerContextKind::AnyType, type_basename});96}97 98TypeQuery::TypeQuery(99    const llvm::ArrayRef<lldb_private::CompilerContext> &context,100    TypeQueryOptions options)101    : m_context(context), m_options(options) {102  // Always use an exact match if we are looking for a type in compiler context.103  m_options |= e_exact_match;104}105 106TypeQuery::TypeQuery(const CompilerDecl &decl, TypeQueryOptions options)107    : m_options(options) {108  // Always for an exact match if we are looking for a type using a declaration.109  m_options |= e_exact_match;110  m_context = decl.GetCompilerContext();111}112 113ConstString TypeQuery::GetTypeBasename() const {114  if (m_context.empty())115    return ConstString();116  return m_context.back().name;117}118 119void TypeQuery::AddLanguage(LanguageType language) {120  if (!m_languages)121    m_languages = LanguageSet();122  m_languages->Insert(language);123}124 125void TypeQuery::SetLanguages(LanguageSet languages) {126  m_languages = std::move(languages);127}128 129bool TypeQuery::ContextMatches(130    llvm::ArrayRef<CompilerContext> context_chain) const {131  auto ctx = context_chain.rbegin(), ctx_end = context_chain.rend();132  for (auto pat = m_context.rbegin(), pat_end = m_context.rend();133       pat != pat_end;) {134 135    if (ctx == ctx_end)136      return false; // Pattern too long.137 138    if (ctx->kind == CompilerContextKind::Namespace && ctx->name.IsEmpty()) {139      // We're matching an anonymous namespace. These are optional, so we check140      // if the pattern expects an anonymous namespace.141      if (pat->name.IsEmpty() && (pat->kind & CompilerContextKind::Namespace) ==142                                     CompilerContextKind::Namespace) {143        // Match, advance both iterators.144        ++pat;145      }146      // Otherwise, only advance the context to skip over the anonymous147      // namespace, and try matching again.148      ++ctx;149      continue;150    }151 152    // See if there is a kind mismatch; they should have 1 bit in common.153    if ((ctx->kind & pat->kind) == CompilerContextKind())154      return false;155 156    if (ctx->name != pat->name)157      return false;158 159    ++ctx;160    ++pat;161  }162 163  // Skip over any remaining module and anonymous namespace entries if we were164  // asked to do that.165  auto should_skip = [this](const CompilerContext &ctx) {166    if (ctx.kind == CompilerContextKind::Module)167      return GetIgnoreModules();168    if (ctx.kind == CompilerContextKind::Namespace && ctx.name.IsEmpty())169      return !GetStrictNamespaces();170    return false;171  };172  ctx = std::find_if_not(ctx, ctx_end, should_skip);173 174  // At this point, we have exhausted the pattern and we have a partial match at175  // least. If that's all we're looking for, we're done.176  if (!GetExactMatch())177    return true;178 179  // We have an exact match if we've exhausted the target context as well.180  return ctx == ctx_end;181}182 183bool TypeQuery::LanguageMatches(lldb::LanguageType language) const {184  // If we have no language filterm language always matches.185  if (!m_languages.has_value())186    return true;187  return (*m_languages)[language];188}189 190bool TypeResults::AlreadySearched(lldb_private::SymbolFile *sym_file) {191  return !m_searched_symbol_files.insert(sym_file).second;192}193 194bool TypeResults::InsertUnique(const lldb::TypeSP &type_sp) {195  if (type_sp)196    return m_type_map.InsertUnique(type_sp);197  return false;198}199 200bool TypeResults::Done(const TypeQuery &query) const {201  if (query.GetFindOne())202    return !m_type_map.Empty();203  return false;204}205 206void CompilerContext::Dump(Stream &s) const {207  switch (kind) {208  default:209    s << "Invalid";210    break;211  case CompilerContextKind::TranslationUnit:212    s << "TranslationUnit";213    break;214  case CompilerContextKind::Module:215    s << "Module";216    break;217  case CompilerContextKind::Namespace:218    s << "Namespace";219    break;220  case CompilerContextKind::ClassOrStruct:221    s << "ClassOrStruct";222    break;223  case CompilerContextKind::Union:224    s << "Union";225    break;226  case CompilerContextKind::Function:227    s << "Function";228    break;229  case CompilerContextKind::Variable:230    s << "Variable";231    break;232  case CompilerContextKind::Enum:233    s << "Enumeration";234    break;235  case CompilerContextKind::Typedef:236    s << "Typedef";237    break;238  case CompilerContextKind::AnyType:239    s << "AnyType";240    break;241  }242  s << "(" << name << ")";243}244 245class TypeAppendVisitor {246public:247  TypeAppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}248 249  bool operator()(const lldb::TypeSP &type) {250    m_type_list.Append(std::make_shared<TypeImpl>(type));251    return true;252  }253 254private:255  TypeListImpl &m_type_list;256};257 258void TypeListImpl::Append(const lldb_private::TypeList &type_list) {259  TypeAppendVisitor cb(*this);260  type_list.ForEach(cb);261}262 263SymbolFileType::SymbolFileType(SymbolFile &symbol_file,264                               const lldb::TypeSP &type_sp)265    : UserID(type_sp ? type_sp->GetID() : LLDB_INVALID_UID),266      m_symbol_file(symbol_file), m_type_sp(type_sp) {}267 268Type *SymbolFileType::GetType() {269  if (!m_type_sp) {270    Type *resolved_type = m_symbol_file.ResolveTypeUID(GetID());271    if (resolved_type)272      m_type_sp = resolved_type->shared_from_this();273  }274  return m_type_sp.get();275}276 277Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name,278           std::optional<uint64_t> byte_size, SymbolContextScope *context,279           user_id_t encoding_uid, EncodingDataType encoding_uid_type,280           const Declaration &decl, const CompilerType &compiler_type,281           ResolveState compiler_type_resolve_state, uint32_t opaque_payload)282    : std::enable_shared_from_this<Type>(), UserID(uid), m_name(name),283      m_symbol_file(symbol_file), m_context(context),284      m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type),285      m_decl(decl), m_compiler_type(compiler_type),286      m_compiler_type_resolve_state(compiler_type ? compiler_type_resolve_state287                                                  : ResolveState::Unresolved),288      m_payload(opaque_payload) {289  if (byte_size) {290    m_byte_size = *byte_size;291    m_byte_size_has_value = true;292  } else {293    m_byte_size = 0;294    m_byte_size_has_value = false;295  }296}297 298Type::Type()299    : std::enable_shared_from_this<Type>(), UserID(0), m_name("<INVALID TYPE>"),300      m_payload(0) {301  m_byte_size = 0;302  m_byte_size_has_value = false;303}304 305void Type::GetDescription(Stream *s, lldb::DescriptionLevel level,306                          bool show_name, ExecutionContextScope *exe_scope) {307  *s << "id = " << (const UserID &)*this;308 309  // Call the name accessor to make sure we resolve the type name310  if (show_name) {311    ConstString type_name = GetName();312    if (type_name) {313      *s << ", name = \"" << type_name << '"';314      ConstString qualified_type_name(GetQualifiedName());315      if (qualified_type_name != type_name) {316        *s << ", qualified = \"" << qualified_type_name << '"';317      }318    }319  }320 321  // Call the get byte size accessor so we resolve our byte size322  if (GetByteSize(exe_scope))323    s->Printf(", byte-size = %" PRIu64, m_byte_size);324  bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose);325  m_decl.Dump(s, show_fullpaths);326 327  if (m_compiler_type.IsValid()) {328    *s << ", compiler_type = \"";329    GetForwardCompilerType().DumpTypeDescription(s);330    *s << '"';331  } else if (m_encoding_uid != LLDB_INVALID_UID) {332    s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);333    switch (m_encoding_uid_type) {334    case eEncodingInvalid:335      break;336    case eEncodingIsUID:337      s->PutCString(" (unresolved type)");338      break;339    case eEncodingIsConstUID:340      s->PutCString(" (unresolved const type)");341      break;342    case eEncodingIsRestrictUID:343      s->PutCString(" (unresolved restrict type)");344      break;345    case eEncodingIsVolatileUID:346      s->PutCString(" (unresolved volatile type)");347      break;348    case eEncodingIsAtomicUID:349      s->PutCString(" (unresolved atomic type)");350      break;351    case eEncodingIsTypedefUID:352      s->PutCString(" (unresolved typedef)");353      break;354    case eEncodingIsPointerUID:355      s->PutCString(" (unresolved pointer)");356      break;357    case eEncodingIsLValueReferenceUID:358      s->PutCString(" (unresolved L value reference)");359      break;360    case eEncodingIsRValueReferenceUID:361      s->PutCString(" (unresolved R value reference)");362      break;363    case eEncodingIsSyntheticUID:364      s->PutCString(" (synthetic type)");365      break;366    case eEncodingIsLLVMPtrAuthUID:367      s->PutCString(" (ptrauth type)");368      break;369    }370  }371}372 373void Type::Dump(Stream *s, bool show_context, lldb::DescriptionLevel level) {374  s->Printf("%p: ", static_cast<void *>(this));375  s->Indent();376  *s << "Type" << static_cast<const UserID &>(*this) << ' ';377  if (m_name)378    *s << ", name = \"" << m_name << "\"";379 380  if (m_byte_size_has_value)381    s->Printf(", size = %" PRIu64, m_byte_size);382 383  if (show_context && m_context != nullptr) {384    s->PutCString(", context = ( ");385    m_context->DumpSymbolContext(s);386    s->PutCString(" )");387  }388 389  bool show_fullpaths = false;390  m_decl.Dump(s, show_fullpaths);391 392  if (m_compiler_type.IsValid()) {393    *s << ", compiler_type = " << m_compiler_type.GetOpaqueQualType() << ' ';394    GetForwardCompilerType().DumpTypeDescription(s, level);395  } else if (m_encoding_uid != LLDB_INVALID_UID) {396    s->Format(", type_data = {0:x-16}", m_encoding_uid);397    switch (m_encoding_uid_type) {398    case eEncodingInvalid:399      break;400    case eEncodingIsUID:401      s->PutCString(" (unresolved type)");402      break;403    case eEncodingIsConstUID:404      s->PutCString(" (unresolved const type)");405      break;406    case eEncodingIsRestrictUID:407      s->PutCString(" (unresolved restrict type)");408      break;409    case eEncodingIsVolatileUID:410      s->PutCString(" (unresolved volatile type)");411      break;412    case eEncodingIsAtomicUID:413      s->PutCString(" (unresolved atomic type)");414      break;415    case eEncodingIsTypedefUID:416      s->PutCString(" (unresolved typedef)");417      break;418    case eEncodingIsPointerUID:419      s->PutCString(" (unresolved pointer)");420      break;421    case eEncodingIsLValueReferenceUID:422      s->PutCString(" (unresolved L value reference)");423      break;424    case eEncodingIsRValueReferenceUID:425      s->PutCString(" (unresolved R value reference)");426      break;427    case eEncodingIsSyntheticUID:428      s->PutCString(" (synthetic type)");429      break;430    case eEncodingIsLLVMPtrAuthUID:431      s->PutCString(" (ptrauth type)");432    }433  }434 435  //436  //  if (m_access)437  //      s->Printf(", access = %u", m_access);438  s->EOL();439}440 441ConstString Type::GetName() {442  if (!m_name)443    m_name = GetForwardCompilerType().GetTypeName();444  return m_name;445}446 447ConstString Type::GetBaseName() {448  return GetForwardCompilerType().GetTypeName(/*BaseOnly*/ true);449}450 451void Type::DumpTypeName(Stream *s) { GetName().Dump(s, "<invalid-type-name>"); }452 453Type *Type::GetEncodingType() {454  if (m_encoding_type == nullptr && m_encoding_uid != LLDB_INVALID_UID)455    m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);456  return m_encoding_type;457}458 459llvm::Expected<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {460  if (m_byte_size_has_value)461    return static_cast<uint64_t>(m_byte_size);462 463  switch (m_encoding_uid_type) {464  case eEncodingInvalid:465    return llvm::createStringError("could not get type size: invalid encoding");466 467  case eEncodingIsSyntheticUID:468    return llvm::createStringError(469        "could not get type size: synthetic encoding");470 471  case eEncodingIsUID:472  case eEncodingIsConstUID:473  case eEncodingIsRestrictUID:474  case eEncodingIsVolatileUID:475  case eEncodingIsAtomicUID:476  case eEncodingIsTypedefUID: {477    Type *encoding_type = GetEncodingType();478    if (encoding_type)479      if (std::optional<uint64_t> size =480              llvm::expectedToOptional(encoding_type->GetByteSize(exe_scope))) {481        m_byte_size = *size;482        m_byte_size_has_value = true;483        return static_cast<uint64_t>(m_byte_size);484      }485 486    auto size_or_err = GetLayoutCompilerType().GetByteSize(exe_scope);487    if (!size_or_err)488      return size_or_err.takeError();489    m_byte_size = *size_or_err;490    m_byte_size_has_value = true;491    return static_cast<uint64_t>(m_byte_size);492  } break;493 494    // If we are a pointer or reference, then this is just a pointer size;495    case eEncodingIsPointerUID:496    case eEncodingIsLValueReferenceUID:497    case eEncodingIsRValueReferenceUID:498    case eEncodingIsLLVMPtrAuthUID: {499      if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {500        m_byte_size = arch.GetAddressByteSize();501        m_byte_size_has_value = true;502        return static_cast<uint64_t>(m_byte_size);503      }504    } break;505  }506  return llvm::createStringError(507      "could not get type size: unexpected encoding");508}509 510llvm::Expected<uint32_t> Type::GetNumChildren(bool omit_empty_base_classes) {511  return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes, nullptr);512}513 514bool Type::IsAggregateType() {515  return GetForwardCompilerType().IsAggregateType();516}517 518bool Type::IsTemplateType() {519  return GetForwardCompilerType().IsTemplateType();520}521 522lldb::TypeSP Type::GetTypedefType() {523  lldb::TypeSP type_sp;524  if (IsTypedef()) {525    Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid);526    if (typedef_type)527      type_sp = typedef_type->shared_from_this();528  }529  return type_sp;530}531 532lldb::Format Type::GetFormat() { return GetForwardCompilerType().GetFormat(); }533 534lldb::Encoding Type::GetEncoding() {535  // Make sure we resolve our type if it already hasn't been.536  return GetForwardCompilerType().GetEncoding();537}538 539bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,540                          AddressType address_type, DataExtractor &data) {541  if (address_type == eAddressTypeFile) {542    // Can't convert a file address to anything valid without more context543    // (which Module it came from)544    return false;545  }546 547  const uint64_t byte_size =548      llvm::expectedToOptional(549          GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope()550                              : nullptr))551          .value_or(0);552  if (data.GetByteSize() < byte_size) {553    lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0'));554    data.SetData(data_sp);555  }556 557  uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));558  if (dst != nullptr) {559    if (address_type == eAddressTypeHost) {560      // The address is an address in this process, so just copy it561      if (addr == 0)562        return false;563      memcpy(dst, reinterpret_cast<uint8_t *>(addr), byte_size);564      return true;565    } else {566      if (exe_ctx) {567        Process *process = exe_ctx->GetProcessPtr();568        if (process) {569          Status error;570          return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size,571                                                      error) == byte_size;572        }573      }574    }575  }576  return false;577}578 579bool Type::WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t addr,580                         AddressType address_type, DataExtractor &data) {581  return false;582}583 584const Declaration &Type::GetDeclaration() const { return m_decl; }585 586bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {587  // TODO: This needs to consider the correct type system to use.588  Type *encoding_type = nullptr;589  if (!m_compiler_type.IsValid()) {590    encoding_type = GetEncodingType();591    if (encoding_type) {592      switch (m_encoding_uid_type) {593      case eEncodingIsUID: {594        CompilerType encoding_compiler_type =595            encoding_type->GetForwardCompilerType();596        if (encoding_compiler_type.IsValid()) {597          m_compiler_type = encoding_compiler_type;598          m_compiler_type_resolve_state =599              encoding_type->m_compiler_type_resolve_state;600        }601      } break;602 603      case eEncodingIsConstUID:604        m_compiler_type =605            encoding_type->GetForwardCompilerType().AddConstModifier();606        break;607 608      case eEncodingIsRestrictUID:609        m_compiler_type =610            encoding_type->GetForwardCompilerType().AddRestrictModifier();611        break;612 613      case eEncodingIsVolatileUID:614        m_compiler_type =615            encoding_type->GetForwardCompilerType().AddVolatileModifier();616        break;617 618      case eEncodingIsAtomicUID:619        m_compiler_type =620            encoding_type->GetForwardCompilerType().GetAtomicType();621        break;622 623      case eEncodingIsTypedefUID:624        m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef(625            m_name.AsCString("__lldb_invalid_typedef_name"),626            GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);627        m_name.Clear();628        break;629 630      case eEncodingIsPointerUID:631        m_compiler_type =632            encoding_type->GetForwardCompilerType().GetPointerType();633        break;634 635      case eEncodingIsLValueReferenceUID:636        m_compiler_type =637            encoding_type->GetForwardCompilerType().GetLValueReferenceType();638        break;639 640      case eEncodingIsRValueReferenceUID:641        m_compiler_type =642            encoding_type->GetForwardCompilerType().GetRValueReferenceType();643        break;644 645      case eEncodingIsLLVMPtrAuthUID:646        m_compiler_type =647            encoding_type->GetForwardCompilerType().AddPtrAuthModifier(648                m_payload);649        break;650 651      default:652        llvm_unreachable("Unhandled encoding_data_type.");653      }654    } else {655      // We have no encoding type, return void?656      auto type_system_or_err =657          m_symbol_file->GetTypeSystemForLanguage(eLanguageTypeC);658      if (auto err = type_system_or_err.takeError()) {659        LLDB_LOG_ERROR(660            GetLog(LLDBLog::Symbols), std::move(err),661            "Unable to construct void type from TypeSystemClang: {0}");662      } else {663        CompilerType void_compiler_type;664        auto ts = *type_system_or_err;665        if (ts)666          void_compiler_type = ts->GetBasicTypeFromAST(eBasicTypeVoid);667        switch (m_encoding_uid_type) {668        case eEncodingIsUID:669          m_compiler_type = void_compiler_type;670          break;671 672        case eEncodingIsConstUID:673          m_compiler_type = void_compiler_type.AddConstModifier();674          break;675 676        case eEncodingIsRestrictUID:677          m_compiler_type = void_compiler_type.AddRestrictModifier();678          break;679 680        case eEncodingIsVolatileUID:681          m_compiler_type = void_compiler_type.AddVolatileModifier();682          break;683 684        case eEncodingIsAtomicUID:685          m_compiler_type = void_compiler_type.GetAtomicType();686          break;687 688        case eEncodingIsTypedefUID:689          m_compiler_type = void_compiler_type.CreateTypedef(690              m_name.AsCString("__lldb_invalid_typedef_name"),691              GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload);692          break;693 694        case eEncodingIsPointerUID:695          m_compiler_type = void_compiler_type.GetPointerType();696          break;697 698        case eEncodingIsLValueReferenceUID:699          m_compiler_type = void_compiler_type.GetLValueReferenceType();700          break;701 702        case eEncodingIsRValueReferenceUID:703          m_compiler_type = void_compiler_type.GetRValueReferenceType();704          break;705 706        case eEncodingIsLLVMPtrAuthUID:707          llvm_unreachable("Cannot handle eEncodingIsLLVMPtrAuthUID without "708                           "valid encoding_type");709 710        default:711          llvm_unreachable("Unhandled encoding_data_type.");712        }713      }714    }715 716    // When we have a EncodingUID, our "m_flags.compiler_type_resolve_state" is717    // set to eResolveStateUnresolved so we need to update it to say that we718    // now have a forward declaration since that is what we created above.719    if (m_compiler_type.IsValid())720      m_compiler_type_resolve_state = ResolveState::Forward;721  }722 723  // Check if we have a forward reference to a class/struct/union/enum?724  if (compiler_type_resolve_state == ResolveState::Layout ||725      compiler_type_resolve_state == ResolveState::Full) {726    // Check if we have a forward reference to a class/struct/union/enum?727    if (m_compiler_type.IsValid() &&728        m_compiler_type_resolve_state < compiler_type_resolve_state) {729      m_compiler_type_resolve_state = ResolveState::Full;730      if (!m_compiler_type.IsDefined()) {731        // We have a forward declaration, we need to resolve it to a complete732        // definition.733        m_symbol_file->CompleteType(m_compiler_type);734      }735    }736  }737 738  // If we have an encoding type, then we need to make sure it is resolved739  // appropriately.740  if (m_encoding_uid != LLDB_INVALID_UID) {741    if (encoding_type == nullptr)742      encoding_type = GetEncodingType();743    if (encoding_type) {744      ResolveState encoding_compiler_type_resolve_state =745          compiler_type_resolve_state;746 747      if (compiler_type_resolve_state == ResolveState::Layout) {748        switch (m_encoding_uid_type) {749        case eEncodingIsPointerUID:750        case eEncodingIsLValueReferenceUID:751        case eEncodingIsRValueReferenceUID:752          encoding_compiler_type_resolve_state = ResolveState::Forward;753          break;754        default:755          break;756        }757      }758      encoding_type->ResolveCompilerType(encoding_compiler_type_resolve_state);759    }760  }761  return m_compiler_type.IsValid();762}763uint32_t Type::GetEncodingMask() {764  uint32_t encoding_mask = 1u << m_encoding_uid_type;765  Type *encoding_type = GetEncodingType();766  assert(encoding_type != this);767  if (encoding_type)768    encoding_mask |= encoding_type->GetEncodingMask();769  return encoding_mask;770}771 772CompilerType Type::GetFullCompilerType() {773  ResolveCompilerType(ResolveState::Full);774  return m_compiler_type;775}776 777CompilerType Type::GetLayoutCompilerType() {778  ResolveCompilerType(ResolveState::Layout);779  return m_compiler_type;780}781 782CompilerType Type::GetForwardCompilerType() {783  ResolveCompilerType(ResolveState::Forward);784  return m_compiler_type;785}786 787ConstString Type::GetQualifiedName() {788  return GetForwardCompilerType().GetTypeName();789}790 791std::optional<Type::ParsedName>792Type::GetTypeScopeAndBasename(llvm::StringRef name) {793  ParsedName result;794 795  if (name.empty())796    return std::nullopt;797 798  if (name.consume_front("struct "))799    result.type_class = eTypeClassStruct;800  else if (name.consume_front("class "))801    result.type_class = eTypeClassClass;802  else if (name.consume_front("union "))803    result.type_class = eTypeClassUnion;804  else if (name.consume_front("enum "))805    result.type_class = eTypeClassEnumeration;806  else if (name.consume_front("typedef "))807    result.type_class = eTypeClassTypedef;808 809  if (name.consume_front("::"))810    result.scope.push_back("::");811 812  bool prev_is_colon = false;813  size_t template_depth = 0;814  size_t name_begin = 0;815  for (const auto &pos : llvm::enumerate(name)) {816    switch (pos.value()) {817    case ':':818      if (prev_is_colon && template_depth == 0) {819        llvm::StringRef scope_name = name.slice(name_begin, pos.index() - 1);820        // The demanglers use these strings to represent anonymous821        // namespaces. Convert it to a more language-agnostic form (which is822        // also used in DWARF).823        if (scope_name == "(anonymous namespace)" ||824            scope_name == "`anonymous namespace'" ||825            scope_name == "`anonymous-namespace'")826          scope_name = "";827        result.scope.push_back(scope_name);828        name_begin = pos.index() + 1;829      }830      break;831    case '<':832      ++template_depth;833      break;834    case '>':835      if (template_depth == 0)836        return std::nullopt; // Invalid name.837      --template_depth;838      break;839    }840    prev_is_colon = pos.value() == ':';841  }842 843  if (name_begin < name.size() && template_depth == 0)844    result.basename = name.substr(name_begin);845  else846    return std::nullopt;847 848  return result;849}850 851ModuleSP Type::GetModule() {852  if (m_symbol_file)853    return m_symbol_file->GetObjectFile()->GetModule();854  return ModuleSP();855}856 857ModuleSP Type::GetExeModule() {858  if (m_compiler_type) {859    auto ts = m_compiler_type.GetTypeSystem();860    if (!ts)861      return {};862    SymbolFile *symbol_file = ts->GetSymbolFile();863    if (symbol_file)864      return symbol_file->GetObjectFile()->GetModule();865  }866  return {};867}868 869TypeAndOrName::TypeAndOrName(TypeSP &in_type_sp) {870  if (in_type_sp) {871    m_compiler_type = in_type_sp->GetForwardCompilerType();872    m_type_name = in_type_sp->GetName();873  }874}875 876TypeAndOrName::TypeAndOrName(const char *in_type_str)877    : m_type_name(in_type_str) {}878 879TypeAndOrName::TypeAndOrName(ConstString &in_type_const_string)880    : m_type_name(in_type_const_string) {}881 882bool TypeAndOrName::operator==(const TypeAndOrName &other) const {883  if (m_compiler_type != other.m_compiler_type)884    return false;885  if (m_type_name != other.m_type_name)886    return false;887  return true;888}889 890bool TypeAndOrName::operator!=(const TypeAndOrName &other) const {891  return !(*this == other);892}893 894ConstString TypeAndOrName::GetName() const {895  if (m_type_name)896    return m_type_name;897  if (m_compiler_type)898    return m_compiler_type.GetTypeName();899  return ConstString("<invalid>");900}901 902void TypeAndOrName::SetName(ConstString type_name) {903  m_type_name = type_name;904}905 906void TypeAndOrName::SetName(const char *type_name_cstr) {907  m_type_name.SetCString(type_name_cstr);908}909 910void TypeAndOrName::SetName(llvm::StringRef type_name) {911  m_type_name.SetString(type_name);912}913 914void TypeAndOrName::SetTypeSP(lldb::TypeSP type_sp) {915  if (type_sp) {916    m_compiler_type = type_sp->GetForwardCompilerType();917    m_type_name = type_sp->GetName();918  } else919    Clear();920}921 922void TypeAndOrName::SetCompilerType(CompilerType compiler_type) {923  m_compiler_type = compiler_type;924  if (m_compiler_type)925    m_type_name = m_compiler_type.GetTypeName();926}927 928bool TypeAndOrName::IsEmpty() const {929  return !((bool)m_type_name || (bool)m_compiler_type);930}931 932void TypeAndOrName::Clear() {933  m_type_name.Clear();934  m_compiler_type.Clear();935}936 937bool TypeAndOrName::HasName() const { return (bool)m_type_name; }938 939bool TypeAndOrName::HasCompilerType() const {940  return m_compiler_type.IsValid();941}942 943TypeImpl::TypeImpl(const lldb::TypeSP &type_sp)944    : m_module_wp(), m_static_type(), m_dynamic_type() {945  SetType(type_sp);946}947 948TypeImpl::TypeImpl(const CompilerType &compiler_type)949    : m_module_wp(), m_static_type(), m_dynamic_type() {950  SetType(compiler_type);951}952 953TypeImpl::TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic)954    : m_module_wp(), m_static_type(), m_dynamic_type(dynamic) {955  SetType(type_sp, dynamic);956}957 958TypeImpl::TypeImpl(const CompilerType &static_type,959                   const CompilerType &dynamic_type)960    : m_module_wp(), m_static_type(), m_dynamic_type() {961  SetType(static_type, dynamic_type);962}963 964void TypeImpl::SetType(const lldb::TypeSP &type_sp) {965  if (type_sp) {966    m_static_type = type_sp->GetForwardCompilerType();967    m_exe_module_wp = type_sp->GetExeModule();968    m_module_wp = type_sp->GetModule();969  } else {970    m_static_type.Clear();971    m_module_wp = lldb::ModuleWP();972  }973}974 975void TypeImpl::SetType(const CompilerType &compiler_type) {976  m_module_wp = lldb::ModuleWP();977  m_static_type = compiler_type;978}979 980void TypeImpl::SetType(const lldb::TypeSP &type_sp,981                       const CompilerType &dynamic) {982  SetType(type_sp);983  m_dynamic_type = dynamic;984}985 986void TypeImpl::SetType(const CompilerType &compiler_type,987                       const CompilerType &dynamic) {988  m_module_wp = lldb::ModuleWP();989  m_static_type = compiler_type;990  m_dynamic_type = dynamic;991}992 993bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const {994  return CheckModuleCommon(m_module_wp, module_sp);995}996 997bool TypeImpl::CheckExeModule(lldb::ModuleSP &module_sp) const {998  return CheckModuleCommon(m_exe_module_wp, module_sp);999}1000 1001bool TypeImpl::CheckModuleCommon(const lldb::ModuleWP &input_module_wp,1002                                 lldb::ModuleSP &module_sp) const {1003  // Check if we have a module for this type. If we do and the shared pointer1004  // is can be successfully initialized with m_module_wp, return true. Else1005  // return false if we didn't have a module, or if we had a module and it has1006  // been deleted. Any functions doing anything with a TypeSP in this TypeImpl1007  // class should call this function and only do anything with the ivars if1008  // this function returns true. If we have a module, the "module_sp" will be1009  // filled in with a strong reference to the module so that the module will at1010  // least stay around long enough for the type query to succeed.1011  module_sp = input_module_wp.lock();1012  if (!module_sp) {1013    lldb::ModuleWP empty_module_wp;1014    // If either call to "std::weak_ptr::owner_before(...) value returns true,1015    // this indicates that m_module_wp once contained (possibly still does) a1016    // reference to a valid shared pointer. This helps us know if we had a1017    // valid reference to a section which is now invalid because the module it1018    // was in was deleted1019    if (empty_module_wp.owner_before(input_module_wp) ||1020        input_module_wp.owner_before(empty_module_wp)) {1021      // input_module_wp had a valid reference to a module, but all strong1022      // references have been released and the module has been deleted1023      return false;1024    }1025  }1026  // We either successfully locked the module, or didn't have one to begin with1027  return true;1028}1029 1030bool TypeImpl::operator==(const TypeImpl &rhs) const {1031  return m_static_type == rhs.m_static_type &&1032         m_dynamic_type == rhs.m_dynamic_type;1033}1034 1035bool TypeImpl::operator!=(const TypeImpl &rhs) const {1036  return !(*this == rhs);1037}1038 1039bool TypeImpl::IsValid() const {1040  // just a name is not valid1041  ModuleSP module_sp;1042  if (CheckModule(module_sp))1043    return m_static_type.IsValid() || m_dynamic_type.IsValid();1044  return false;1045}1046 1047TypeImpl::operator bool() const { return IsValid(); }1048 1049void TypeImpl::Clear() {1050  m_module_wp = lldb::ModuleWP();1051  m_static_type.Clear();1052  m_dynamic_type.Clear();1053}1054 1055ModuleSP TypeImpl::GetModule() const {1056  lldb::ModuleSP module_sp;1057  if (CheckExeModule(module_sp))1058    return module_sp;1059  return nullptr;1060}1061 1062ConstString TypeImpl::GetName() const {1063  ModuleSP module_sp;1064  if (CheckModule(module_sp)) {1065    if (m_dynamic_type)1066      return m_dynamic_type.GetTypeName();1067    return m_static_type.GetTypeName();1068  }1069  return ConstString();1070}1071 1072ConstString TypeImpl::GetDisplayTypeName() const {1073  ModuleSP module_sp;1074  if (CheckModule(module_sp)) {1075    if (m_dynamic_type)1076      return m_dynamic_type.GetDisplayTypeName();1077    return m_static_type.GetDisplayTypeName();1078  }1079  return ConstString();1080}1081 1082TypeImpl TypeImpl::GetPointerType() const {1083  ModuleSP module_sp;1084  if (CheckModule(module_sp)) {1085    if (m_dynamic_type.IsValid()) {1086      return TypeImpl(m_static_type.GetPointerType(),1087                      m_dynamic_type.GetPointerType());1088    }1089    return TypeImpl(m_static_type.GetPointerType());1090  }1091  return TypeImpl();1092}1093 1094TypeImpl TypeImpl::GetPointeeType() const {1095  ModuleSP module_sp;1096  if (CheckModule(module_sp)) {1097    if (m_dynamic_type.IsValid()) {1098      return TypeImpl(m_static_type.GetPointeeType(),1099                      m_dynamic_type.GetPointeeType());1100    }1101    return TypeImpl(m_static_type.GetPointeeType());1102  }1103  return TypeImpl();1104}1105 1106TypeImpl TypeImpl::GetReferenceType() const {1107  ModuleSP module_sp;1108  if (CheckModule(module_sp)) {1109    if (m_dynamic_type.IsValid()) {1110      return TypeImpl(m_static_type.GetLValueReferenceType(),1111                      m_dynamic_type.GetLValueReferenceType());1112    }1113    return TypeImpl(m_static_type.GetLValueReferenceType());1114  }1115  return TypeImpl();1116}1117 1118TypeImpl TypeImpl::GetTypedefedType() const {1119  ModuleSP module_sp;1120  if (CheckModule(module_sp)) {1121    if (m_dynamic_type.IsValid()) {1122      return TypeImpl(m_static_type.GetTypedefedType(),1123                      m_dynamic_type.GetTypedefedType());1124    }1125    return TypeImpl(m_static_type.GetTypedefedType());1126  }1127  return TypeImpl();1128}1129 1130TypeImpl TypeImpl::GetDereferencedType() const {1131  ModuleSP module_sp;1132  if (CheckModule(module_sp)) {1133    if (m_dynamic_type.IsValid()) {1134      return TypeImpl(m_static_type.GetNonReferenceType(),1135                      m_dynamic_type.GetNonReferenceType());1136    }1137    return TypeImpl(m_static_type.GetNonReferenceType());1138  }1139  return TypeImpl();1140}1141 1142TypeImpl TypeImpl::GetUnqualifiedType() const {1143  ModuleSP module_sp;1144  if (CheckModule(module_sp)) {1145    if (m_dynamic_type.IsValid()) {1146      return TypeImpl(m_static_type.GetFullyUnqualifiedType(),1147                      m_dynamic_type.GetFullyUnqualifiedType());1148    }1149    return TypeImpl(m_static_type.GetFullyUnqualifiedType());1150  }1151  return TypeImpl();1152}1153 1154TypeImpl TypeImpl::GetCanonicalType() const {1155  ModuleSP module_sp;1156  if (CheckModule(module_sp)) {1157    if (m_dynamic_type.IsValid()) {1158      return TypeImpl(m_static_type.GetCanonicalType(),1159                      m_dynamic_type.GetCanonicalType());1160    }1161    return TypeImpl(m_static_type.GetCanonicalType());1162  }1163  return TypeImpl();1164}1165 1166CompilerType TypeImpl::GetCompilerType(bool prefer_dynamic) {1167  ModuleSP module_sp;1168  if (CheckModule(module_sp)) {1169    if (prefer_dynamic) {1170      if (m_dynamic_type.IsValid())1171        return m_dynamic_type;1172    }1173    return m_static_type;1174  }1175  return CompilerType();1176}1177 1178CompilerType::TypeSystemSPWrapper TypeImpl::GetTypeSystem(bool prefer_dynamic) {1179  ModuleSP module_sp;1180  if (CheckModule(module_sp)) {1181    if (prefer_dynamic) {1182      if (m_dynamic_type.IsValid())1183        return m_dynamic_type.GetTypeSystem();1184    }1185    return m_static_type.GetTypeSystem();1186  }1187  return {};1188}1189 1190bool TypeImpl::GetDescription(lldb_private::Stream &strm,1191                              lldb::DescriptionLevel description_level) {1192  ModuleSP module_sp;1193  if (CheckModule(module_sp)) {1194    if (m_dynamic_type.IsValid()) {1195      strm.Printf("Dynamic:\n");1196      m_dynamic_type.DumpTypeDescription(&strm);1197      strm.Printf("\nStatic:\n");1198    }1199    m_static_type.DumpTypeDescription(&strm);1200  } else {1201    strm.PutCString("Invalid TypeImpl module for type has been deleted\n");1202  }1203  return true;1204}1205 1206CompilerType TypeImpl::FindDirectNestedType(llvm::StringRef name) {1207  if (name.empty())1208    return CompilerType();1209  return GetCompilerType(/*prefer_dynamic=*/false)1210      .GetDirectNestedTypeWithName(name);1211}1212 1213bool TypeMemberFunctionImpl::IsValid() {1214  return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown;1215}1216 1217ConstString TypeMemberFunctionImpl::GetName() const { return m_name; }1218 1219ConstString TypeMemberFunctionImpl::GetMangledName() const {1220  return m_decl.GetMangledName();1221}1222 1223CompilerType TypeMemberFunctionImpl::GetType() const { return m_type; }1224 1225lldb::MemberFunctionKind TypeMemberFunctionImpl::GetKind() const {1226  return m_kind;1227}1228 1229bool TypeMemberFunctionImpl::GetDescription(Stream &stream) {1230  switch (m_kind) {1231  case lldb::eMemberFunctionKindUnknown:1232    return false;1233  case lldb::eMemberFunctionKindConstructor:1234    stream.Printf("constructor for %s",1235                  m_type.GetTypeName().AsCString("<unknown>"));1236    break;1237  case lldb::eMemberFunctionKindDestructor:1238    stream.Printf("destructor for %s",1239                  m_type.GetTypeName().AsCString("<unknown>"));1240    break;1241  case lldb::eMemberFunctionKindInstanceMethod:1242    stream.Printf("instance method %s of type %s", m_name.AsCString(),1243                  m_decl.GetDeclContext().GetName().AsCString());1244    break;1245  case lldb::eMemberFunctionKindStaticMethod:1246    stream.Printf("static method %s of type %s", m_name.AsCString(),1247                  m_decl.GetDeclContext().GetName().AsCString());1248    break;1249  }1250  return true;1251}1252 1253CompilerType TypeMemberFunctionImpl::GetReturnType() const {1254  if (m_type)1255    return m_type.GetFunctionReturnType();1256  return m_decl.GetFunctionReturnType();1257}1258 1259size_t TypeMemberFunctionImpl::GetNumArguments() const {1260  if (m_type)1261    return m_type.GetNumberOfFunctionArguments();1262  else1263    return m_decl.GetNumFunctionArguments();1264}1265 1266CompilerType TypeMemberFunctionImpl::GetArgumentAtIndex(size_t idx) const {1267  if (m_type)1268    return m_type.GetFunctionArgumentAtIndex(idx);1269  else1270    return m_decl.GetFunctionArgumentType(idx);1271}1272 1273TypeEnumMemberImpl::TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp,1274                                       ConstString name,1275                                       const llvm::APSInt &value)1276    : m_integer_type_sp(integer_type_sp), m_name(name), m_value(value),1277      m_valid((bool)name && (bool)integer_type_sp)1278 1279{}1280