LLDB  mainline
Language.cpp
Go to the documentation of this file.
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 
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 
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());
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());
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 
133 Language::GetHardcodedSynthetics() {
134  return {};
135 }
136 
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 
149 Language::GetStringPrinterEscapingHelper(
151  elem_type) {
152  return StringPrinter::GetDefaultEscapingHelper(elem_type);
153 }
154 
156  const char *name;
158 };
159 
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 
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) {
248  return true;
249  default:
250  return false;
251  }
252 }
253 
254 bool Language::LanguageIsObjC(LanguageType language) {
255  switch (language) {
256  case eLanguageTypeObjC:
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::LanguageIsPascal(LanguageType language) {
277  switch (language) {
279  return true;
280  default:
281  return false;
282  }
283 }
284 
285 LanguageType Language::GetPrimaryLanguage(LanguageType language) {
286  switch (language) {
292  case eLanguageTypeC:
293  case eLanguageTypeC89:
294  case eLanguageTypeC99:
295  case eLanguageTypeC11:
296  return eLanguageTypeC;
297  case eLanguageTypeObjC:
299  return eLanguageTypeObjC;
308  case eLanguageTypeAda83:
309  case eLanguageTypeAda95:
311  case eLanguageTypeJava:
312  case eLanguageTypePLI:
313  case eLanguageTypeUPC:
314  case eLanguageTypeD:
315  case eLanguageTypePython:
316  case eLanguageTypeOpenCL:
317  case eLanguageTypeGo:
320  case eLanguageTypeOCaml:
321  case eLanguageTypeRust:
322  case eLanguageTypeSwift:
323  case eLanguageTypeJulia:
324  case eLanguageTypeDylan:
328  default:
329  return language;
330  }
331 }
332 
333 void Language::GetLanguagesSupportingTypeSystems(
334  std::set<lldb::LanguageType> &languages,
335  std::set<lldb::LanguageType> &languages_for_expressions) {
336  uint32_t idx = 0;
337 
338  while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager::
339  GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++)) {
340  (*enumerate)(languages, languages_for_expressions);
341  }
342 }
343 
344 void Language::GetLanguagesSupportingREPLs(
345  std::set<lldb::LanguageType> &languages) {
346  uint32_t idx = 0;
347 
348  while (REPLEnumerateSupportedLanguages enumerate =
349  PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(
350  idx++)) {
351  (*enumerate)(languages);
352  }
353 }
354 
355 std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
356  return nullptr;
357 }
358 
359 const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
360 
361 size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope,
362  const char *key, ResultSet &results,
363  bool append) {
364  if (!exe_scope || !exe_scope->CalculateTarget().get())
365  return false;
366 
367  if (!key || !key[0])
368  return false;
369 
370  if (!append)
371  results.clear();
372 
373  size_t old_size = results.size();
374 
375  if (this->Find_Impl(exe_scope, key, results))
376  return results.size() - old_size;
377  return 0;
378 }
379 
380 bool Language::ImageListTypeScavenger::Find_Impl(
381  ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
382  bool result = false;
383 
384  Target *target = exe_scope->CalculateTarget().get();
385  if (target) {
386  const auto &images(target->GetImages());
387  ConstString cs_key(key);
388  llvm::DenseSet<SymbolFile *> searched_sym_files;
389  TypeList matches;
390  images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files,
391  matches);
392  for (const auto &match : matches.Types()) {
393  if (match) {
394  CompilerType compiler_type(match->GetFullCompilerType());
395  compiler_type = AdjustForInclusion(compiler_type);
396  if (!compiler_type)
397  continue;
398  std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
399  new Result(compiler_type));
400  results.insert(std::move(scavengeresult));
401  result = true;
402  }
403  }
404  }
405 
406  return result;
407 }
408 
409 bool Language::GetFormatterPrefixSuffix(ValueObject &valobj,
410  ConstString type_hint,
411  std::string &prefix,
412  std::string &suffix) {
413  return false;
414 }
415 
416 DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() {
417  return nullptr;
418 }
419 
420 LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) {
421  return eLazyBoolCalculate;
422 }
423 
424 bool Language::IsNilReference(ValueObject &valobj) { return false; }
425 
426 bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
427 
428 bool Language::GetFunctionDisplayName(const SymbolContext *sc,
429  const ExecutionContext *exe_ctx,
430  FunctionNameRepresentation representation,
431  Stream &s) {
432  return false;
433 }
434 
435 void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
436  Stream &s) {
437  GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
438 }
439 
440 void Language::GetDefaultExceptionResolverDescription(bool catch_on,
441  bool throw_on,
442  Stream &s) {
443  s.Printf("Exception breakpoint (catch: %s throw: %s)",
444  catch_on ? "on" : "off", throw_on ? "on" : "off");
445 }
446 // Constructor
447 Language::Language() {}
448 
449 // Destructor
450 Language::~Language() {}
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
std::unique_ptr< Language > LanguageUP
Definition: Language.cpp:28
HardcodedFormatterFinders< SyntheticChildren > HardcodedSyntheticFinder
Definition: FormatClasses.h:42
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
virtual bool IsSourceFile(llvm::StringRef file_path) const =0
A class that describes a function.
Definition: Function.h:323
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
std::map< lldb::LanguageType, LanguageUP > LanguagesMap
Definition: Language.cpp:29
Unified Parallel C.
static std::mutex & GetLanguagesMutex()
Definition: Language.cpp:42
HardcodedFormatterFinders< TypeFormatImpl > HardcodedFormatFinder
Definition: FormatClasses.h:40
HardcodedFormatterFinders< TypeSummaryImpl > HardcodedSummaryFinder
Definition: FormatClasses.h:41
virtual lldb::TargetSP CalculateTarget()=0
static LanguagesMap & GetLanguagesMap()
Definition: Language.cpp:31
#define UINT32_MAX
Definition: lldb-defines.h:31
LanguageType
Programming language type.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
const char * name
Definition: Language.cpp:156
TypeList FindTypes(ConstString name)
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:899
struct language_name_pair language_names[]
Definition: Language.cpp:160
std::set< std::unique_ptr< Result > > ResultSet
Definition: Language.h:42
A uniqued constant string class.
Definition: ConstString.h:38
std::function< StringPrinter::StringPrinterBufferPointer< uint8_t, char, size_t >uint8_t *, uint8_t *, uint8_t *&)> EscapingHelper
Unknown or invalid language value.
Non-standardized C, such as K&R.
Definition: SBAddress.h:15
TypeIterable Types()
Definition: TypeList.h:46
HardcodedFormatterFinders< TypeValidatorImpl > HardcodedValidatorFinder
Definition: FormatClasses.h:43
std::function< bool(ConstString, ConstString, const DumpValueObjectOptions &, Stream &)> DeclPrintingHelper
static uint32_t num_languages
Definition: Language.cpp:207
LanguageType type
Definition: Language.cpp:157
An error handling class.
Definition: Status.h:44