1 //===-- LanguageCategory.cpp ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/DataFormatters/LanguageCategory.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/DataFormatters/FormatManager.h"
17 #include "lldb/DataFormatters/TypeCategory.h"
18 #include "lldb/DataFormatters/TypeFormat.h"
19 #include "lldb/DataFormatters/TypeSummary.h"
20 #include "lldb/DataFormatters/TypeSynthetic.h"
21 #include "lldb/DataFormatters/TypeValidator.h"
22 #include "lldb/Target/Language.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 LanguageCategory::LanguageCategory (lldb::LanguageType lang_type) :
28     m_category_sp(),
29     m_hardcoded_formats(),
30     m_hardcoded_summaries(),
31     m_hardcoded_synthetics(),
32     m_hardcoded_validators(),
33     m_format_cache(),
34     m_enabled(false)
35 {
36     if (Language* language_plugin = Language::FindPlugin(lang_type))
37     {
38         m_category_sp = language_plugin->GetFormatters();
39         m_hardcoded_formats = language_plugin->GetHardcodedFormats();
40         m_hardcoded_summaries = language_plugin->GetHardcodedSummaries();
41         m_hardcoded_synthetics = language_plugin->GetHardcodedSynthetics();
42         m_hardcoded_validators = language_plugin->GetHardcodedValidators();
43     }
44     Enable();
45 }
46 
47 bool
48 LanguageCategory::Get (ValueObject& valobj,
49                        lldb::DynamicValueType dynamic,
50                        FormattersMatchVector matches,
51                        lldb::TypeFormatImplSP& format_sp)
52 {
53     if (!m_category_sp)
54         return false;
55 
56     if (!IsEnabled())
57         return false;
58 
59     ConstString type_name = FormatManager::GetTypeForCache(valobj, dynamic);
60     if (type_name)
61     {
62         if (m_format_cache.GetFormat(type_name, format_sp))
63             return format_sp.get() != nullptr;
64     }
65     bool result = m_category_sp->Get(valobj, matches, format_sp);
66     if (type_name && (!format_sp || !format_sp->NonCacheable()))
67     {
68         m_format_cache.SetFormat(type_name, format_sp);
69     }
70     return result;
71 }
72 
73 bool
74 LanguageCategory::Get (ValueObject& valobj,
75                        lldb::DynamicValueType dynamic,
76                        FormattersMatchVector matches,
77                        lldb::TypeSummaryImplSP& format_sp)
78 {
79     if (!m_category_sp)
80         return false;
81 
82     if (!IsEnabled())
83         return false;
84 
85     ConstString type_name = FormatManager::GetTypeForCache(valobj, dynamic);
86     if (type_name)
87     {
88         if (m_format_cache.GetSummary(type_name, format_sp))
89             return format_sp.get() != nullptr;
90     }
91     bool result = m_category_sp->Get(valobj, matches, format_sp);
92     if (type_name && (!format_sp || !format_sp->NonCacheable()))
93     {
94         m_format_cache.SetSummary(type_name, format_sp);
95     }
96     return result;
97 }
98 
99 bool
100 LanguageCategory::Get (ValueObject& valobj,
101                        lldb::DynamicValueType dynamic,
102                        FormattersMatchVector matches,
103                        lldb::SyntheticChildrenSP& format_sp)
104 {
105     if (!m_category_sp)
106         return false;
107 
108     if (!IsEnabled())
109         return false;
110 
111     ConstString type_name = FormatManager::GetTypeForCache(valobj, dynamic);
112     if (type_name)
113     {
114         if (m_format_cache.GetSynthetic(type_name, format_sp))
115             return format_sp.get() != nullptr;
116     }
117     bool result = m_category_sp->Get(valobj, matches, format_sp);
118     if (type_name && (!format_sp || !format_sp->NonCacheable()))
119     {
120         m_format_cache.SetSynthetic(type_name, format_sp);
121     }
122     return result;
123 }
124 
125 bool
126 LanguageCategory::Get (ValueObject& valobj,
127                        lldb::DynamicValueType dynamic,
128                        FormattersMatchVector matches,
129                        lldb::TypeValidatorImplSP& format_sp)
130 {
131     if (!m_category_sp)
132         return false;
133 
134     if (!IsEnabled())
135         return false;
136 
137     ConstString type_name = FormatManager::GetTypeForCache(valobj, dynamic);
138     if (type_name)
139     {
140         if (m_format_cache.GetValidator(type_name, format_sp))
141             return format_sp.get() != nullptr;
142     }
143     bool result = m_category_sp->Get(valobj, matches, format_sp);
144     if (type_name && (!format_sp || !format_sp->NonCacheable()))
145     {
146         m_format_cache.SetValidator(type_name, format_sp);
147     }
148     return result;
149 }
150 
151 bool
152 LanguageCategory::GetHardcoded (ValueObject& valobj,
153                                 lldb::DynamicValueType use_dynamic,
154                                 FormatManager& fmt_mgr,
155                                 lldb::TypeFormatImplSP& format_sp)
156 {
157     if (!IsEnabled())
158         return false;
159 
160     ConstString type_name = FormatManager::GetTypeForCache(valobj, use_dynamic);
161 
162     for (auto& candidate : m_hardcoded_formats)
163     {
164         if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
165             break;
166     }
167     if (type_name && (!format_sp || !format_sp->NonCacheable()))
168     {
169         m_format_cache.SetFormat(type_name, format_sp);
170     }
171     return format_sp.get() != nullptr;
172 }
173 
174 bool
175 LanguageCategory::GetHardcoded (ValueObject& valobj,
176                                 lldb::DynamicValueType use_dynamic,
177                                 FormatManager& fmt_mgr,
178                                 lldb::TypeSummaryImplSP& format_sp)
179 {
180     if (!IsEnabled())
181         return false;
182 
183     ConstString type_name = FormatManager::GetTypeForCache(valobj, use_dynamic);
184 
185     for (auto& candidate : m_hardcoded_summaries)
186     {
187         if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
188             break;
189     }
190     if (type_name && (!format_sp || !format_sp->NonCacheable()))
191     {
192         m_format_cache.SetSummary(type_name, format_sp);
193     }
194     return format_sp.get() != nullptr;
195 }
196 
197 bool
198 LanguageCategory::GetHardcoded (ValueObject& valobj,
199                                 lldb::DynamicValueType use_dynamic,
200                                 FormatManager& fmt_mgr,
201                                 lldb::SyntheticChildrenSP& format_sp)
202 {
203     if (!IsEnabled())
204         return false;
205 
206     ConstString type_name = FormatManager::GetTypeForCache(valobj, use_dynamic);
207 
208     for (auto& candidate : m_hardcoded_synthetics)
209     {
210         if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
211             break;
212     }
213     if (type_name && (!format_sp || !format_sp->NonCacheable()))
214     {
215         m_format_cache.SetSynthetic(type_name, format_sp);
216     }
217     return format_sp.get() != nullptr;
218 }
219 
220 bool
221 LanguageCategory::GetHardcoded (ValueObject& valobj,
222                                 lldb::DynamicValueType use_dynamic,
223                                 FormatManager& fmt_mgr,
224                                 lldb::TypeValidatorImplSP& format_sp)
225 {
226     if (!IsEnabled())
227         return false;
228 
229     ConstString type_name = FormatManager::GetTypeForCache(valobj, use_dynamic);
230 
231     for (auto& candidate : m_hardcoded_validators)
232     {
233         if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
234             break;
235     }
236     if (type_name && (!format_sp || !format_sp->NonCacheable()))
237     {
238         m_format_cache.SetValidator(type_name, format_sp);
239     }
240     return format_sp.get() != nullptr;
241 }
242 
243 lldb::TypeCategoryImplSP
244 LanguageCategory::GetCategory () const
245 {
246     return m_category_sp;
247 }
248 
249 void
250 LanguageCategory::Enable ()
251 {
252     if (m_category_sp)
253         m_category_sp->Enable(true, TypeCategoryMap::Default);
254     m_enabled = true;
255 }
256 
257 void
258 LanguageCategory::Disable ()
259 {
260     if (m_category_sp)
261         m_category_sp->Disable();
262     m_enabled = false;
263 }
264 
265 bool
266 LanguageCategory::IsEnabled ()
267 {
268     return m_enabled;
269 }
270