LLDB  mainline
TypeSystem.cpp
Go to the documentation of this file.
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
13 #include "lldb/Target/Language.h"
14 
15 #include "llvm/ADT/DenseSet.h"
16 
17 using namespace lldb_private;
18 using namespace lldb;
19 
20 /// A 64-bit SmallBitVector is only small up to 64-7 bits, and the
21 /// setBitsInMask interface wants to write full bytes.
22 static const size_t g_num_small_bitvector_bits = 64 - 8;
24  "Languages bit vector is no longer small on 64 bit systems");
26 
27 llvm::Optional<LanguageType> LanguageSet::GetSingularLanguage() {
28  if (bitvector.count() == 1)
29  return (LanguageType)bitvector.find_first();
30  return {};
31 }
32 
33 void LanguageSet::Insert(LanguageType language) { bitvector.set(language); }
34 size_t LanguageSet::Size() const { return bitvector.count(); }
35 bool LanguageSet::Empty() const { return bitvector.none(); }
36 bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; }
37 
38 TypeSystem::~TypeSystem() = default;
39 
40 static TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,
41  Module *module, Target *target) {
42  uint32_t i = 0;
43  TypeSystemCreateInstance create_callback;
44  while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
45  i++)) != nullptr) {
46  if (auto type_system_sp = create_callback(language, module, target))
47  return type_system_sp;
48  }
49 
50  return {};
51 }
52 
53 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
54  Module *module) {
55  return CreateInstanceHelper(language, module, nullptr);
56 }
57 
58 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
59  Target *target) {
60  return CreateInstanceHelper(language, nullptr, target);
61 }
62 
63 #ifndef NDEBUG
65 #endif
66 
68  return false;
69 }
70 
72  uint64_t size) {
73  return CompilerType();
74 }
75 
78  return CompilerType();
79 }
80 
83  return CompilerType();
84 }
85 
87  return CompilerType();
88 }
89 
91  return CompilerType();
92 }
93 
96  return CompilerType();
97 }
98 
101  return CompilerType();
102 }
103 
105  const char *name,
106  const CompilerDeclContext &decl_ctx,
107  uint32_t opaque_payload) {
108  return CompilerType();
109 }
110 
112  return CompilerType();
113 }
114 
116  return CompilerType(weak_from_this(), type);
117 }
118 
120  bool expand_pack) {
121  return 0;
122 }
123 
126  bool expand_pack) {
128 }
129 
131  size_t idx, bool expand_pack) {
132  return CompilerType();
133 }
134 
135 llvm::Optional<CompilerType::IntegralTemplateArgument>
137  bool expand_pack) {
138  return llvm::None;
139 }
140 
142  return eLazyBoolCalculate;
143 }
144 
146  return false;
147 }
148 
150  return ConstString();
151 }
152 
154  return CompilerDeclContext();
155 }
156 
158  return CompilerType();
159 }
160 
161 size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) { return 0; }
162 
164  size_t arg_idx) {
165  return CompilerType();
166 }
167 
168 std::vector<CompilerDecl>
170  bool ignore_imported_decls) {
171  return std::vector<CompilerDecl>();
172 }
173 
174 std::unique_ptr<UtilityFunction>
176  return {};
177 }
178 
179 llvm::Optional<llvm::json::Value> TypeSystem::ReportStatistics() {
180  return llvm::None;
181 }
182 
183 #pragma mark TypeSystemMap
184 
185 TypeSystemMap::TypeSystemMap() : m_mutex(), m_map() {}
186 
188 
190  collection map;
191  {
192  std::lock_guard<std::mutex> guard(m_mutex);
193  map = m_map;
194  m_clear_in_progress = true;
195  }
196  llvm::DenseSet<TypeSystem *> visited;
197  for (auto &pair : map) {
198  if (visited.count(pair.second.get()))
199  continue;
200  visited.insert(pair.second.get());
201  if (lldb::TypeSystemSP type_system = pair.second)
202  type_system->Finalize();
203  }
204  map.clear();
205  {
206  std::lock_guard<std::mutex> guard(m_mutex);
207  m_map.clear();
208  m_clear_in_progress = false;
209  }
210 }
211 
213  std::function<bool(lldb::TypeSystemSP)> const &callback) {
214  std::lock_guard<std::mutex> guard(m_mutex);
215  // Use a std::set so we only call the callback once for each unique
216  // TypeSystem instance.
217  llvm::DenseSet<TypeSystem *> visited;
218  for (auto &pair : m_map) {
219  TypeSystem *type_system = pair.second.get();
220  if (!type_system || visited.count(type_system))
221  continue;
222  visited.insert(type_system);
223  assert(type_system);
224  if (!callback(pair.second))
225  break;
226  }
227 }
228 
229 llvm::Expected<lldb::TypeSystemSP> TypeSystemMap::GetTypeSystemForLanguage(
230  lldb::LanguageType language,
231  llvm::Optional<CreateCallback> create_callback) {
232  std::lock_guard<std::mutex> guard(m_mutex);
234  return llvm::make_error<llvm::StringError>(
235  "Unable to get TypeSystem because TypeSystemMap is being cleared",
236  llvm::inconvertibleErrorCode());
237 
238  collection::iterator pos = m_map.find(language);
239  if (pos != m_map.end()) {
240  if (pos->second) {
241  assert(!pos->second->weak_from_this().expired());
242  return pos->second;
243  }
244  return llvm::make_error<llvm::StringError>(
245  "TypeSystem for language " +
246  llvm::StringRef(Language::GetNameForLanguageType(language)) +
247  " doesn't exist",
248  llvm::inconvertibleErrorCode());
249  }
250 
251  for (const auto &pair : m_map) {
252  if (pair.second && pair.second->SupportsLanguage(language)) {
253  // Add a new mapping for "language" to point to an already existing
254  // TypeSystem that supports this language
255  m_map[language] = pair.second;
256  if (pair.second)
257  return pair.second;
258  return llvm::make_error<llvm::StringError>(
259  "TypeSystem for language " +
260  llvm::StringRef(Language::GetNameForLanguageType(language)) +
261  " doesn't exist",
262  llvm::inconvertibleErrorCode());
263  }
264  }
265 
266  if (!create_callback)
267  return llvm::make_error<llvm::StringError>(
268  "Unable to find type system for language " +
269  llvm::StringRef(Language::GetNameForLanguageType(language)),
270  llvm::inconvertibleErrorCode());
271 
272  // Cache even if we get a shared pointer that contains a null type system
273  // back.
274  TypeSystemSP type_system_sp = (*create_callback)();
275  m_map[language] = type_system_sp;
276  if (type_system_sp)
277  return type_system_sp;
278  return llvm::make_error<llvm::StringError>(
279  "TypeSystem for language " +
280  llvm::StringRef(Language::GetNameForLanguageType(language)) +
281  " doesn't exist",
282  llvm::inconvertibleErrorCode());
283 }
284 
285 llvm::Expected<lldb::TypeSystemSP>
287  Module *module, bool can_create) {
288  if (can_create) {
290  language, llvm::Optional<CreateCallback>([language, module]() {
291  return TypeSystem::CreateInstance(language, module);
292  }));
293  }
294  return GetTypeSystemForLanguage(language);
295 }
296 
297 llvm::Expected<lldb::TypeSystemSP>
299  Target *target, bool can_create) {
300  if (can_create) {
302  language, llvm::Optional<CreateCallback>([language, target]() {
303  return TypeSystem::CreateInstance(language, target);
304  }));
305  }
306  return GetTypeSystemForLanguage(language);
307 }
lldb_private::TypeSystem::DeclGetFunctionNumArguments
virtual size_t DeclGetFunctionNumArguments(void *opaque_decl)
Definition: TypeSystem.cpp:161
lldb_private::TypeSystem::GetNumTemplateArguments
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type, bool expand_pack)
Definition: TypeSystem.cpp:119
lldb_private::TypeSystem::CreateInstance
static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module)
Definition: TypeSystem.cpp:53
lldb_private::LanguageSet::GetSingularLanguage
llvm::Optional< lldb::LanguageType > GetSingularLanguage()
If the set contains a single language only, return it.
Definition: TypeSystem.cpp:27
lldb::eNumLanguageTypes
@ eNumLanguageTypes
Definition: lldb-enumerations.h:483
lldb_private::TypeSystem::IsAnonymousType
virtual bool IsAnonymousType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:67
lldb_private::TypeSystemMap::collection
llvm::DenseMap< uint16_t, lldb::TypeSystemSP > collection
Definition: TypeSystem.h:553
lldb_private::TypeSystem::DeclGetDeclContext
virtual CompilerDeclContext DeclGetDeclContext(void *opaque_decl)
Definition: TypeSystem.cpp:153
TypeSystemCreateInstance
lldb_private::LanguageSet::LanguageSet
LanguageSet()
Definition: TypeSystem.cpp:25
lldb_private::TypeSystem::GetRValueReferenceType
virtual CompilerType GetRValueReferenceType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:82
lldb_private::TypeSystem::GetTypeTemplateArgument
virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
Definition: TypeSystem.cpp:130
lldb_private::Module
Definition: Module.h:86
lldb_private::TypeSystem::IsMeaninglessWithoutDynamicResolution
virtual bool IsMeaninglessWithoutDynamicResolution(void *type)
Definition: TypeSystem.cpp:145
lldb_private::TypeSystemMap::GetTypeSystemForLanguage
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language, Module *module, bool can_create)
Definition: TypeSystem.cpp:286
lldb_private::LanguageSet::Insert
void Insert(lldb::LanguageType language)
Definition: TypeSystem.cpp:33
Language.h
lldb_private::LazyBool
LazyBool
Definition: lldb-private-enumerations.h:115
lldb_private::LanguageSet::Empty
bool Empty() const
Definition: TypeSystem.cpp:35
lldb_private::Target
Definition: Target.h:469
lldb_private::TypeSystem::GetTemplateArgumentKind
virtual lldb::TemplateArgumentKind GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
Definition: TypeSystem.cpp:125
lldb_private::TypeSystem::CreateTypedef
virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, const CompilerDeclContext &decl_ctx, uint32_t opaque_payload)
Definition: TypeSystem.cpp:104
lldb_private::TypeSystem::DeclGetMangledName
virtual ConstString DeclGetMangledName(void *opaque_decl)
Definition: TypeSystem.cpp:149
CreateInstanceHelper
static TypeSystemSP CreateInstanceHelper(lldb::LanguageType language, Module *module, Target *target)
Definition: TypeSystem.cpp:40
lldb_private::LanguageSet::bitvector
llvm::SmallBitVector bitvector
Definition: TypeSystem.h:45
lldb_private::TypeSystem::AddVolatileModifier
virtual CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:95
lldb_private::TypeSystemMap::m_mutex
std::mutex m_mutex
A mutex to keep this object happy in multi-threaded environments.
Definition: TypeSystem.h:554
lldb_private::TypeSystem::DeclContextFindDeclByName
virtual std::vector< CompilerDecl > DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls)
Definition: TypeSystem.cpp:169
lldb_private::TypeSystem::GetLValueReferenceType
virtual CompilerType GetLValueReferenceType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:77
lldb_private::ConstString
Definition: ConstString.h:39
lldb_private::TypeSystem::ReportStatistics
virtual llvm::Optional< llvm::json::Value > ReportStatistics()
Definition: TypeSystem.cpp:179
lldb_private::TypeSystemMap::~TypeSystemMap
~TypeSystemMap()
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::TypeSystem::Verify
virtual bool Verify(lldb::opaque_compiler_type_t type)=0
Verify the integrity of the type to catch CompilerTypes that mix and match invalid TypeSystem/Opaque ...
Definition: TypeSystem.cpp:64
TypeSystem.h
lldb::TemplateArgumentKind
TemplateArgumentKind
Definition: lldb-enumerations.h:822
CompilerType.h
lldb_private::CompilerDeclContext
Represents a generic declaration context in a program.
Definition: CompilerDeclContext.h:30
UtilityFunction.h
lldb_private::TypeSystemMap::TypeSystemMap
TypeSystemMap()
Definition: TypeSystem.cpp:185
lldb_private::TypeSystem::GetBuiltinTypeByName
virtual CompilerType GetBuiltinTypeByName(ConstString name)
Definition: TypeSystem.cpp:111
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
lldb::eTemplateArgumentKindNull
@ eTemplateArgumentKindNull
Definition: lldb-enumerations.h:823
lldb_private::TypeSystem::CreateUtilityFunction
virtual std::unique_ptr< UtilityFunction > CreateUtilityFunction(std::string text, std::string name)
Definition: TypeSystem.cpp:175
uint32_t
lldb_private::TypeSystem::~TypeSystem
~TypeSystem() override
lldb_private::TypeSystem::AddConstModifier
virtual CompilerType AddConstModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:90
lldb_private::TypeSystem::GetArrayType
virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type, uint64_t size)
Definition: TypeSystem.cpp:71
PluginManager.h
lldb_private::TypeSystem::GetIntegralTemplateArgument
virtual llvm::Optional< CompilerType::IntegralTemplateArgument > GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, bool expand_pack)
Definition: TypeSystem.cpp:136
lldb_private::TypeSystem::ShouldPrintAsOneLiner
virtual LazyBool ShouldPrintAsOneLiner(void *type, ValueObject *valobj)
Definition: TypeSystem.cpp:141
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:35
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::TypeSystem::DeclGetFunctionReturnType
virtual CompilerType DeclGetFunctionReturnType(void *opaque_decl)
Definition: TypeSystem.cpp:157
lldb_private::eLazyBoolCalculate
@ eLazyBoolCalculate
Definition: lldb-private-enumerations.h:115
lldb_private::LanguageSet::Size
size_t Size() const
Definition: TypeSystem.cpp:34
lldb_private::PluginManager::GetTypeSystemCreateCallbackAtIndex
static TypeSystemCreateInstance GetTypeSystemCreateCallbackAtIndex(uint32_t idx)
Definition: PluginManager.cpp:1311
lldb_private::TypeSystem
Interface for representing a type system.
Definition: TypeSystem.h:75
lldb_private::TypeSystem::DeclGetFunctionArgumentType
virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl, size_t arg_idx)
Definition: TypeSystem.cpp:163
lldb_private::TypeSystem::GetTypeForFormatters
virtual CompilerType GetTypeForFormatters(void *type)
Definition: TypeSystem.cpp:115
lldb_private::Language::GetNameForLanguageType
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition: Language.cpp:217
lldb_private::TypeSystemMap::m_map
collection m_map
Definition: TypeSystem.h:556
lldb_private::TypeSystemMap::Clear
void Clear()
Definition: TypeSystem.cpp:189
lldb_private::TypeSystem::AddRestrictModifier
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:100
lldb_private::LanguageSet::operator[]
bool operator[](unsigned i) const
Definition: TypeSystem.cpp:36
lldb
Definition: SBAddress.h:15
lldb_private::TypeSystemMap::ForEach
void ForEach(std::function< bool(lldb::TypeSystemSP)> const &callback)
Definition: TypeSystem.cpp:212
lldb_private::TypeSystemMap::m_clear_in_progress
bool m_clear_in_progress
Definition: TypeSystem.h:557
lldb::opaque_compiler_type_t
void * opaque_compiler_type_t
Definition: lldb-types.h:90
lldb::LanguageType
LanguageType
Programming language type.
Definition: lldb-enumerations.h:437
g_num_small_bitvector_bits
static const size_t g_num_small_bitvector_bits
A 64-bit SmallBitVector is only small up to 64-7 bits, and the setBitsInMask interface wants to write...
Definition: TypeSystem.cpp:22
lldb_private::TypeSystem::GetAtomicType
virtual CompilerType GetAtomicType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:86