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