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