1*0b57cec5SDimitry Andric //===-- Language.cpp -------------------------------------------------*- C++
2*0b57cec5SDimitry Andric //-*-===//
3*0b57cec5SDimitry Andric //
4*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric //
8*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric 
10*0b57cec5SDimitry Andric #include <functional>
11*0b57cec5SDimitry Andric #include <map>
12*0b57cec5SDimitry Andric #include <mutex>
13*0b57cec5SDimitry Andric 
14*0b57cec5SDimitry Andric #include "lldb/Target/Language.h"
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h"
17*0b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
18*0b57cec5SDimitry Andric #include "lldb/Symbol/TypeList.h"
19*0b57cec5SDimitry Andric #include "lldb/Target/Target.h"
20*0b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
21*0b57cec5SDimitry Andric 
22*0b57cec5SDimitry Andric #include "llvm/Support/Threading.h"
23*0b57cec5SDimitry Andric 
24*0b57cec5SDimitry Andric using namespace lldb;
25*0b57cec5SDimitry Andric using namespace lldb_private;
26*0b57cec5SDimitry Andric using namespace lldb_private::formatters;
27*0b57cec5SDimitry Andric 
28*0b57cec5SDimitry Andric typedef std::unique_ptr<Language> LanguageUP;
29*0b57cec5SDimitry Andric typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;
30*0b57cec5SDimitry Andric 
31*0b57cec5SDimitry Andric static LanguagesMap &GetLanguagesMap() {
32*0b57cec5SDimitry Andric   static LanguagesMap *g_map = nullptr;
33*0b57cec5SDimitry Andric   static llvm::once_flag g_initialize;
34*0b57cec5SDimitry Andric 
35*0b57cec5SDimitry Andric   llvm::call_once(g_initialize, [] {
36*0b57cec5SDimitry Andric     g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global
37*0b57cec5SDimitry Andric                                 // destructor chain
38*0b57cec5SDimitry Andric   });
39*0b57cec5SDimitry Andric 
40*0b57cec5SDimitry Andric   return *g_map;
41*0b57cec5SDimitry Andric }
42*0b57cec5SDimitry Andric static std::mutex &GetLanguagesMutex() {
43*0b57cec5SDimitry Andric   static std::mutex *g_mutex = nullptr;
44*0b57cec5SDimitry Andric   static llvm::once_flag g_initialize;
45*0b57cec5SDimitry Andric 
46*0b57cec5SDimitry Andric   llvm::call_once(g_initialize, [] {
47*0b57cec5SDimitry Andric     g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global
48*0b57cec5SDimitry Andric                                 // destructor chain
49*0b57cec5SDimitry Andric   });
50*0b57cec5SDimitry Andric 
51*0b57cec5SDimitry Andric   return *g_mutex;
52*0b57cec5SDimitry Andric }
53*0b57cec5SDimitry Andric 
54*0b57cec5SDimitry Andric Language *Language::FindPlugin(lldb::LanguageType language) {
55*0b57cec5SDimitry Andric   std::lock_guard<std::mutex> guard(GetLanguagesMutex());
56*0b57cec5SDimitry Andric   LanguagesMap &map(GetLanguagesMap());
57*0b57cec5SDimitry Andric   auto iter = map.find(language), end = map.end();
58*0b57cec5SDimitry Andric   if (iter != end)
59*0b57cec5SDimitry Andric     return iter->second.get();
60*0b57cec5SDimitry Andric 
61*0b57cec5SDimitry Andric   Language *language_ptr = nullptr;
62*0b57cec5SDimitry Andric   LanguageCreateInstance create_callback;
63*0b57cec5SDimitry Andric 
64*0b57cec5SDimitry Andric   for (uint32_t idx = 0;
65*0b57cec5SDimitry Andric        (create_callback =
66*0b57cec5SDimitry Andric             PluginManager::GetLanguageCreateCallbackAtIndex(idx)) != nullptr;
67*0b57cec5SDimitry Andric        ++idx) {
68*0b57cec5SDimitry Andric     language_ptr = create_callback(language);
69*0b57cec5SDimitry Andric 
70*0b57cec5SDimitry Andric     if (language_ptr) {
71*0b57cec5SDimitry Andric       map[language] = std::unique_ptr<Language>(language_ptr);
72*0b57cec5SDimitry Andric       return language_ptr;
73*0b57cec5SDimitry Andric     }
74*0b57cec5SDimitry Andric   }
75*0b57cec5SDimitry Andric 
76*0b57cec5SDimitry Andric   return nullptr;
77*0b57cec5SDimitry Andric }
78*0b57cec5SDimitry Andric 
79*0b57cec5SDimitry Andric Language *Language::FindPlugin(llvm::StringRef file_path) {
80*0b57cec5SDimitry Andric   Language *result = nullptr;
81*0b57cec5SDimitry Andric   ForEach([&result, file_path](Language *language) {
82*0b57cec5SDimitry Andric     if (language->IsSourceFile(file_path)) {
83*0b57cec5SDimitry Andric       result = language;
84*0b57cec5SDimitry Andric       return false;
85*0b57cec5SDimitry Andric     }
86*0b57cec5SDimitry Andric     return true;
87*0b57cec5SDimitry Andric   });
88*0b57cec5SDimitry Andric   return result;
89*0b57cec5SDimitry Andric }
90*0b57cec5SDimitry Andric 
91*0b57cec5SDimitry Andric Language *Language::FindPlugin(LanguageType language,
92*0b57cec5SDimitry Andric                                llvm::StringRef file_path) {
93*0b57cec5SDimitry Andric   Language *result = FindPlugin(language);
94*0b57cec5SDimitry Andric   // Finding a language by file path is slower, we so we use this as the
95*0b57cec5SDimitry Andric   // fallback.
96*0b57cec5SDimitry Andric   if (!result)
97*0b57cec5SDimitry Andric     result = FindPlugin(file_path);
98*0b57cec5SDimitry Andric   return result;
99*0b57cec5SDimitry Andric }
100*0b57cec5SDimitry Andric 
101*0b57cec5SDimitry Andric void Language::ForEach(std::function<bool(Language *)> callback) {
102*0b57cec5SDimitry Andric   // If we want to iterate over all languages, we first have to complete the
103*0b57cec5SDimitry Andric   // LanguagesMap.
104*0b57cec5SDimitry Andric   static llvm::once_flag g_initialize;
105*0b57cec5SDimitry Andric   llvm::call_once(g_initialize, [] {
106*0b57cec5SDimitry Andric     for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes;
107*0b57cec5SDimitry Andric          ++lang) {
108*0b57cec5SDimitry Andric       FindPlugin(static_cast<lldb::LanguageType>(lang));
109*0b57cec5SDimitry Andric     }
110*0b57cec5SDimitry Andric   });
111*0b57cec5SDimitry Andric 
112*0b57cec5SDimitry Andric   std::lock_guard<std::mutex> guard(GetLanguagesMutex());
113*0b57cec5SDimitry Andric   LanguagesMap &map(GetLanguagesMap());
114*0b57cec5SDimitry Andric   for (const auto &entry : map) {
115*0b57cec5SDimitry Andric     if (!callback(entry.second.get()))
116*0b57cec5SDimitry Andric       break;
117*0b57cec5SDimitry Andric   }
118*0b57cec5SDimitry Andric }
119*0b57cec5SDimitry Andric 
120*0b57cec5SDimitry Andric bool Language::IsTopLevelFunction(Function &function) { return false; }
121*0b57cec5SDimitry Andric 
122*0b57cec5SDimitry Andric lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; }
123*0b57cec5SDimitry Andric 
124*0b57cec5SDimitry Andric HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats() {
125*0b57cec5SDimitry Andric   return {};
126*0b57cec5SDimitry Andric }
127*0b57cec5SDimitry Andric 
128*0b57cec5SDimitry Andric HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries() {
129*0b57cec5SDimitry Andric   return {};
130*0b57cec5SDimitry Andric }
131*0b57cec5SDimitry Andric 
132*0b57cec5SDimitry Andric HardcodedFormatters::HardcodedSyntheticFinder
133*0b57cec5SDimitry Andric Language::GetHardcodedSynthetics() {
134*0b57cec5SDimitry Andric   return {};
135*0b57cec5SDimitry Andric }
136*0b57cec5SDimitry Andric 
137*0b57cec5SDimitry Andric HardcodedFormatters::HardcodedValidatorFinder
138*0b57cec5SDimitry Andric Language::GetHardcodedValidators() {
139*0b57cec5SDimitry Andric   return {};
140*0b57cec5SDimitry Andric }
141*0b57cec5SDimitry Andric 
142*0b57cec5SDimitry Andric std::vector<ConstString>
143*0b57cec5SDimitry Andric Language::GetPossibleFormattersMatches(ValueObject &valobj,
144*0b57cec5SDimitry Andric                                        lldb::DynamicValueType use_dynamic) {
145*0b57cec5SDimitry Andric   return {};
146*0b57cec5SDimitry Andric }
147*0b57cec5SDimitry Andric 
148*0b57cec5SDimitry Andric lldb_private::formatters::StringPrinter::EscapingHelper
149*0b57cec5SDimitry Andric Language::GetStringPrinterEscapingHelper(
150*0b57cec5SDimitry Andric     lldb_private::formatters::StringPrinter::GetPrintableElementType
151*0b57cec5SDimitry Andric         elem_type) {
152*0b57cec5SDimitry Andric   return StringPrinter::GetDefaultEscapingHelper(elem_type);
153*0b57cec5SDimitry Andric }
154*0b57cec5SDimitry Andric 
155*0b57cec5SDimitry Andric struct language_name_pair {
156*0b57cec5SDimitry Andric   const char *name;
157*0b57cec5SDimitry Andric   LanguageType type;
158*0b57cec5SDimitry Andric };
159*0b57cec5SDimitry Andric 
160*0b57cec5SDimitry Andric struct language_name_pair language_names[] = {
161*0b57cec5SDimitry Andric     // To allow GetNameForLanguageType to be a simple array lookup, the first
162*0b57cec5SDimitry Andric     // part of this array must follow enum LanguageType exactly.
163*0b57cec5SDimitry Andric     {"unknown", eLanguageTypeUnknown},
164*0b57cec5SDimitry Andric     {"c89", eLanguageTypeC89},
165*0b57cec5SDimitry Andric     {"c", eLanguageTypeC},
166*0b57cec5SDimitry Andric     {"ada83", eLanguageTypeAda83},
167*0b57cec5SDimitry Andric     {"c++", eLanguageTypeC_plus_plus},
168*0b57cec5SDimitry Andric     {"cobol74", eLanguageTypeCobol74},
169*0b57cec5SDimitry Andric     {"cobol85", eLanguageTypeCobol85},
170*0b57cec5SDimitry Andric     {"fortran77", eLanguageTypeFortran77},
171*0b57cec5SDimitry Andric     {"fortran90", eLanguageTypeFortran90},
172*0b57cec5SDimitry Andric     {"pascal83", eLanguageTypePascal83},
173*0b57cec5SDimitry Andric     {"modula2", eLanguageTypeModula2},
174*0b57cec5SDimitry Andric     {"java", eLanguageTypeJava},
175*0b57cec5SDimitry Andric     {"c99", eLanguageTypeC99},
176*0b57cec5SDimitry Andric     {"ada95", eLanguageTypeAda95},
177*0b57cec5SDimitry Andric     {"fortran95", eLanguageTypeFortran95},
178*0b57cec5SDimitry Andric     {"pli", eLanguageTypePLI},
179*0b57cec5SDimitry Andric     {"objective-c", eLanguageTypeObjC},
180*0b57cec5SDimitry Andric     {"objective-c++", eLanguageTypeObjC_plus_plus},
181*0b57cec5SDimitry Andric     {"upc", eLanguageTypeUPC},
182*0b57cec5SDimitry Andric     {"d", eLanguageTypeD},
183*0b57cec5SDimitry Andric     {"python", eLanguageTypePython},
184*0b57cec5SDimitry Andric     {"opencl", eLanguageTypeOpenCL},
185*0b57cec5SDimitry Andric     {"go", eLanguageTypeGo},
186*0b57cec5SDimitry Andric     {"modula3", eLanguageTypeModula3},
187*0b57cec5SDimitry Andric     {"haskell", eLanguageTypeHaskell},
188*0b57cec5SDimitry Andric     {"c++03", eLanguageTypeC_plus_plus_03},
189*0b57cec5SDimitry Andric     {"c++11", eLanguageTypeC_plus_plus_11},
190*0b57cec5SDimitry Andric     {"ocaml", eLanguageTypeOCaml},
191*0b57cec5SDimitry Andric     {"rust", eLanguageTypeRust},
192*0b57cec5SDimitry Andric     {"c11", eLanguageTypeC11},
193*0b57cec5SDimitry Andric     {"swift", eLanguageTypeSwift},
194*0b57cec5SDimitry Andric     {"julia", eLanguageTypeJulia},
195*0b57cec5SDimitry Andric     {"dylan", eLanguageTypeDylan},
196*0b57cec5SDimitry Andric     {"c++14", eLanguageTypeC_plus_plus_14},
197*0b57cec5SDimitry Andric     {"fortran03", eLanguageTypeFortran03},
198*0b57cec5SDimitry Andric     {"fortran08", eLanguageTypeFortran08},
199*0b57cec5SDimitry Andric     // Vendor Extensions
200*0b57cec5SDimitry Andric     {"mipsassem", eLanguageTypeMipsAssembler},
201*0b57cec5SDimitry Andric     {"renderscript", eLanguageTypeExtRenderScript},
202*0b57cec5SDimitry Andric     // Now synonyms, in arbitrary order
203*0b57cec5SDimitry Andric     {"objc", eLanguageTypeObjC},
204*0b57cec5SDimitry Andric     {"objc++", eLanguageTypeObjC_plus_plus},
205*0b57cec5SDimitry Andric     {"pascal", eLanguageTypePascal83}};
206*0b57cec5SDimitry Andric 
207*0b57cec5SDimitry Andric static uint32_t num_languages =
208*0b57cec5SDimitry Andric     sizeof(language_names) / sizeof(struct language_name_pair);
209*0b57cec5SDimitry Andric 
210*0b57cec5SDimitry Andric LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) {
211*0b57cec5SDimitry Andric   for (const auto &L : language_names) {
212*0b57cec5SDimitry Andric     if (string.equals_lower(L.name))
213*0b57cec5SDimitry Andric       return static_cast<LanguageType>(L.type);
214*0b57cec5SDimitry Andric   }
215*0b57cec5SDimitry Andric 
216*0b57cec5SDimitry Andric   return eLanguageTypeUnknown;
217*0b57cec5SDimitry Andric }
218*0b57cec5SDimitry Andric 
219*0b57cec5SDimitry Andric const char *Language::GetNameForLanguageType(LanguageType language) {
220*0b57cec5SDimitry Andric   if (language < num_languages)
221*0b57cec5SDimitry Andric     return language_names[language].name;
222*0b57cec5SDimitry Andric   else
223*0b57cec5SDimitry Andric     return language_names[eLanguageTypeUnknown].name;
224*0b57cec5SDimitry Andric }
225*0b57cec5SDimitry Andric 
226*0b57cec5SDimitry Andric void Language::PrintAllLanguages(Stream &s, const char *prefix,
227*0b57cec5SDimitry Andric                                  const char *suffix) {
228*0b57cec5SDimitry Andric   for (uint32_t i = 1; i < num_languages; i++) {
229*0b57cec5SDimitry Andric     s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
230*0b57cec5SDimitry Andric   }
231*0b57cec5SDimitry Andric }
232*0b57cec5SDimitry Andric 
233*0b57cec5SDimitry Andric void Language::ForAllLanguages(
234*0b57cec5SDimitry Andric     std::function<bool(lldb::LanguageType)> callback) {
235*0b57cec5SDimitry Andric   for (uint32_t i = 1; i < num_languages; i++) {
236*0b57cec5SDimitry Andric     if (!callback(language_names[i].type))
237*0b57cec5SDimitry Andric       break;
238*0b57cec5SDimitry Andric   }
239*0b57cec5SDimitry Andric }
240*0b57cec5SDimitry Andric 
241*0b57cec5SDimitry Andric bool Language::LanguageIsCPlusPlus(LanguageType language) {
242*0b57cec5SDimitry Andric   switch (language) {
243*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus:
244*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_03:
245*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_11:
246*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_14:
247*0b57cec5SDimitry Andric   case eLanguageTypeObjC_plus_plus:
248*0b57cec5SDimitry Andric     return true;
249*0b57cec5SDimitry Andric   default:
250*0b57cec5SDimitry Andric     return false;
251*0b57cec5SDimitry Andric   }
252*0b57cec5SDimitry Andric }
253*0b57cec5SDimitry Andric 
254*0b57cec5SDimitry Andric bool Language::LanguageIsObjC(LanguageType language) {
255*0b57cec5SDimitry Andric   switch (language) {
256*0b57cec5SDimitry Andric   case eLanguageTypeObjC:
257*0b57cec5SDimitry Andric   case eLanguageTypeObjC_plus_plus:
258*0b57cec5SDimitry Andric     return true;
259*0b57cec5SDimitry Andric   default:
260*0b57cec5SDimitry Andric     return false;
261*0b57cec5SDimitry Andric   }
262*0b57cec5SDimitry Andric }
263*0b57cec5SDimitry Andric 
264*0b57cec5SDimitry Andric bool Language::LanguageIsC(LanguageType language) {
265*0b57cec5SDimitry Andric   switch (language) {
266*0b57cec5SDimitry Andric   case eLanguageTypeC:
267*0b57cec5SDimitry Andric   case eLanguageTypeC89:
268*0b57cec5SDimitry Andric   case eLanguageTypeC99:
269*0b57cec5SDimitry Andric   case eLanguageTypeC11:
270*0b57cec5SDimitry Andric     return true;
271*0b57cec5SDimitry Andric   default:
272*0b57cec5SDimitry Andric     return false;
273*0b57cec5SDimitry Andric   }
274*0b57cec5SDimitry Andric }
275*0b57cec5SDimitry Andric 
276*0b57cec5SDimitry Andric bool Language::LanguageIsCFamily(LanguageType language) {
277*0b57cec5SDimitry Andric   switch (language) {
278*0b57cec5SDimitry Andric   case eLanguageTypeC:
279*0b57cec5SDimitry Andric   case eLanguageTypeC89:
280*0b57cec5SDimitry Andric   case eLanguageTypeC99:
281*0b57cec5SDimitry Andric   case eLanguageTypeC11:
282*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus:
283*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_03:
284*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_11:
285*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_14:
286*0b57cec5SDimitry Andric   case eLanguageTypeObjC_plus_plus:
287*0b57cec5SDimitry Andric   case eLanguageTypeObjC:
288*0b57cec5SDimitry Andric     return true;
289*0b57cec5SDimitry Andric   default:
290*0b57cec5SDimitry Andric     return false;
291*0b57cec5SDimitry Andric   }
292*0b57cec5SDimitry Andric }
293*0b57cec5SDimitry Andric 
294*0b57cec5SDimitry Andric bool Language::LanguageIsPascal(LanguageType language) {
295*0b57cec5SDimitry Andric   switch (language) {
296*0b57cec5SDimitry Andric   case eLanguageTypePascal83:
297*0b57cec5SDimitry Andric     return true;
298*0b57cec5SDimitry Andric   default:
299*0b57cec5SDimitry Andric     return false;
300*0b57cec5SDimitry Andric   }
301*0b57cec5SDimitry Andric }
302*0b57cec5SDimitry Andric 
303*0b57cec5SDimitry Andric LanguageType Language::GetPrimaryLanguage(LanguageType language) {
304*0b57cec5SDimitry Andric   switch (language) {
305*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus:
306*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_03:
307*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_11:
308*0b57cec5SDimitry Andric   case eLanguageTypeC_plus_plus_14:
309*0b57cec5SDimitry Andric     return eLanguageTypeC_plus_plus;
310*0b57cec5SDimitry Andric   case eLanguageTypeC:
311*0b57cec5SDimitry Andric   case eLanguageTypeC89:
312*0b57cec5SDimitry Andric   case eLanguageTypeC99:
313*0b57cec5SDimitry Andric   case eLanguageTypeC11:
314*0b57cec5SDimitry Andric     return eLanguageTypeC;
315*0b57cec5SDimitry Andric   case eLanguageTypeObjC:
316*0b57cec5SDimitry Andric   case eLanguageTypeObjC_plus_plus:
317*0b57cec5SDimitry Andric     return eLanguageTypeObjC;
318*0b57cec5SDimitry Andric   case eLanguageTypePascal83:
319*0b57cec5SDimitry Andric   case eLanguageTypeCobol74:
320*0b57cec5SDimitry Andric   case eLanguageTypeCobol85:
321*0b57cec5SDimitry Andric   case eLanguageTypeFortran77:
322*0b57cec5SDimitry Andric   case eLanguageTypeFortran90:
323*0b57cec5SDimitry Andric   case eLanguageTypeFortran95:
324*0b57cec5SDimitry Andric   case eLanguageTypeFortran03:
325*0b57cec5SDimitry Andric   case eLanguageTypeFortran08:
326*0b57cec5SDimitry Andric   case eLanguageTypeAda83:
327*0b57cec5SDimitry Andric   case eLanguageTypeAda95:
328*0b57cec5SDimitry Andric   case eLanguageTypeModula2:
329*0b57cec5SDimitry Andric   case eLanguageTypeJava:
330*0b57cec5SDimitry Andric   case eLanguageTypePLI:
331*0b57cec5SDimitry Andric   case eLanguageTypeUPC:
332*0b57cec5SDimitry Andric   case eLanguageTypeD:
333*0b57cec5SDimitry Andric   case eLanguageTypePython:
334*0b57cec5SDimitry Andric   case eLanguageTypeOpenCL:
335*0b57cec5SDimitry Andric   case eLanguageTypeGo:
336*0b57cec5SDimitry Andric   case eLanguageTypeModula3:
337*0b57cec5SDimitry Andric   case eLanguageTypeHaskell:
338*0b57cec5SDimitry Andric   case eLanguageTypeOCaml:
339*0b57cec5SDimitry Andric   case eLanguageTypeRust:
340*0b57cec5SDimitry Andric   case eLanguageTypeSwift:
341*0b57cec5SDimitry Andric   case eLanguageTypeJulia:
342*0b57cec5SDimitry Andric   case eLanguageTypeDylan:
343*0b57cec5SDimitry Andric   case eLanguageTypeMipsAssembler:
344*0b57cec5SDimitry Andric   case eLanguageTypeExtRenderScript:
345*0b57cec5SDimitry Andric   case eLanguageTypeUnknown:
346*0b57cec5SDimitry Andric   default:
347*0b57cec5SDimitry Andric     return language;
348*0b57cec5SDimitry Andric   }
349*0b57cec5SDimitry Andric }
350*0b57cec5SDimitry Andric 
351*0b57cec5SDimitry Andric std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
352*0b57cec5SDimitry Andric   std::set<lldb::LanguageType> supported_languages;
353*0b57cec5SDimitry Andric   ForEach([&](Language *lang) {
354*0b57cec5SDimitry Andric     supported_languages.emplace(lang->GetLanguageType());
355*0b57cec5SDimitry Andric     return true;
356*0b57cec5SDimitry Andric   });
357*0b57cec5SDimitry Andric   return supported_languages;
358*0b57cec5SDimitry Andric }
359*0b57cec5SDimitry Andric 
360*0b57cec5SDimitry Andric void Language::GetLanguagesSupportingTypeSystems(
361*0b57cec5SDimitry Andric     std::set<lldb::LanguageType> &languages,
362*0b57cec5SDimitry Andric     std::set<lldb::LanguageType> &languages_for_expressions) {
363*0b57cec5SDimitry Andric   uint32_t idx = 0;
364*0b57cec5SDimitry Andric 
365*0b57cec5SDimitry Andric   while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager::
366*0b57cec5SDimitry Andric              GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++)) {
367*0b57cec5SDimitry Andric     (*enumerate)(languages, languages_for_expressions);
368*0b57cec5SDimitry Andric   }
369*0b57cec5SDimitry Andric }
370*0b57cec5SDimitry Andric 
371*0b57cec5SDimitry Andric void Language::GetLanguagesSupportingREPLs(
372*0b57cec5SDimitry Andric     std::set<lldb::LanguageType> &languages) {
373*0b57cec5SDimitry Andric   uint32_t idx = 0;
374*0b57cec5SDimitry Andric 
375*0b57cec5SDimitry Andric   while (REPLEnumerateSupportedLanguages enumerate =
376*0b57cec5SDimitry Andric              PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(
377*0b57cec5SDimitry Andric                  idx++)) {
378*0b57cec5SDimitry Andric     (*enumerate)(languages);
379*0b57cec5SDimitry Andric   }
380*0b57cec5SDimitry Andric }
381*0b57cec5SDimitry Andric 
382*0b57cec5SDimitry Andric std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
383*0b57cec5SDimitry Andric   return nullptr;
384*0b57cec5SDimitry Andric }
385*0b57cec5SDimitry Andric 
386*0b57cec5SDimitry Andric const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
387*0b57cec5SDimitry Andric 
388*0b57cec5SDimitry Andric size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope,
389*0b57cec5SDimitry Andric                                      const char *key, ResultSet &results,
390*0b57cec5SDimitry Andric                                      bool append) {
391*0b57cec5SDimitry Andric   if (!exe_scope || !exe_scope->CalculateTarget().get())
392*0b57cec5SDimitry Andric     return false;
393*0b57cec5SDimitry Andric 
394*0b57cec5SDimitry Andric   if (!key || !key[0])
395*0b57cec5SDimitry Andric     return false;
396*0b57cec5SDimitry Andric 
397*0b57cec5SDimitry Andric   if (!append)
398*0b57cec5SDimitry Andric     results.clear();
399*0b57cec5SDimitry Andric 
400*0b57cec5SDimitry Andric   size_t old_size = results.size();
401*0b57cec5SDimitry Andric 
402*0b57cec5SDimitry Andric   if (this->Find_Impl(exe_scope, key, results))
403*0b57cec5SDimitry Andric     return results.size() - old_size;
404*0b57cec5SDimitry Andric   return 0;
405*0b57cec5SDimitry Andric }
406*0b57cec5SDimitry Andric 
407*0b57cec5SDimitry Andric bool Language::ImageListTypeScavenger::Find_Impl(
408*0b57cec5SDimitry Andric     ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
409*0b57cec5SDimitry Andric   bool result = false;
410*0b57cec5SDimitry Andric 
411*0b57cec5SDimitry Andric   Target *target = exe_scope->CalculateTarget().get();
412*0b57cec5SDimitry Andric   if (target) {
413*0b57cec5SDimitry Andric     const auto &images(target->GetImages());
414*0b57cec5SDimitry Andric     ConstString cs_key(key);
415*0b57cec5SDimitry Andric     llvm::DenseSet<SymbolFile *> searched_sym_files;
416*0b57cec5SDimitry Andric     TypeList matches;
417*0b57cec5SDimitry Andric     images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files,
418*0b57cec5SDimitry Andric                      matches);
419*0b57cec5SDimitry Andric     for (const auto &match : matches.Types()) {
420*0b57cec5SDimitry Andric       if (match) {
421*0b57cec5SDimitry Andric         CompilerType compiler_type(match->GetFullCompilerType());
422*0b57cec5SDimitry Andric         compiler_type = AdjustForInclusion(compiler_type);
423*0b57cec5SDimitry Andric         if (!compiler_type)
424*0b57cec5SDimitry Andric           continue;
425*0b57cec5SDimitry Andric         std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
426*0b57cec5SDimitry Andric             new Result(compiler_type));
427*0b57cec5SDimitry Andric         results.insert(std::move(scavengeresult));
428*0b57cec5SDimitry Andric         result = true;
429*0b57cec5SDimitry Andric       }
430*0b57cec5SDimitry Andric     }
431*0b57cec5SDimitry Andric   }
432*0b57cec5SDimitry Andric 
433*0b57cec5SDimitry Andric   return result;
434*0b57cec5SDimitry Andric }
435*0b57cec5SDimitry Andric 
436*0b57cec5SDimitry Andric bool Language::GetFormatterPrefixSuffix(ValueObject &valobj,
437*0b57cec5SDimitry Andric                                         ConstString type_hint,
438*0b57cec5SDimitry Andric                                         std::string &prefix,
439*0b57cec5SDimitry Andric                                         std::string &suffix) {
440*0b57cec5SDimitry Andric   return false;
441*0b57cec5SDimitry Andric }
442*0b57cec5SDimitry Andric 
443*0b57cec5SDimitry Andric DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() {
444*0b57cec5SDimitry Andric   return nullptr;
445*0b57cec5SDimitry Andric }
446*0b57cec5SDimitry Andric 
447*0b57cec5SDimitry Andric LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) {
448*0b57cec5SDimitry Andric   return eLazyBoolCalculate;
449*0b57cec5SDimitry Andric }
450*0b57cec5SDimitry Andric 
451*0b57cec5SDimitry Andric bool Language::IsNilReference(ValueObject &valobj) { return false; }
452*0b57cec5SDimitry Andric 
453*0b57cec5SDimitry Andric bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
454*0b57cec5SDimitry Andric 
455*0b57cec5SDimitry Andric bool Language::GetFunctionDisplayName(const SymbolContext *sc,
456*0b57cec5SDimitry Andric                                       const ExecutionContext *exe_ctx,
457*0b57cec5SDimitry Andric                                       FunctionNameRepresentation representation,
458*0b57cec5SDimitry Andric                                       Stream &s) {
459*0b57cec5SDimitry Andric   return false;
460*0b57cec5SDimitry Andric }
461*0b57cec5SDimitry Andric 
462*0b57cec5SDimitry Andric void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
463*0b57cec5SDimitry Andric                                                Stream &s) {
464*0b57cec5SDimitry Andric   GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
465*0b57cec5SDimitry Andric }
466*0b57cec5SDimitry Andric 
467*0b57cec5SDimitry Andric void Language::GetDefaultExceptionResolverDescription(bool catch_on,
468*0b57cec5SDimitry Andric                                                       bool throw_on,
469*0b57cec5SDimitry Andric                                                       Stream &s) {
470*0b57cec5SDimitry Andric   s.Printf("Exception breakpoint (catch: %s throw: %s)",
471*0b57cec5SDimitry Andric            catch_on ? "on" : "off", throw_on ? "on" : "off");
472*0b57cec5SDimitry Andric }
473*0b57cec5SDimitry Andric // Constructor
474*0b57cec5SDimitry Andric Language::Language() {}
475*0b57cec5SDimitry Andric 
476*0b57cec5SDimitry Andric // Destructor
477*0b57cec5SDimitry Andric Language::~Language() {}
478