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