LLDB  mainline
Language.cpp
Go to the documentation of this file.
1 //===-- Language.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <functional>
10 #include <map>
11 #include <mutex>
12 
13 #include "lldb/Target/Language.h"
14 
16 #include "lldb/Symbol/SymbolFile.h"
17 #include "lldb/Symbol/TypeList.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Utility/Stream.h"
20 
21 #include "llvm/Support/Threading.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 
31  static LanguagesMap *g_map = nullptr;
32  static llvm::once_flag g_initialize;
33 
34  llvm::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 llvm::once_flag g_initialize;
44 
45  llvm::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());
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 Language *Language::FindPlugin(llvm::StringRef file_path) {
79  Language *result = nullptr;
80  ForEach([&result, file_path](Language *language) {
81  if (language->IsSourceFile(file_path)) {
82  result = language;
83  return false;
84  }
85  return true;
86  });
87  return result;
88 }
89 
90 Language *Language::FindPlugin(LanguageType language,
91  llvm::StringRef file_path) {
92  Language *result = FindPlugin(language);
93  // Finding a language by file path is slower, we so we use this as the
94  // fallback.
95  if (!result)
96  result = FindPlugin(file_path);
97  return result;
98 }
99 
100 void Language::ForEach(std::function<bool(Language *)> callback) {
101  // If we want to iterate over all languages, we first have to complete the
102  // LanguagesMap.
103  static llvm::once_flag g_initialize;
104  llvm::call_once(g_initialize, [] {
105  for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes;
106  ++lang) {
107  FindPlugin(static_cast<lldb::LanguageType>(lang));
108  }
109  });
110 
111  std::lock_guard<std::mutex> guard(GetLanguagesMutex());
113  for (const auto &entry : map) {
114  if (!callback(entry.second.get()))
115  break;
116  }
117 }
118 
119 bool Language::IsTopLevelFunction(Function &function) { return false; }
120 
121 lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; }
122 
123 HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats() {
124  return {};
125 }
126 
127 HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries() {
128  return {};
129 }
130 
132 Language::GetHardcodedSynthetics() {
133  return {};
134 }
135 
136 std::vector<ConstString>
137 Language::GetPossibleFormattersMatches(ValueObject &valobj,
138  lldb::DynamicValueType use_dynamic) {
139  return {};
140 }
141 
143  const char *name;
145 };
146 
148  // To allow GetNameForLanguageType to be a simple array lookup, the first
149  // part of this array must follow enum LanguageType exactly.
150  {"unknown", eLanguageTypeUnknown},
151  {"c89", eLanguageTypeC89},
152  {"c", eLanguageTypeC},
153  {"ada83", eLanguageTypeAda83},
154  {"c++", eLanguageTypeC_plus_plus},
155  {"cobol74", eLanguageTypeCobol74},
156  {"cobol85", eLanguageTypeCobol85},
157  {"fortran77", eLanguageTypeFortran77},
158  {"fortran90", eLanguageTypeFortran90},
159  {"pascal83", eLanguageTypePascal83},
160  {"modula2", eLanguageTypeModula2},
161  {"java", eLanguageTypeJava},
162  {"c99", eLanguageTypeC99},
163  {"ada95", eLanguageTypeAda95},
164  {"fortran95", eLanguageTypeFortran95},
165  {"pli", eLanguageTypePLI},
166  {"objective-c", eLanguageTypeObjC},
167  {"objective-c++", eLanguageTypeObjC_plus_plus},
168  {"upc", eLanguageTypeUPC},
169  {"d", eLanguageTypeD},
170  {"python", eLanguageTypePython},
171  {"opencl", eLanguageTypeOpenCL},
172  {"go", eLanguageTypeGo},
173  {"modula3", eLanguageTypeModula3},
174  {"haskell", eLanguageTypeHaskell},
175  {"c++03", eLanguageTypeC_plus_plus_03},
176  {"c++11", eLanguageTypeC_plus_plus_11},
177  {"ocaml", eLanguageTypeOCaml},
178  {"rust", eLanguageTypeRust},
179  {"c11", eLanguageTypeC11},
180  {"swift", eLanguageTypeSwift},
181  {"julia", eLanguageTypeJulia},
182  {"dylan", eLanguageTypeDylan},
183  {"c++14", eLanguageTypeC_plus_plus_14},
184  {"fortran03", eLanguageTypeFortran03},
185  {"fortran08", eLanguageTypeFortran08},
186  // Vendor Extensions
187  {"mipsassem", eLanguageTypeMipsAssembler},
188  {"renderscript", eLanguageTypeExtRenderScript},
189  // Now synonyms, in arbitrary order
190  {"objc", eLanguageTypeObjC},
191  {"objc++", eLanguageTypeObjC_plus_plus},
192  {"pascal", eLanguageTypePascal83}};
193 
195  sizeof(language_names) / sizeof(struct language_name_pair);
196 
197 LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) {
198  for (const auto &L : language_names) {
199  if (string.equals_lower(L.name))
200  return static_cast<LanguageType>(L.type);
201  }
202 
203  return eLanguageTypeUnknown;
204 }
205 
206 const char *Language::GetNameForLanguageType(LanguageType language) {
207  if (language < num_languages)
208  return language_names[language].name;
209  else
210  return language_names[eLanguageTypeUnknown].name;
211 }
212 
213 void Language::PrintAllLanguages(Stream &s, const char *prefix,
214  const char *suffix) {
215  for (uint32_t i = 1; i < num_languages; i++) {
216  s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
217  }
218 }
219 
220 void Language::ForAllLanguages(
221  std::function<bool(lldb::LanguageType)> callback) {
222  for (uint32_t i = 1; i < num_languages; i++) {
223  if (!callback(language_names[i].type))
224  break;
225  }
226 }
227 
228 bool Language::LanguageIsCPlusPlus(LanguageType language) {
229  switch (language) {
235  return true;
236  default:
237  return false;
238  }
239 }
240 
241 bool Language::LanguageIsObjC(LanguageType language) {
242  switch (language) {
243  case eLanguageTypeObjC:
245  return true;
246  default:
247  return false;
248  }
249 }
250 
251 bool Language::LanguageIsC(LanguageType language) {
252  switch (language) {
253  case eLanguageTypeC:
254  case eLanguageTypeC89:
255  case eLanguageTypeC99:
256  case eLanguageTypeC11:
257  return true;
258  default:
259  return false;
260  }
261 }
262 
263 bool Language::LanguageIsCFamily(LanguageType language) {
264  switch (language) {
265  case eLanguageTypeC:
266  case eLanguageTypeC89:
267  case eLanguageTypeC99:
268  case eLanguageTypeC11:
274  case eLanguageTypeObjC:
275  return true;
276  default:
277  return false;
278  }
279 }
280 
281 bool Language::LanguageIsPascal(LanguageType language) {
282  switch (language) {
284  return true;
285  default:
286  return false;
287  }
288 }
289 
290 LanguageType Language::GetPrimaryLanguage(LanguageType language) {
291  switch (language) {
297  case eLanguageTypeC:
298  case eLanguageTypeC89:
299  case eLanguageTypeC99:
300  case eLanguageTypeC11:
301  return eLanguageTypeC;
302  case eLanguageTypeObjC:
304  return eLanguageTypeObjC;
313  case eLanguageTypeAda83:
314  case eLanguageTypeAda95:
316  case eLanguageTypeJava:
317  case eLanguageTypePLI:
318  case eLanguageTypeUPC:
319  case eLanguageTypeD:
320  case eLanguageTypePython:
321  case eLanguageTypeOpenCL:
322  case eLanguageTypeGo:
325  case eLanguageTypeOCaml:
326  case eLanguageTypeRust:
327  case eLanguageTypeSwift:
328  case eLanguageTypeJulia:
329  case eLanguageTypeDylan:
333  default:
334  return language;
335  }
336 }
337 
338 std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
339  std::set<lldb::LanguageType> supported_languages;
340  ForEach([&](Language *lang) {
341  supported_languages.emplace(lang->GetLanguageType());
342  return true;
343  });
344  return supported_languages;
345 }
346 
347 LanguageSet Language::GetLanguagesSupportingTypeSystems() {
348  return PluginManager::GetAllTypeSystemSupportedLanguagesForTypes();
349 }
350 
351 LanguageSet Language::GetLanguagesSupportingTypeSystemsForExpressions() {
352  return PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions();
353 }
354 
355 LanguageSet Language::GetLanguagesSupportingREPLs() {
356  return PluginManager::GetREPLAllTypeSystemSupportedLanguages();
357 }
358 
359 std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
360  return nullptr;
361 }
362 
363 const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
364 
365 size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope,
366  const char *key, ResultSet &results,
367  bool append) {
368  if (!exe_scope || !exe_scope->CalculateTarget().get())
369  return false;
370 
371  if (!key || !key[0])
372  return false;
373 
374  if (!append)
375  results.clear();
376 
377  size_t old_size = results.size();
378 
379  if (this->Find_Impl(exe_scope, key, results))
380  return results.size() - old_size;
381  return 0;
382 }
383 
384 bool Language::ImageListTypeScavenger::Find_Impl(
385  ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
386  bool result = false;
387 
388  Target *target = exe_scope->CalculateTarget().get();
389  if (target) {
390  const auto &images(target->GetImages());
391  ConstString cs_key(key);
392  llvm::DenseSet<SymbolFile *> searched_sym_files;
393  TypeList matches;
394  images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files,
395  matches);
396  for (const auto &match : matches.Types()) {
397  if (match) {
398  CompilerType compiler_type(match->GetFullCompilerType());
399  compiler_type = AdjustForInclusion(compiler_type);
400  if (!compiler_type)
401  continue;
402  std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
403  new Result(compiler_type));
404  results.insert(std::move(scavengeresult));
405  result = true;
406  }
407  }
408  }
409 
410  return result;
411 }
412 
413 bool Language::GetFormatterPrefixSuffix(ValueObject &valobj,
414  ConstString type_hint,
415  std::string &prefix,
416  std::string &suffix) {
417  return false;
418 }
419 
420 DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() {
421  return nullptr;
422 }
423 
424 LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) {
425  return eLazyBoolCalculate;
426 }
427 
428 bool Language::IsNilReference(ValueObject &valobj) { return false; }
429 
430 bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
431 
432 bool Language::GetFunctionDisplayName(const SymbolContext *sc,
433  const ExecutionContext *exe_ctx,
434  FunctionNameRepresentation representation,
435  Stream &s) {
436  return false;
437 }
438 
439 void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
440  Stream &s) {
441  GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
442 }
443 
444 void Language::GetDefaultExceptionResolverDescription(bool catch_on,
445  bool throw_on,
446  Stream &s) {
447  s.Printf("Exception breakpoint (catch: %s throw: %s)",
448  catch_on ? "on" : "off", throw_on ? "on" : "off");
449 }
450 // Constructor
451 Language::Language() {}
452 
453 // Destructor
454 Language::~Language() {}
A class that represents a running process on the host machine.
std::unique_ptr< Language > LanguageUP
Definition: Language.cpp:27
HardcodedFormatterFinders< SyntheticChildren > HardcodedSyntheticFinder
Definition: FormatClasses.h:41
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:409
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition: TypeSystem.h:40
std::map< lldb::LanguageType, LanguageUP > LanguagesMap
Definition: Language.cpp:28
Unified Parallel C.
static std::mutex & GetLanguagesMutex()
Definition: Language.cpp:41
HardcodedFormatterFinders< TypeFormatImpl > HardcodedFormatFinder
Definition: FormatClasses.h:39
HardcodedFormatterFinders< TypeSummaryImpl > HardcodedSummaryFinder
Definition: FormatClasses.h:40
virtual lldb::TargetSP CalculateTarget()=0
static LanguagesMap & GetLanguagesMap()
Definition: Language.cpp:30
virtual lldb::LanguageType GetLanguageType() const =0
#define UINT32_MAX
Definition: lldb-defines.h:31
LanguageType
Programming language type.
static llvm::raw_ostream & error(Stream &strm)
"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:107
const char * name
Definition: Language.cpp:143
TypeList FindTypes(ConstString name)
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:900
struct language_name_pair language_names[]
Definition: Language.cpp:147
std::set< std::unique_ptr< Result > > ResultSet
Definition: Language.h:43
A uniqued constant string class.
Definition: ConstString.h:40
Unknown or invalid language value.
Non-standardized C, such as K&R.
Definition: SBAddress.h:15
Represents a generic type in a programming language.
Definition: CompilerType.h:33
TypeIterable Types()
Definition: TypeList.h:45
std::function< bool(ConstString, ConstString, const DumpValueObjectOptions &, Stream &)> DeclPrintingHelper
static uint32_t num_languages
Definition: Language.cpp:194
LanguageType type
Definition: Language.cpp:144
An error handling class.
Definition: Status.h:44