180814287SRaphael Isemann //===-- TypeSystem.cpp ----------------------------------------------------===//
2696bd635SAlexander Shaposhnikov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6696bd635SAlexander Shaposhnikov //
7696bd635SAlexander Shaposhnikov //===----------------------------------------------------------------------===//
8696bd635SAlexander Shaposhnikov 
9c6f04689SGreg Clayton #include "lldb/Symbol/TypeSystem.h"
1056939cb3SGreg Clayton #include "lldb/Core/PluginManager.h"
11a4459fecSJonas Devlieghere #include "lldb/Expression/UtilityFunction.h"
1256939cb3SGreg Clayton #include "lldb/Symbol/CompilerType.h"
130e252e38SAlex Langford #include "lldb/Target/Language.h"
1456939cb3SGreg Clayton 
15a4459fecSJonas Devlieghere #include <set>
16a4459fecSJonas Devlieghere 
17c6f04689SGreg Clayton using namespace lldb_private;
18769b21eaSPavel Labath using namespace lldb;
19c6f04689SGreg Clayton 
20aa97a89dSAdrian Prantl /// A 64-bit SmallBitVector is only small up to 64-7 bits, and the
21aa97a89dSAdrian Prantl /// setBitsInMask interface wants to write full bytes.
22aa97a89dSAdrian Prantl static const size_t g_num_small_bitvector_bits = 64 - 8;
23aa97a89dSAdrian Prantl static_assert(eNumLanguageTypes < g_num_small_bitvector_bits,
24aa97a89dSAdrian Prantl               "Languages bit vector is no longer small on 64 bit systems");
LanguageSet()258afcfbfbSKazu Hirata LanguageSet::LanguageSet() : bitvector(eNumLanguageTypes, false) {}
26aa97a89dSAdrian Prantl 
GetSingularLanguage()27aa97a89dSAdrian Prantl llvm::Optional<LanguageType> LanguageSet::GetSingularLanguage() {
28aa97a89dSAdrian Prantl   if (bitvector.count() == 1)
29aa97a89dSAdrian Prantl     return (LanguageType)bitvector.find_first();
30aa97a89dSAdrian Prantl   return {};
31aa97a89dSAdrian Prantl }
32aa97a89dSAdrian Prantl 
Insert(LanguageType language)33aa97a89dSAdrian Prantl void LanguageSet::Insert(LanguageType language) { bitvector.set(language); }
Size() const34aa97a89dSAdrian Prantl size_t LanguageSet::Size() const { return bitvector.count(); }
Empty() const35aa97a89dSAdrian Prantl bool LanguageSet::Empty() const { return bitvector.none(); }
operator [](unsigned i) const36aa97a89dSAdrian Prantl bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; }
37aa97a89dSAdrian Prantl 
38fd2433e1SJonas Devlieghere TypeSystem::~TypeSystem() = default;
3956939cb3SGreg Clayton 
CreateInstanceHelper(lldb::LanguageType language,Module * module,Target * target)409ce44321SDavide Italiano static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,
419ce44321SDavide Italiano                                                Module *module, Target *target) {
4256939cb3SGreg Clayton   uint32_t i = 0;
4356939cb3SGreg Clayton   TypeSystemCreateInstance create_callback;
44b9c1b51eSKate Stone   while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
45b9c1b51eSKate Stone               i++)) != nullptr) {
46b9c1b51eSKate Stone     lldb::TypeSystemSP type_system_sp =
479ce44321SDavide Italiano         create_callback(language, module, target);
485beec213SGreg Clayton     if (type_system_sp)
495beec213SGreg Clayton       return type_system_sp;
505beec213SGreg Clayton   }
515beec213SGreg Clayton 
525beec213SGreg Clayton   return lldb::TypeSystemSP();
535beec213SGreg Clayton }
545beec213SGreg Clayton 
CreateInstance(lldb::LanguageType language,Module * module)55b9c1b51eSKate Stone lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
569ce44321SDavide Italiano                                               Module *module) {
579ce44321SDavide Italiano   return CreateInstanceHelper(language, module, nullptr);
589ce44321SDavide Italiano }
599ce44321SDavide Italiano 
CreateInstance(lldb::LanguageType language,Target * target)609ce44321SDavide Italiano lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
61b9c1b51eSKate Stone                                               Target *target) {
629ce44321SDavide Italiano   return CreateInstanceHelper(language, nullptr, target);
6356939cb3SGreg Clayton }
6456939cb3SGreg Clayton 
65ea960371SAdrian Prantl #ifndef NDEBUG
Verify(lldb::opaque_compiler_type_t type)66ea960371SAdrian Prantl bool TypeSystem::Verify(lldb::opaque_compiler_type_t type) { return true; }
67ea960371SAdrian Prantl #endif
68ea960371SAdrian Prantl 
IsAnonymousType(lldb::opaque_compiler_type_t type)69b9c1b51eSKate Stone bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) {
707123e2b5SEnrico Granata   return false;
717123e2b5SEnrico Granata }
727123e2b5SEnrico Granata 
GetArrayType(lldb::opaque_compiler_type_t type,uint64_t size)73b9c1b51eSKate Stone CompilerType TypeSystem::GetArrayType(lldb::opaque_compiler_type_t type,
74b9c1b51eSKate Stone                                       uint64_t size) {
75639392feSEnrico Granata   return CompilerType();
76639392feSEnrico Granata }
77639392feSEnrico Granata 
78639392feSEnrico Granata CompilerType
GetLValueReferenceType(lldb::opaque_compiler_type_t type)79b9c1b51eSKate Stone TypeSystem::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
8056939cb3SGreg Clayton   return CompilerType();
8156939cb3SGreg Clayton }
8256939cb3SGreg Clayton 
8356939cb3SGreg Clayton CompilerType
GetRValueReferenceType(lldb::opaque_compiler_type_t type)84b9c1b51eSKate Stone TypeSystem::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
85b9c1b51eSKate Stone   return CompilerType();
86b9c1b51eSKate Stone }
87b9c1b51eSKate Stone 
GetAtomicType(lldb::opaque_compiler_type_t type)88d0fb7a47SRaphael Isemann CompilerType TypeSystem::GetAtomicType(lldb::opaque_compiler_type_t type) {
89d0fb7a47SRaphael Isemann   return CompilerType();
90d0fb7a47SRaphael Isemann }
91d0fb7a47SRaphael Isemann 
AddConstModifier(lldb::opaque_compiler_type_t type)92b9c1b51eSKate Stone CompilerType TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type) {
9356939cb3SGreg Clayton   return CompilerType();
9456939cb3SGreg Clayton }
9556939cb3SGreg Clayton 
9656939cb3SGreg Clayton CompilerType
AddVolatileModifier(lldb::opaque_compiler_type_t type)97b9c1b51eSKate Stone TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
9856939cb3SGreg Clayton   return CompilerType();
9956939cb3SGreg Clayton }
10056939cb3SGreg Clayton 
10156939cb3SGreg Clayton CompilerType
AddRestrictModifier(lldb::opaque_compiler_type_t type)102b9c1b51eSKate Stone TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
10356939cb3SGreg Clayton   return CompilerType();
10456939cb3SGreg Clayton }
10556939cb3SGreg Clayton 
CreateTypedef(lldb::opaque_compiler_type_t type,const char * name,const CompilerDeclContext & decl_ctx,uint32_t opaque_payload)106b9c1b51eSKate Stone CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type,
107b9c1b51eSKate Stone                                        const char *name,
108143d507cSAdrian Prantl                                        const CompilerDeclContext &decl_ctx,
109143d507cSAdrian Prantl                                        uint32_t opaque_payload) {
11056939cb3SGreg Clayton   return CompilerType();
11156939cb3SGreg Clayton }
11256939cb3SGreg Clayton 
GetBuiltinTypeByName(ConstString name)1130e4c4821SAdrian Prantl CompilerType TypeSystem::GetBuiltinTypeByName(ConstString name) {
11456939cb3SGreg Clayton   return CompilerType();
11556939cb3SGreg Clayton }
11656939cb3SGreg Clayton 
GetTypeForFormatters(void * type)117b9c1b51eSKate Stone CompilerType TypeSystem::GetTypeForFormatters(void *type) {
118c6bf2e2dSEnrico Granata   return CompilerType(this, type);
119c6bf2e2dSEnrico Granata }
1209c63f99aSEnrico Granata 
GetNumTemplateArguments(lldb::opaque_compiler_type_t type,bool expand_pack)121*2d5c43adSJonas Devlieghere size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
122*2d5c43adSJonas Devlieghere                                            bool expand_pack) {
1230d0a5960SFrederic Riss   return 0;
1240d0a5960SFrederic Riss }
1250d0a5960SFrederic Riss 
126769b21eaSPavel Labath TemplateArgumentKind
GetTemplateArgumentKind(opaque_compiler_type_t type,size_t idx,bool expand_pack)127*2d5c43adSJonas Devlieghere TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx,
128*2d5c43adSJonas Devlieghere                                     bool expand_pack) {
129769b21eaSPavel Labath   return eTemplateArgumentKindNull;
130769b21eaSPavel Labath }
131769b21eaSPavel Labath 
GetTypeTemplateArgument(opaque_compiler_type_t type,size_t idx,bool expand_pack)132769b21eaSPavel Labath CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type,
133*2d5c43adSJonas Devlieghere                                                  size_t idx, bool expand_pack) {
134769b21eaSPavel Labath   return CompilerType();
135769b21eaSPavel Labath }
136769b21eaSPavel Labath 
137f59056ffSPavel Labath llvm::Optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(opaque_compiler_type_t type,size_t idx,bool expand_pack)138*2d5c43adSJonas Devlieghere TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type, size_t idx,
139*2d5c43adSJonas Devlieghere                                         bool expand_pack) {
140f59056ffSPavel Labath   return llvm::None;
141769b21eaSPavel Labath }
142769b21eaSPavel Labath 
ShouldPrintAsOneLiner(void * type,ValueObject * valobj)143b9c1b51eSKate Stone LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) {
1449c63f99aSEnrico Granata   return eLazyBoolCalculate;
1459c63f99aSEnrico Granata }
1465beec213SGreg Clayton 
IsMeaninglessWithoutDynamicResolution(void * type)14778f05d35SDavide Italiano bool TypeSystem::IsMeaninglessWithoutDynamicResolution(void *type) {
14878f05d35SDavide Italiano   return false;
14978f05d35SDavide Italiano }
15078f05d35SDavide Italiano 
DeclGetMangledName(void * opaque_decl)151b9c1b51eSKate Stone ConstString TypeSystem::DeclGetMangledName(void *opaque_decl) {
152fe68904fSGreg Clayton   return ConstString();
153fe68904fSGreg Clayton }
154fe68904fSGreg Clayton 
DeclGetDeclContext(void * opaque_decl)155b9c1b51eSKate Stone CompilerDeclContext TypeSystem::DeclGetDeclContext(void *opaque_decl) {
156fe68904fSGreg Clayton   return CompilerDeclContext();
157fe68904fSGreg Clayton }
158fe68904fSGreg Clayton 
DeclGetFunctionReturnType(void * opaque_decl)159b9c1b51eSKate Stone CompilerType TypeSystem::DeclGetFunctionReturnType(void *opaque_decl) {
160fe68904fSGreg Clayton   return CompilerType();
161fe68904fSGreg Clayton }
162fe68904fSGreg Clayton 
DeclGetFunctionNumArguments(void * opaque_decl)163b9c1b51eSKate Stone size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) { return 0; }
164fe68904fSGreg Clayton 
DeclGetFunctionArgumentType(void * opaque_decl,size_t arg_idx)165b9c1b51eSKate Stone CompilerType TypeSystem::DeclGetFunctionArgumentType(void *opaque_decl,
166b9c1b51eSKate Stone                                                      size_t arg_idx) {
167fe68904fSGreg Clayton   return CompilerType();
168fe68904fSGreg Clayton }
169fe68904fSGreg Clayton 
170dfc09621SGreg Clayton std::vector<CompilerDecl>
DeclContextFindDeclByName(void * opaque_decl_ctx,ConstString name,bool ignore_imported_decls)171b9c1b51eSKate Stone TypeSystem::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
172b9c1b51eSKate Stone                                       bool ignore_imported_decls) {
173dfc09621SGreg Clayton   return std::vector<CompilerDecl>();
174dfc09621SGreg Clayton }
175dfc09621SGreg Clayton 
176a4459fecSJonas Devlieghere std::unique_ptr<UtilityFunction>
CreateUtilityFunction(std::string text,std::string name)177a4459fecSJonas Devlieghere TypeSystem::CreateUtilityFunction(std::string text, std::string name) {
178a4459fecSJonas Devlieghere   return {};
179a4459fecSJonas Devlieghere }
180a4459fecSJonas Devlieghere 
1815beec213SGreg Clayton #pragma mark TypeSystemMap
1825beec213SGreg Clayton 
TypeSystemMap()1839494c510SJonas Devlieghere TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}
1845beec213SGreg Clayton 
185fd2433e1SJonas Devlieghere TypeSystemMap::~TypeSystemMap() = default;
1865beec213SGreg Clayton 
Clear()187b9c1b51eSKate Stone void TypeSystemMap::Clear() {
1880ea010aeSJim Ingham   collection map;
1890ea010aeSJim Ingham   {
190bb19a13cSSaleem Abdulrasool     std::lock_guard<std::mutex> guard(m_mutex);
1910ea010aeSJim Ingham     map = m_map;
192b6bdfc52SJim Ingham     m_clear_in_progress = true;
1930ea010aeSJim Ingham   }
1940ea010aeSJim Ingham   std::set<TypeSystem *> visited;
195b9c1b51eSKate Stone   for (auto pair : map) {
1960ea010aeSJim Ingham     TypeSystem *type_system = pair.second.get();
197b9c1b51eSKate Stone     if (type_system && !visited.count(type_system)) {
1980ea010aeSJim Ingham       visited.insert(type_system);
1990ea010aeSJim Ingham       type_system->Finalize();
2000ea010aeSJim Ingham     }
2010ea010aeSJim Ingham   }
2020ea010aeSJim Ingham   map.clear();
2030ea010aeSJim Ingham   {
204bb19a13cSSaleem Abdulrasool     std::lock_guard<std::mutex> guard(m_mutex);
2055beec213SGreg Clayton     m_map.clear();
206b6bdfc52SJim Ingham     m_clear_in_progress = false;
2075beec213SGreg Clayton   }
2080ea010aeSJim Ingham }
2095beec213SGreg Clayton 
ForEach(std::function<bool (TypeSystem *)> const & callback)210b9c1b51eSKate Stone void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
211bb19a13cSSaleem Abdulrasool   std::lock_guard<std::mutex> guard(m_mutex);
2125beec213SGreg Clayton   // Use a std::set so we only call the callback once for each unique
2135beec213SGreg Clayton   // TypeSystem instance
2145beec213SGreg Clayton   std::set<TypeSystem *> visited;
215b9c1b51eSKate Stone   for (auto pair : m_map) {
2165beec213SGreg Clayton     TypeSystem *type_system = pair.second.get();
217b9c1b51eSKate Stone     if (type_system && !visited.count(type_system)) {
2185beec213SGreg Clayton       visited.insert(type_system);
219a6682a41SJonas Devlieghere       if (!callback(type_system))
2205beec213SGreg Clayton         break;
2215beec213SGreg Clayton     }
2225beec213SGreg Clayton   }
2235beec213SGreg Clayton }
2245beec213SGreg Clayton 
GetTypeSystemForLanguage(lldb::LanguageType language,llvm::Optional<CreateCallback> create_callback)225f974d64bSRaphael Isemann llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
226f974d64bSRaphael Isemann     lldb::LanguageType language,
227f974d64bSRaphael Isemann     llvm::Optional<CreateCallback> create_callback) {
228bb19a13cSSaleem Abdulrasool   std::lock_guard<std::mutex> guard(m_mutex);
2295033f079SDimitry Andric   if (m_clear_in_progress)
2305033f079SDimitry Andric     return llvm::make_error<llvm::StringError>(
2310e252e38SAlex Langford         "Unable to get TypeSystem because TypeSystemMap is being cleared",
2320e252e38SAlex Langford         llvm::inconvertibleErrorCode());
2335033f079SDimitry Andric 
2345beec213SGreg Clayton   collection::iterator pos = m_map.find(language);
2350e252e38SAlex Langford   if (pos != m_map.end()) {
2360e252e38SAlex Langford     auto *type_system = pos->second.get();
2375033f079SDimitry Andric     if (type_system)
2380e252e38SAlex Langford       return *type_system;
2395033f079SDimitry Andric     return llvm::make_error<llvm::StringError>(
2400e252e38SAlex Langford         "TypeSystem for language " +
241574685b8SJonas Devlieghere             llvm::StringRef(Language::GetNameForLanguageType(language)) +
2420e252e38SAlex Langford             " doesn't exist",
2430e252e38SAlex Langford         llvm::inconvertibleErrorCode());
2440e252e38SAlex Langford   }
2455beec213SGreg Clayton 
246b9c1b51eSKate Stone   for (const auto &pair : m_map) {
247b9c1b51eSKate Stone     if (pair.second && pair.second->SupportsLanguage(language)) {
2485beec213SGreg Clayton       // Add a new mapping for "language" to point to an already existing
2495beec213SGreg Clayton       // TypeSystem that supports this language
2500e252e38SAlex Langford       m_map[language] = pair.second;
2515033f079SDimitry Andric       if (pair.second.get())
2520e252e38SAlex Langford         return *pair.second.get();
2535033f079SDimitry Andric       return llvm::make_error<llvm::StringError>(
2540e252e38SAlex Langford           "TypeSystem for language " +
255574685b8SJonas Devlieghere               llvm::StringRef(Language::GetNameForLanguageType(language)) +
2560e252e38SAlex Langford               " doesn't exist",
2570e252e38SAlex Langford           llvm::inconvertibleErrorCode());
2585beec213SGreg Clayton     }
2595beec213SGreg Clayton   }
2605beec213SGreg Clayton 
2615033f079SDimitry Andric   if (!create_callback)
2625033f079SDimitry Andric     return llvm::make_error<llvm::StringError>(
2630e252e38SAlex Langford         "Unable to find type system for language " +
264574685b8SJonas Devlieghere             llvm::StringRef(Language::GetNameForLanguageType(language)),
2650e252e38SAlex Langford         llvm::inconvertibleErrorCode());
2665033f079SDimitry Andric 
2670e252e38SAlex Langford   // Cache even if we get a shared pointer that contains a null type system
2680e252e38SAlex Langford   // back
269f974d64bSRaphael Isemann   TypeSystemSP type_system_sp = (*create_callback)();
270b6bdfc52SJim Ingham   m_map[language] = type_system_sp;
2715033f079SDimitry Andric   if (type_system_sp.get())
2720e252e38SAlex Langford     return *type_system_sp.get();
2735033f079SDimitry Andric   return llvm::make_error<llvm::StringError>(
2740e252e38SAlex Langford       "TypeSystem for language " +
275574685b8SJonas Devlieghere           llvm::StringRef(Language::GetNameForLanguageType(language)) +
2760e252e38SAlex Langford           " doesn't exist",
2770e252e38SAlex Langford       llvm::inconvertibleErrorCode());
2780e252e38SAlex Langford }
2790e252e38SAlex Langford 
2800e252e38SAlex Langford llvm::Expected<TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language,Module * module,bool can_create)2810e252e38SAlex Langford TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
282f974d64bSRaphael Isemann                                         Module *module, bool can_create) {
283f974d64bSRaphael Isemann   if (can_create) {
284f974d64bSRaphael Isemann     return GetTypeSystemForLanguage(
285f974d64bSRaphael Isemann         language, llvm::Optional<CreateCallback>([language, module]() {
286f974d64bSRaphael Isemann           return TypeSystem::CreateInstance(language, module);
287f974d64bSRaphael Isemann         }));
288f974d64bSRaphael Isemann   }
289f974d64bSRaphael Isemann   return GetTypeSystemForLanguage(language);
290f974d64bSRaphael Isemann }
291f974d64bSRaphael Isemann 
292f974d64bSRaphael Isemann llvm::Expected<TypeSystem &>
GetTypeSystemForLanguage(lldb::LanguageType language,Target * target,bool can_create)293f974d64bSRaphael Isemann TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
2940e252e38SAlex Langford                                         Target *target, bool can_create) {
295f974d64bSRaphael Isemann   if (can_create) {
296f974d64bSRaphael Isemann     return GetTypeSystemForLanguage(
297f974d64bSRaphael Isemann         language, llvm::Optional<CreateCallback>([language, target]() {
298f974d64bSRaphael Isemann           return TypeSystem::CreateInstance(language, target);
299f974d64bSRaphael Isemann         }));
3000e252e38SAlex Langford   }
301f974d64bSRaphael Isemann   return GetTypeSystemForLanguage(language);
302b6bdfc52SJim Ingham }
303