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 <set>
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 
39 
40 static lldb::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  lldb::TypeSystemSP type_system_sp =
47  create_callback(language, module, target);
48  if (type_system_sp)
49  return type_system_sp;
50  }
51 
52  return lldb::TypeSystemSP();
53 }
54 
55 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
56  Module *module) {
57  return CreateInstanceHelper(language, module, nullptr);
58 }
59 
60 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
61  Target *target) {
62  return CreateInstanceHelper(language, nullptr, target);
63 }
64 
65 #ifndef NDEBUG
67 #endif
68 
70  return false;
71 }
72 
74  uint64_t size) {
75  return CompilerType();
76 }
77 
80  return CompilerType();
81 }
82 
85  return CompilerType();
86 }
87 
89  return CompilerType();
90 }
91 
93  return CompilerType();
94 }
95 
98  return CompilerType();
99 }
100 
103  return CompilerType();
104 }
105 
107  const char *name,
108  const CompilerDeclContext &decl_ctx,
109  uint32_t opaque_payload) {
110  return CompilerType();
111 }
112 
114  return CompilerType();
115 }
116 
118  return CompilerType(this, type);
119 }
120 
122  return 0;
123 }
124 
128 }
129 
131  size_t idx) {
132  return CompilerType();
133 }
134 
135 llvm::Optional<CompilerType::IntegralTemplateArgument>
137  size_t idx) {
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 #pragma mark TypeSystemMap
180 
182  : m_mutex(), m_map(), m_clear_in_progress(false) {}
183 
185 
187  collection map;
188  {
189  std::lock_guard<std::mutex> guard(m_mutex);
190  map = m_map;
191  m_clear_in_progress = true;
192  }
193  std::set<TypeSystem *> visited;
194  for (auto pair : map) {
195  TypeSystem *type_system = pair.second.get();
196  if (type_system && !visited.count(type_system)) {
197  visited.insert(type_system);
198  type_system->Finalize();
199  }
200  }
201  map.clear();
202  {
203  std::lock_guard<std::mutex> guard(m_mutex);
204  m_map.clear();
205  m_clear_in_progress = false;
206  }
207 }
208 
209 void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
210  std::lock_guard<std::mutex> guard(m_mutex);
211  // Use a std::set so we only call the callback once for each unique
212  // TypeSystem instance
213  std::set<TypeSystem *> visited;
214  for (auto pair : m_map) {
215  TypeSystem *type_system = pair.second.get();
216  if (type_system && !visited.count(type_system)) {
217  visited.insert(type_system);
218  if (!callback(type_system))
219  break;
220  }
221  }
222 }
223 
224 llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
225  lldb::LanguageType language,
226  llvm::Optional<CreateCallback> create_callback) {
227  llvm::Error error = llvm::Error::success();
228  assert(!error); // Check the success value when assertions are enabled
229  std::lock_guard<std::mutex> guard(m_mutex);
230  if (m_clear_in_progress) {
231  error = llvm::make_error<llvm::StringError>(
232  "Unable to get TypeSystem because TypeSystemMap is being cleared",
233  llvm::inconvertibleErrorCode());
234  } else {
235  collection::iterator pos = m_map.find(language);
236  if (pos != m_map.end()) {
237  auto *type_system = pos->second.get();
238  if (type_system) {
239  llvm::consumeError(std::move(error));
240  return *type_system;
241  }
242  error = llvm::make_error<llvm::StringError>(
243  "TypeSystem for language " +
244  llvm::StringRef(Language::GetNameForLanguageType(language)) +
245  " doesn't exist",
246  llvm::inconvertibleErrorCode());
247  return std::move(error);
248  }
249 
250  for (const auto &pair : m_map) {
251  if (pair.second && pair.second->SupportsLanguage(language)) {
252  // Add a new mapping for "language" to point to an already existing
253  // TypeSystem that supports this language
254  m_map[language] = pair.second;
255  if (pair.second.get()) {
256  llvm::consumeError(std::move(error));
257  return *pair.second.get();
258  }
259  error = llvm::make_error<llvm::StringError>(
260  "TypeSystem for language " +
261  llvm::StringRef(Language::GetNameForLanguageType(language)) +
262  " doesn't exist",
263  llvm::inconvertibleErrorCode());
264  return std::move(error);
265  }
266  }
267 
268  if (!create_callback) {
269  error = llvm::make_error<llvm::StringError>(
270  "Unable to find type system for language " +
271  llvm::StringRef(Language::GetNameForLanguageType(language)),
272  llvm::inconvertibleErrorCode());
273  } else {
274  // Cache even if we get a shared pointer that contains a null type system
275  // back
276  TypeSystemSP type_system_sp = (*create_callback)();
277  m_map[language] = type_system_sp;
278  if (type_system_sp.get()) {
279  llvm::consumeError(std::move(error));
280  return *type_system_sp.get();
281  }
282  error = llvm::make_error<llvm::StringError>(
283  "TypeSystem for language " +
284  llvm::StringRef(Language::GetNameForLanguageType(language)) +
285  " doesn't exist",
286  llvm::inconvertibleErrorCode());
287  }
288  }
289 
290  return std::move(error);
291 }
292 
293 llvm::Expected<TypeSystem &>
295  Module *module, bool can_create) {
296  if (can_create) {
298  language, llvm::Optional<CreateCallback>([language, module]() {
299  return TypeSystem::CreateInstance(language, module);
300  }));
301  }
302  return GetTypeSystemForLanguage(language);
303 }
304 
305 llvm::Expected<TypeSystem &>
307  Target *target, bool can_create) {
308  if (can_create) {
310  language, llvm::Optional<CreateCallback>([language, target]() {
311  return TypeSystem::CreateInstance(language, target);
312  }));
313  }
314  return GetTypeSystemForLanguage(language);
315 }
lldb_private::TypeSystem::DeclGetFunctionNumArguments
virtual size_t DeclGetFunctionNumArguments(void *opaque_decl)
Definition: TypeSystem.cpp:161
lldb_private::TypeSystem::CreateInstance
static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module)
Definition: TypeSystem.cpp:55
lldb_private::LanguageSet::GetSingularLanguage
llvm::Optional< lldb::LanguageType > GetSingularLanguage()
If the set contains a single language only, return it.
Definition: TypeSystem.cpp:27
lldb_private::TypeSystem::GetNumTemplateArguments
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:121
lldb_private::TypeSystem::IsAnonymousType
virtual bool IsAnonymousType(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:69
lldb_private::TypeSystem::GetIntegralTemplateArgument
virtual llvm::Optional< CompilerType::IntegralTemplateArgument > GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx)
Definition: TypeSystem.cpp:136
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:84
CreateInstanceHelper
static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language, Module *module, Target *target)
Definition: TypeSystem.cpp:40
lldb::eNumLanguageTypes
@ eNumLanguageTypes
Definition: lldb-enumerations.h:482
lldb::LanguageType
LanguageType
Programming language type.
Definition: lldb-enumerations.h:436
lldb_private::Module
Definition: Module.h:75
lldb_private::TypeSystem::IsMeaninglessWithoutDynamicResolution
virtual bool IsMeaninglessWithoutDynamicResolution(void *type)
Definition: TypeSystem.cpp:145
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:445
lldb_private::TypeSystemMap::GetTypeSystemForLanguage
llvm::Expected< TypeSystem & > GetTypeSystemForLanguage(lldb::LanguageType language, Module *module, bool can_create)
Definition: TypeSystem.cpp:294
lldb_private::TypeSystem::Finalize
virtual void Finalize()
Definition: TypeSystem.h:87
lldb_private::TypeSystemMap::ForEach
void ForEach(std::function< bool(TypeSystem *)> const &callback)
Definition: TypeSystem.cpp:209
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:106
lldb_private::TypeSystem::DeclGetMangledName
virtual ConstString DeclGetMangledName(void *opaque_decl)
Definition: TypeSystem.cpp:149
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::LanguageSet::bitvector
llvm::SmallBitVector bitvector
Definition: TypeSystem.h:41
lldb_private::TypeSystem::AddVolatileModifier
virtual CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:97
lldb_private::TypeSystemMap::m_mutex
std::mutex m_mutex
A mutex to keep this object happy in multi-threaded environments.
Definition: TypeSystem.h:524
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:79
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::TypeSystemMap::~TypeSystemMap
~TypeSystemMap()
Definition: TypeSystem.cpp:184
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:38
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:66
TypeSystem.h
lldb::TemplateArgumentKind
TemplateArgumentKind
Definition: lldb-enumerations.h:813
CompilerType.h
lldb_private::CompilerDeclContext
Represents a generic declaration context in a program.
Definition: CompilerDeclContext.h:30
UtilityFunction.h
lldb_private::TypeSystem::GetTemplateArgumentKind
virtual lldb::TemplateArgumentKind GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx)
Definition: TypeSystem.cpp:126
lldb_private::TypeSystemMap::TypeSystemMap
TypeSystemMap()
Definition: TypeSystem.cpp:181
lldb_private::TypeSystemMap::collection
std::map< lldb::LanguageType, lldb::TypeSystemSP > collection
Definition: TypeSystem.h:523
lldb_private::TypeSystem::GetBuiltinTypeByName
virtual CompilerType GetBuiltinTypeByName(ConstString name)
Definition: TypeSystem.cpp:113
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
lldb::eTemplateArgumentKindNull
@ eTemplateArgumentKindNull
Definition: lldb-enumerations.h:814
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
Definition: TypeSystem.cpp:38
lldb_private::TypeSystem::AddConstModifier
virtual CompilerType AddConstModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:92
lldb_private::TypeSystem::GetTypeTemplateArgument
virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx)
Definition: TypeSystem.cpp:130
lldb_private::TypeSystem::GetArrayType
virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type, uint64_t size)
Definition: TypeSystem.cpp:73
PluginManager.h
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:33
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:1218
lldb_private::TypeSystem
Interface for representing a type system.
Definition: TypeSystem.h:71
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:29
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:117
lldb_private::Language::GetNameForLanguageType
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition: Language.cpp:206
lldb_private::TypeSystemMap::m_map
collection m_map
Definition: TypeSystem.h:526
lldb_private::TypeSystemMap::Clear
void Clear()
Definition: TypeSystem.cpp:186
lldb_private::TypeSystem::AddRestrictModifier
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type)
Definition: TypeSystem.cpp:102
lldb_private::LanguageSet::operator[]
bool operator[](unsigned i) const
Definition: TypeSystem.cpp:36
lldb
Definition: SBAddress.h:15
lldb_private::TypeSystemMap::m_clear_in_progress
bool m_clear_in_progress
Definition: TypeSystem.h:527
lldb::opaque_compiler_type_t
void * opaque_compiler_type_t
Definition: lldb-types.h:90
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:88