brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.1 KiB · 8712142 Raw
364 lines · cpp
1//===-- TypeSystem.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/TypeSystem.h"10#include "lldb/Core/PluginManager.h"11#include "lldb/Expression/UtilityFunction.h"12#include "lldb/Symbol/CompilerType.h"13#include "lldb/Target/Language.h"14 15#include "llvm/ADT/DenseSet.h"16#include <optional>17 18using namespace lldb_private;19using namespace lldb;20 21/// A 64-bit SmallBitVector is only small up to 64-7 bits, and the22/// setBitsInMask interface wants to write full bytes.23static const size_t g_num_small_bitvector_bits = 64 - 8;24static_assert(eNumLanguageTypes < g_num_small_bitvector_bits,25              "Languages bit vector is no longer small on 64 bit systems");26LanguageSet::LanguageSet() : bitvector(eNumLanguageTypes, false) {}27 28std::optional<LanguageType> LanguageSet::GetSingularLanguage() {29  if (bitvector.count() == 1)30    return (LanguageType)bitvector.find_first();31  return {};32}33 34void LanguageSet::Insert(LanguageType language) { bitvector.set(language); }35size_t LanguageSet::Size() const { return bitvector.count(); }36bool LanguageSet::Empty() const { return bitvector.none(); }37bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; }38 39TypeSystem::TypeSystem() = default;40TypeSystem::~TypeSystem() = default;41 42static TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,43                                         Module *module, Target *target) {44  uint32_t i = 0;45  TypeSystemCreateInstance create_callback;46  while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(47              i++)) != nullptr) {48    if (auto type_system_sp = create_callback(language, module, target))49      return type_system_sp;50  }51 52  return {};53}54 55lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,56                                              Module *module) {57  return CreateInstanceHelper(language, module, nullptr);58}59 60lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,61                                              Target *target) {62  return CreateInstanceHelper(language, nullptr, target);63}64 65#ifndef NDEBUG66bool TypeSystem::Verify(lldb::opaque_compiler_type_t type) { return true; }67#endif68 69bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) {70  return false;71}72 73CompilerType TypeSystem::GetArrayType(lldb::opaque_compiler_type_t type,74                                      uint64_t size) {75  return CompilerType();76}77 78CompilerType79TypeSystem::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {80  return CompilerType();81}82 83CompilerType84TypeSystem::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {85  return CompilerType();86}87 88CompilerType TypeSystem::GetAtomicType(lldb::opaque_compiler_type_t type) {89  return CompilerType();90}91 92CompilerType TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type) {93  return CompilerType();94}95 96CompilerType TypeSystem::AddPtrAuthModifier(lldb::opaque_compiler_type_t type,97                                            uint32_t payload) {98  return CompilerType();99}100 101CompilerType102TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type) {103  return CompilerType();104}105 106CompilerType107TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type) {108  return CompilerType();109}110 111CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type,112                                       const char *name,113                                       const CompilerDeclContext &decl_ctx,114                                       uint32_t opaque_payload) {115  return CompilerType();116}117 118CompilerType TypeSystem::GetBuiltinTypeByName(ConstString name) {119  return CompilerType();120}121 122CompilerType TypeSystem::GetTypeForFormatters(void *type) {123  return CompilerType(weak_from_this(), type);124}125 126bool TypeSystem::IsPromotableIntegerType(lldb::opaque_compiler_type_t type) {127  return false;128}129 130llvm::Expected<CompilerType>131TypeSystem::DoIntegralPromotion(CompilerType from,132                                ExecutionContextScope *exe_scope) {133  return llvm::createStringError(134      "Integral promotion is not implemented for this TypeSystem");135}136 137bool TypeSystem::IsTemplateType(lldb::opaque_compiler_type_t type) {138  return false;139}140 141size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,142                                           bool expand_pack) {143  return 0;144}145 146TemplateArgumentKind147TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx,148                                    bool expand_pack) {149  return eTemplateArgumentKindNull;150}151 152CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type,153                                                 size_t idx, bool expand_pack) {154  return CompilerType();155}156 157std::optional<CompilerType::IntegralTemplateArgument>158TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type, size_t idx,159                                        bool expand_pack) {160  return std::nullopt;161}162 163LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) {164  return eLazyBoolCalculate;165}166 167bool TypeSystem::IsMeaninglessWithoutDynamicResolution(void *type) {168  return false;169}170 171ConstString TypeSystem::GetMangledTypeName(void *type) {172  return GetTypeName(type, false);173}174 175ConstString TypeSystem::DeclGetMangledName(void *opaque_decl) {176  return ConstString();177}178 179CompilerDeclContext TypeSystem::DeclGetDeclContext(void *opaque_decl) {180  return CompilerDeclContext();181}182 183CompilerType TypeSystem::DeclGetFunctionReturnType(void *opaque_decl) {184  return CompilerType();185}186 187size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) { return 0; }188 189CompilerType TypeSystem::DeclGetFunctionArgumentType(void *opaque_decl,190                                                     size_t arg_idx) {191  return CompilerType();192}193 194std::vector<lldb_private::CompilerContext>195TypeSystem::DeclGetCompilerContext(void *opaque_decl) {196  return {};197}198 199std::vector<lldb_private::CompilerContext>200TypeSystem::DeclContextGetCompilerContext(void *opaque_decl_ctx) {201  return {};202}203 204std::vector<CompilerDecl>205TypeSystem::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,206                                      bool ignore_imported_decls) {207  return std::vector<CompilerDecl>();208}209 210std::unique_ptr<UtilityFunction>211TypeSystem::CreateUtilityFunction(std::string text, std::string name) {212  return {};213}214 215std::optional<llvm::json::Value> TypeSystem::ReportStatistics() {216  return std::nullopt;217}218 219CompilerDeclContext220TypeSystem::GetCompilerDeclContextForType(const CompilerType &type) {221  return CompilerDeclContext();222}223 224#pragma mark TypeSystemMap225 226TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}227 228TypeSystemMap::~TypeSystemMap() = default;229 230void TypeSystemMap::Clear() {231  collection map;232  {233    std::lock_guard<std::mutex> guard(m_mutex);234    map = m_map;235    m_clear_in_progress = true;236  }237  llvm::DenseSet<TypeSystem *> visited;238  for (auto &pair : map) {239    if (visited.count(pair.second.get()))240      continue;241    visited.insert(pair.second.get());242    if (lldb::TypeSystemSP type_system = pair.second)243      type_system->Finalize();244  }245  map.clear();246  {247    std::lock_guard<std::mutex> guard(m_mutex);248    m_map.clear();249    m_clear_in_progress = false;250  }251}252 253void TypeSystemMap::ForEach(254    std::function<bool(lldb::TypeSystemSP)> const &callback) {255 256  // The callback may call into this function again causing257  // us to lock m_mutex twice if we held it across the callback.258  // Since we just care about guarding access to 'm_map', make259  // a local copy and iterate over that instead.260  collection map_snapshot;261  {262      std::lock_guard<std::mutex> guard(m_mutex);263      map_snapshot = m_map;264  }265 266  // Use a std::set so we only call the callback once for each unique267  // TypeSystem instance.268  llvm::DenseSet<TypeSystem *> visited;269  for (auto &pair : map_snapshot) {270    TypeSystem *type_system = pair.second.get();271    if (!type_system || visited.count(type_system))272      continue;273    visited.insert(type_system);274    assert(type_system);275    if (!callback(pair.second))276      break;277  }278}279 280llvm::Expected<lldb::TypeSystemSP> TypeSystemMap::GetTypeSystemForLanguage(281    lldb::LanguageType language,282    std::optional<CreateCallback> create_callback) {283  std::lock_guard<std::mutex> guard(m_mutex);284  if (m_clear_in_progress)285    return llvm::createStringError(286        "Unable to get TypeSystem because TypeSystemMap is being cleared");287 288  collection::iterator pos = m_map.find(language);289  if (pos != m_map.end()) {290    if (pos->second) {291      assert(!pos->second->weak_from_this().expired());292      return pos->second;293    }294    return llvm::createStringError(295        "TypeSystem for language " +296        llvm::StringRef(Language::GetNameForLanguageType(language)) +297        " doesn't exist");298  }299 300  for (const auto &pair : m_map) {301    if (pair.second && pair.second->SupportsLanguage(language)) {302      // Add a new mapping for "language" to point to an already existing303      // TypeSystem that supports this language304      m_map[language] = pair.second;305      if (pair.second)306        return pair.second;307      return llvm::createStringError(308          "TypeSystem for language " +309          llvm::StringRef(Language::GetNameForLanguageType(language)) +310          " doesn't exist");311    }312  }313 314  if (!create_callback)315    return llvm::createStringError(316        "Unable to find type system for language " +317        llvm::StringRef(Language::GetNameForLanguageType(language)));318  // Cache even if we get a shared pointer that contains a null type system319  // back.320  TypeSystemSP type_system_sp = (*create_callback)();321  m_map[language] = type_system_sp;322  if (type_system_sp)323    return type_system_sp;324  return llvm::createStringError(325      "TypeSystem for language " +326      llvm::StringRef(Language::GetNameForLanguageType(language)) +327      " doesn't exist");328}329 330llvm::Expected<lldb::TypeSystemSP>331TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,332                                        Module *module, bool can_create) {333  if (can_create) {334    return GetTypeSystemForLanguage(335        language, std::optional<CreateCallback>([language, module]() {336          return TypeSystem::CreateInstance(language, module);337        }));338  }339  return GetTypeSystemForLanguage(language);340}341 342llvm::Expected<lldb::TypeSystemSP>343TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,344                                        Target *target, bool can_create) {345  if (can_create) {346    return GetTypeSystemForLanguage(347        language, std::optional<CreateCallback>([language, target]() {348          return TypeSystem::CreateInstance(language, target);349        }));350  }351  return GetTypeSystemForLanguage(language);352}353 354bool TypeSystem::SupportsLanguageStatic(lldb::LanguageType language) {355  if (language == eLanguageTypeUnknown || language >= eNumLanguageTypes)356    return false;357 358  LanguageSet languages =359      PluginManager::GetAllTypeSystemSupportedLanguagesForTypes();360  if (languages.Empty())361    return false;362  return languages[language];363}364