]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Symbol/TypeSystem.cpp
Fix a memory leak in if_delgroups() introduced in r334118.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Symbol / TypeSystem.cpp
1 //===-- TypeSystem.cpp ------------------------------------------*- C++ -*-===//
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
9 //
10 //  TypeSystem.cpp
11 //  lldb
12 //
13 //  Created by Ryan Brown on 3/29/15.
14 //
15 //
16
17 #include "lldb/Symbol/TypeSystem.h"
18
19 #include <set>
20
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Symbol/CompilerType.h"
23
24 using namespace lldb_private;
25 using namespace lldb;
26
27 TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {}
28
29 TypeSystem::~TypeSystem() {}
30
31 static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,
32                                                Module *module, Target *target) {
33   uint32_t i = 0;
34   TypeSystemCreateInstance create_callback;
35   while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
36               i++)) != nullptr) {
37     lldb::TypeSystemSP type_system_sp =
38         create_callback(language, module, target);
39     if (type_system_sp)
40       return type_system_sp;
41   }
42
43   return lldb::TypeSystemSP();
44 }
45
46 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
47                                               Module *module) {
48   return CreateInstanceHelper(language, module, nullptr);
49 }
50
51 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
52                                               Target *target) {
53   return CreateInstanceHelper(language, nullptr, target);
54 }
55
56 bool TypeSystem::IsAnonymousType(lldb::opaque_compiler_type_t type) {
57   return false;
58 }
59
60 CompilerType TypeSystem::GetArrayType(lldb::opaque_compiler_type_t type,
61                                       uint64_t size) {
62   return CompilerType();
63 }
64
65 CompilerType
66 TypeSystem::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
67   return CompilerType();
68 }
69
70 CompilerType
71 TypeSystem::GetRValueReferenceType(lldb::opaque_compiler_type_t type) {
72   return CompilerType();
73 }
74
75 CompilerType TypeSystem::AddConstModifier(lldb::opaque_compiler_type_t type) {
76   return CompilerType();
77 }
78
79 CompilerType
80 TypeSystem::AddVolatileModifier(lldb::opaque_compiler_type_t type) {
81   return CompilerType();
82 }
83
84 CompilerType
85 TypeSystem::AddRestrictModifier(lldb::opaque_compiler_type_t type) {
86   return CompilerType();
87 }
88
89 CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type,
90                                        const char *name,
91                                        const CompilerDeclContext &decl_ctx) {
92   return CompilerType();
93 }
94
95 CompilerType TypeSystem::GetBuiltinTypeByName(ConstString name) {
96   return CompilerType();
97 }
98
99 CompilerType TypeSystem::GetTypeForFormatters(void *type) {
100   return CompilerType(this, type);
101 }
102
103 size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
104   return 0;
105 }
106
107 TemplateArgumentKind
108 TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) {
109   return eTemplateArgumentKindNull;
110 }
111
112 CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type,
113                                                  size_t idx) {
114   return CompilerType();
115 }
116
117 llvm::Optional<CompilerType::IntegralTemplateArgument>
118 TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type,
119                                         size_t idx) {
120   return llvm::None;
121 }
122
123 LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) {
124   return eLazyBoolCalculate;
125 }
126
127 bool TypeSystem::IsMeaninglessWithoutDynamicResolution(void *type) {
128   return false;
129 }
130
131 ConstString TypeSystem::DeclGetMangledName(void *opaque_decl) {
132   return ConstString();
133 }
134
135 CompilerDeclContext TypeSystem::DeclGetDeclContext(void *opaque_decl) {
136   return CompilerDeclContext();
137 }
138
139 CompilerType TypeSystem::DeclGetFunctionReturnType(void *opaque_decl) {
140   return CompilerType();
141 }
142
143 size_t TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl) { return 0; }
144
145 CompilerType TypeSystem::DeclGetFunctionArgumentType(void *opaque_decl,
146                                                      size_t arg_idx) {
147   return CompilerType();
148 }
149
150 std::vector<CompilerDecl>
151 TypeSystem::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
152                                       bool ignore_imported_decls) {
153   return std::vector<CompilerDecl>();
154 }
155
156 #pragma mark TypeSystemMap
157
158 TypeSystemMap::TypeSystemMap()
159     : m_mutex(), m_map(), m_clear_in_progress(false) {}
160
161 TypeSystemMap::~TypeSystemMap() {}
162
163 void TypeSystemMap::Clear() {
164   collection map;
165   {
166     std::lock_guard<std::mutex> guard(m_mutex);
167     map = m_map;
168     m_clear_in_progress = true;
169   }
170   std::set<TypeSystem *> visited;
171   for (auto pair : map) {
172     TypeSystem *type_system = pair.second.get();
173     if (type_system && !visited.count(type_system)) {
174       visited.insert(type_system);
175       type_system->Finalize();
176     }
177   }
178   map.clear();
179   {
180     std::lock_guard<std::mutex> guard(m_mutex);
181     m_map.clear();
182     m_clear_in_progress = false;
183   }
184 }
185
186 void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
187   std::lock_guard<std::mutex> guard(m_mutex);
188   // Use a std::set so we only call the callback once for each unique
189   // TypeSystem instance
190   std::set<TypeSystem *> visited;
191   for (auto pair : m_map) {
192     TypeSystem *type_system = pair.second.get();
193     if (type_system && !visited.count(type_system)) {
194       visited.insert(type_system);
195       if (!callback(type_system))
196         break;
197     }
198   }
199 }
200
201 TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
202                                                     Module *module,
203                                                     bool can_create) {
204   std::lock_guard<std::mutex> guard(m_mutex);
205   collection::iterator pos = m_map.find(language);
206   if (pos != m_map.end())
207     return pos->second.get();
208
209   for (const auto &pair : m_map) {
210     if (pair.second && pair.second->SupportsLanguage(language)) {
211       // Add a new mapping for "language" to point to an already existing
212       // TypeSystem that supports this language
213       AddToMap(language, pair.second);
214       return pair.second.get();
215     }
216   }
217
218   if (!can_create)
219     return nullptr;
220
221   // Cache even if we get a shared pointer that contains null type system back
222   lldb::TypeSystemSP type_system_sp =
223       TypeSystem::CreateInstance(language, module);
224   AddToMap(language, type_system_sp);
225   return type_system_sp.get();
226 }
227
228 TypeSystem *TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
229                                                     Target *target,
230                                                     bool can_create) {
231   std::lock_guard<std::mutex> guard(m_mutex);
232   collection::iterator pos = m_map.find(language);
233   if (pos != m_map.end())
234     return pos->second.get();
235
236   for (const auto &pair : m_map) {
237     if (pair.second && pair.second->SupportsLanguage(language)) {
238       // Add a new mapping for "language" to point to an already existing
239       // TypeSystem that supports this language
240
241       AddToMap(language, pair.second);
242       return pair.second.get();
243     }
244   }
245
246   if (!can_create)
247     return nullptr;
248
249   // Cache even if we get a shared pointer that contains null type system back
250   lldb::TypeSystemSP type_system_sp;
251   if (!m_clear_in_progress)
252     type_system_sp = TypeSystem::CreateInstance(language, target);
253
254   AddToMap(language, type_system_sp);
255   return type_system_sp.get();
256 }
257
258 void TypeSystemMap::AddToMap(lldb::LanguageType language,
259                              lldb::TypeSystemSP const &type_system_sp) {
260   if (!m_clear_in_progress)
261     m_map[language] = type_system_sp;
262 }