1 //
2 //  TypeSystem.cpp
3 //  lldb
4 //
5 //  Created by Ryan Brown on 3/29/15.
6 //
7 //
8 
9 #include "lldb/Symbol/TypeSystem.h"
10 
11 #include <set>
12 
13 #include "lldb/Core/PluginManager.h"
14 #include "lldb/Symbol/CompilerType.h"
15 
16 using namespace lldb_private;
17 
18 TypeSystem::TypeSystem(LLVMCastKind kind) :
19     m_kind (kind),
20     m_sym_file (nullptr)
21 {
22 }
23 
24 TypeSystem::~TypeSystem()
25 {
26 }
27 
28 lldb::TypeSystemSP
29 TypeSystem::CreateInstance (lldb::LanguageType language, Module *module)
30 {
31     uint32_t i = 0;
32     TypeSystemCreateInstance create_callback;
33     while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex (i++)) != nullptr)
34     {
35         lldb::TypeSystemSP type_system_sp = create_callback(language, module, nullptr);
36         if (type_system_sp)
37             return type_system_sp;
38     }
39 
40     return lldb::TypeSystemSP();
41 }
42 
43 lldb::TypeSystemSP
44 TypeSystem::CreateInstance (lldb::LanguageType language, Target *target)
45 {
46     uint32_t i = 0;
47     TypeSystemCreateInstance create_callback;
48     while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex (i++)) != nullptr)
49     {
50         lldb::TypeSystemSP type_system_sp = create_callback(language, nullptr, target);
51         if (type_system_sp)
52             return type_system_sp;
53     }
54 
55     return lldb::TypeSystemSP();
56 }
57 
58 CompilerType
59 TypeSystem::GetLValueReferenceType (lldb::opaque_compiler_type_t type)
60 {
61     return CompilerType();
62 }
63 
64 CompilerType
65 TypeSystem::GetRValueReferenceType (lldb::opaque_compiler_type_t type)
66 {
67     return CompilerType();
68 }
69 
70 CompilerType
71 TypeSystem::AddConstModifier (lldb::opaque_compiler_type_t type)
72 {
73     return CompilerType();
74 }
75 
76 CompilerType
77 TypeSystem::AddVolatileModifier (lldb::opaque_compiler_type_t type)
78 {
79     return CompilerType();
80 }
81 
82 CompilerType
83 TypeSystem::AddRestrictModifier (lldb::opaque_compiler_type_t type)
84 {
85     return CompilerType();
86 }
87 
88 CompilerType
89 TypeSystem::CreateTypedef (lldb::opaque_compiler_type_t type, const char *name, const CompilerDeclContext &decl_ctx)
90 {
91     return CompilerType();
92 }
93 
94 CompilerType
95 TypeSystem::GetBuiltinTypeByName (const ConstString &name)
96 {
97     return CompilerType();
98 }
99 
100 CompilerType
101 TypeSystem::GetTypeForFormatters (void* type)
102 {
103     return CompilerType(this, type);
104 }
105 
106 LazyBool
107 TypeSystem::ShouldPrintAsOneLiner (void* type)
108 {
109     return eLazyBoolCalculate;
110 }
111 
112 bool
113 TypeSystem::IsMeaninglessWithoutDynamicResolution (void* type)
114 {
115     return false;
116 }
117 
118 #pragma mark TypeSystemMap
119 
120 TypeSystemMap::TypeSystemMap() :
121     m_mutex (),
122     m_map ()
123 {
124 }
125 
126 TypeSystemMap::~TypeSystemMap()
127 {
128 }
129 
130 void
131 TypeSystemMap::Clear ()
132 {
133     Mutex::Locker locker (m_mutex);
134     m_map.clear();
135 }
136 
137 
138 void
139 TypeSystemMap::ForEach (std::function <bool(TypeSystem *)> const &callback)
140 {
141     Mutex::Locker locker (m_mutex);
142     // Use a std::set so we only call the callback once for each unique
143     // TypeSystem instance
144     std::set<TypeSystem *> visited;
145     for (auto pair : m_map)
146     {
147         TypeSystem *type_system = pair.second.get();
148         if (type_system && !visited.count(type_system))
149         {
150             visited.insert(type_system);
151             if (callback (type_system) == false)
152                 break;
153         }
154     }
155 }
156 
157 TypeSystem *
158 TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *module, bool can_create)
159 {
160     Mutex::Locker locker (m_mutex);
161     collection::iterator pos = m_map.find(language);
162     if (pos != m_map.end())
163         return pos->second.get();
164 
165     for (const auto &pair : m_map)
166     {
167         if (pair.second && pair.second->SupportsLanguage(language))
168         {
169             // Add a new mapping for "language" to point to an already existing
170             // TypeSystem that supports this language
171             m_map[language] = pair.second;
172             return pair.second.get();
173         }
174     }
175 
176     if (!can_create)
177         return nullptr;
178 
179     // Cache even if we get a shared pointer that contains null type system back
180     lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, module);
181     m_map[language] = type_system_sp;
182     return type_system_sp.get();
183 }
184 
185 TypeSystem *
186 TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create)
187 {
188     Mutex::Locker locker (m_mutex);
189     collection::iterator pos = m_map.find(language);
190     if (pos != m_map.end())
191         return pos->second.get();
192 
193     for (const auto &pair : m_map)
194     {
195         if (pair.second && pair.second->SupportsLanguage(language))
196         {
197             // Add a new mapping for "language" to point to an already existing
198             // TypeSystem that supports this language
199             m_map[language] = pair.second;
200             return pair.second.get();
201         }
202     }
203 
204     if (!can_create)
205         return nullptr;
206 
207     // Cache even if we get a shared pointer that contains null type system back
208     lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, target);
209     m_map[language] = type_system_sp;
210     return type_system_sp.get();
211 }
212