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  // callback may call a method in Language that attempts to acquire the same
112  // lock (such as Language::ForEach or Language::FindPlugin). To avoid a
113  // deadlock, we do not use callback while holding the lock.
114  std::vector<Language *> loaded_plugins;
115  {
116  std::lock_guard<std::mutex> guard(GetLanguagesMutex());
118  for (const auto &entry : map) {
119  if (entry.second)
120  loaded_plugins.push_back(entry.second.get());
121  }
122  }
123 
124  for (auto *lang : loaded_plugins) {
125  if (!callback(lang))
126  break;
127  }
128 }
129 
130 bool Language::IsTopLevelFunction(Function &function) { return false; }
131 
132 lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; }
133 
134 HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats() {
135  return {};
136 }
137 
138 HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries() {
139  return {};
140 }
141 
143 Language::GetHardcodedSynthetics() {
144  return {};
145 }
146 
147 std::vector<ConstString>
148 Language::GetPossibleFormattersMatches(ValueObject &valobj,
149  lldb::DynamicValueType use_dynamic) {
150  return {};
151 }
152 
154  const char *name;
156 };
157 
159  // To allow GetNameForLanguageType to be a simple array lookup, the first
160  // part of this array must follow enum LanguageType exactly.
161  {"unknown", eLanguageTypeUnknown},
162  {"c89", eLanguageTypeC89},
163  {"c", eLanguageTypeC},
164  {"ada83", eLanguageTypeAda83},
165  {"c++", eLanguageTypeC_plus_plus},
166  {"cobol74", eLanguageTypeCobol74},
167  {"cobol85", eLanguageTypeCobol85},
168  {"fortran77", eLanguageTypeFortran77},
169  {"fortran90", eLanguageTypeFortran90},
170  {"pascal83", eLanguageTypePascal83},
171  {"modula2", eLanguageTypeModula2},
172  {"java", eLanguageTypeJava},
173  {"c99", eLanguageTypeC99},
174  {"ada95", eLanguageTypeAda95},
175  {"fortran95", eLanguageTypeFortran95},
176  {"pli", eLanguageTypePLI},
177  {"objective-c", eLanguageTypeObjC},
178  {"objective-c++", eLanguageTypeObjC_plus_plus},
179  {"upc", eLanguageTypeUPC},
180  {"d", eLanguageTypeD},
181  {"python", eLanguageTypePython},
182  {"opencl", eLanguageTypeOpenCL},
183  {"go", eLanguageTypeGo},
184  {"modula3", eLanguageTypeModula3},
185  {"haskell", eLanguageTypeHaskell},
186  {"c++03", eLanguageTypeC_plus_plus_03},
187  {"c++11", eLanguageTypeC_plus_plus_11},
188  {"ocaml", eLanguageTypeOCaml},
189  {"rust", eLanguageTypeRust},
190  {"c11", eLanguageTypeC11},
191  {"swift", eLanguageTypeSwift},
192  {"julia", eLanguageTypeJulia},
193  {"dylan", eLanguageTypeDylan},
194  {"c++14", eLanguageTypeC_plus_plus_14},
195  {"fortran03", eLanguageTypeFortran03},
196  {"fortran08", eLanguageTypeFortran08},
197  // Vendor Extensions
198  {"assembler", eLanguageTypeMipsAssembler},
199  {"renderscript", eLanguageTypeExtRenderScript},
200  // Now synonyms, in arbitrary order
201  {"objc", eLanguageTypeObjC},
202  {"objc++", eLanguageTypeObjC_plus_plus},
203  {"pascal", eLanguageTypePascal83}};
204 
206  sizeof(language_names) / sizeof(struct language_name_pair);
207 
208 LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) {
209  for (const auto &L : language_names) {
210  if (string.equals_insensitive(L.name))
211  return static_cast<LanguageType>(L.type);
212  }
213 
214  return eLanguageTypeUnknown;
215 }
216 
217 const char *Language::GetNameForLanguageType(LanguageType language) {
218  if (language < num_languages)
219  return language_names[language].name;
220  else
222 }
223 
224 void Language::PrintAllLanguages(Stream &s, const char *prefix,
225  const char *suffix) {
226  for (uint32_t i = 1; i < num_languages; i++) {
227  s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
228  }
229 }
230 
231 void Language::ForAllLanguages(
232  std::function<bool(lldb::LanguageType)> callback) {
233  for (uint32_t i = 1; i < num_languages; i++) {
234  if (!callback(language_names[i].type))
235  break;
236  }
237 }
238 
239 bool Language::LanguageIsCPlusPlus(LanguageType language) {
240  switch (language) {
246  return true;
247  default:
248  return false;
249  }
250 }
251 
252 bool Language::LanguageIsObjC(LanguageType language) {
253  switch (language) {
254  case eLanguageTypeObjC:
256  return true;
257  default:
258  return false;
259  }
260 }
261 
262 bool Language::LanguageIsC(LanguageType language) {
263  switch (language) {
264  case eLanguageTypeC:
265  case eLanguageTypeC89:
266  case eLanguageTypeC99:
267  case eLanguageTypeC11:
268  return true;
269  default:
270  return false;
271  }
272 }
273 
274 bool Language::LanguageIsCFamily(LanguageType language) {
275  switch (language) {
276  case eLanguageTypeC:
277  case eLanguageTypeC89:
278  case eLanguageTypeC99:
279  case eLanguageTypeC11:
285  case eLanguageTypeObjC:
286  return true;
287  default:
288  return false;
289  }
290 }
291 
292 bool Language::LanguageIsPascal(LanguageType language) {
293  switch (language) {
295  return true;
296  default:
297  return false;
298  }
299 }
300 
301 LanguageType Language::GetPrimaryLanguage(LanguageType language) {
302  switch (language) {
308  case eLanguageTypeC:
309  case eLanguageTypeC89:
310  case eLanguageTypeC99:
311  case eLanguageTypeC11:
312  return eLanguageTypeC;
313  case eLanguageTypeObjC:
315  return eLanguageTypeObjC;
324  case eLanguageTypeAda83:
325  case eLanguageTypeAda95:
327  case eLanguageTypeJava:
328  case eLanguageTypePLI:
329  case eLanguageTypeUPC:
330  case eLanguageTypeD:
331  case eLanguageTypePython:
332  case eLanguageTypeOpenCL:
333  case eLanguageTypeGo:
336  case eLanguageTypeOCaml:
337  case eLanguageTypeRust:
338  case eLanguageTypeSwift:
339  case eLanguageTypeJulia:
340  case eLanguageTypeDylan:
344  default:
345  return language;
346  }
347 }
348 
349 std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
350  std::set<lldb::LanguageType> supported_languages;
351  ForEach([&](Language *lang) {
352  supported_languages.emplace(lang->GetLanguageType());
353  return true;
354  });
355  return supported_languages;
356 }
357 
358 LanguageSet Language::GetLanguagesSupportingTypeSystems() {
359  return PluginManager::GetAllTypeSystemSupportedLanguagesForTypes();
360 }
361 
362 LanguageSet Language::GetLanguagesSupportingTypeSystemsForExpressions() {
363  return PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions();
364 }
365 
366 LanguageSet Language::GetLanguagesSupportingREPLs() {
367  return PluginManager::GetREPLAllTypeSystemSupportedLanguages();
368 }
369 
370 std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
371  return nullptr;
372 }
373 
374 const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
375 
376 size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope,
377  const char *key, ResultSet &results,
378  bool append) {
379  if (!exe_scope || !exe_scope->CalculateTarget().get())
380  return false;
381 
382  if (!key || !key[0])
383  return false;
384 
385  if (!append)
386  results.clear();
387 
388  size_t old_size = results.size();
389 
390  if (this->Find_Impl(exe_scope, key, results))
391  return results.size() - old_size;
392  return 0;
393 }
394 
395 bool Language::ImageListTypeScavenger::Find_Impl(
396  ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
397  bool result = false;
398 
399  Target *target = exe_scope->CalculateTarget().get();
400  if (target) {
401  const auto &images(target->GetImages());
402  ConstString cs_key(key);
403  llvm::DenseSet<SymbolFile *> searched_sym_files;
404  TypeList matches;
405  images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files,
406  matches);
407  for (const auto &match : matches.Types()) {
408  if (match) {
409  CompilerType compiler_type(match->GetFullCompilerType());
410  compiler_type = AdjustForInclusion(compiler_type);
411  if (!compiler_type)
412  continue;
413  std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
414  new Result(compiler_type));
415  results.insert(std::move(scavengeresult));
416  result = true;
417  }
418  }
419  }
420 
421  return result;
422 }
423 
424 bool Language::GetFormatterPrefixSuffix(ValueObject &valobj,
425  ConstString type_hint,
426  std::string &prefix,
427  std::string &suffix) {
428  return false;
429 }
430 
431 DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() {
432  return nullptr;
433 }
434 
435 LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) {
436  return eLazyBoolCalculate;
437 }
438 
439 bool Language::IsNilReference(ValueObject &valobj) { return false; }
440 
441 bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
442 
443 bool Language::GetFunctionDisplayName(const SymbolContext *sc,
444  const ExecutionContext *exe_ctx,
445  FunctionNameRepresentation representation,
446  Stream &s) {
447  return false;
448 }
449 
450 void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
451  Stream &s) {
452  GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
453 }
454 
455 void Language::GetDefaultExceptionResolverDescription(bool catch_on,
456  bool throw_on,
457  Stream &s) {
458  s.Printf("Exception breakpoint (catch: %s throw: %s)",
459  catch_on ? "on" : "off", throw_on ? "on" : "off");
460 }
461 // Constructor
462 Language::Language() = default;
463 
464 // Destructor
465 Language::~Language() = default;
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::DumpValueObjectOptions::DeclPrintingHelper
std::function< bool(ConstString, ConstString, const DumpValueObjectOptions &, Stream &)> DeclPrintingHelper
Definition: DumpValueObjectOptions.h:54
lldb::eLanguageTypeFortran03
@ eLanguageTypeFortran03
ISO Fortran 2003.
Definition: lldb-enumerations.h:473
lldb::eLanguageTypeGo
@ eLanguageTypeGo
Go.
Definition: lldb-enumerations.h:461
lldb_private::HardcodedFormatters::HardcodedFormatFinder
HardcodedFormatterFinders< TypeFormatImpl > HardcodedFormatFinder
Definition: FormatClasses.h:39
lldb::eLanguageTypePascal83
@ eLanguageTypePascal83
ISO Pascal:1983.
Definition: lldb-enumerations.h:446
lldb::eLanguageTypeC99
@ eLanguageTypeC99
ISO C:1999.
Definition: lldb-enumerations.h:449
num_languages
static uint32_t num_languages
Definition: Language.cpp:205
lldb::eLanguageTypeD
@ eLanguageTypeD
D.
Definition: lldb-enumerations.h:456
lldb::eNumLanguageTypes
@ eNumLanguageTypes
Definition: lldb-enumerations.h:482
lldb::eLanguageTypeMipsAssembler
@ eLanguageTypeMipsAssembler
Mips_Assembler.
Definition: lldb-enumerations.h:480
lldb::LanguageType
LanguageType
Programming language type.
Definition: lldb-enumerations.h:436
lldb_private::Language::TypeScavenger::ResultSet
std::set< std::unique_ptr< Result > > ResultSet
Definition: Language.h:43
lldb_private::Language::ImageListTypeScavenger::Result
Definition: Language.h:58
lldb_private::Stream
Definition: Stream.h:28
Language.h
lldb::eLanguageTypeRust
@ eLanguageTypeRust
Rust.
Definition: lldb-enumerations.h:467
lldb_private::LazyBool
LazyBool
Definition: lldb-private-enumerations.h:115
lldb::eLanguageTypeModula3
@ eLanguageTypeModula3
Modula 3.
Definition: lldb-enumerations.h:462
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::Target
Definition: Target.h:450
lldb_private::Target::GetImages
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:924
lldb::eLanguageTypeUPC
@ eLanguageTypeUPC
Unified Parallel C.
Definition: lldb-enumerations.h:455
lldb::eLanguageTypeC_plus_plus_11
@ eLanguageTypeC_plus_plus_11
ISO C++:2011.
Definition: lldb-enumerations.h:465
lldb_private::HardcodedFormatters::HardcodedSummaryFinder
HardcodedFormatterFinders< TypeSummaryImpl > HardcodedSummaryFinder
Definition: FormatClasses.h:40
lldb::eLanguageTypeDylan
@ eLanguageTypeDylan
Dylan.
Definition: lldb-enumerations.h:471
lldb_private::Language::IsSourceFile
virtual bool IsSourceFile(llvm::StringRef file_path) const =0
lldb::eLanguageTypeModula2
@ eLanguageTypeModula2
ISO Modula-2:1996.
Definition: lldb-enumerations.h:447
Target.h
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb::eLanguageTypeFortran95
@ eLanguageTypeFortran95
ISO Fortran 95.
Definition: lldb-enumerations.h:451
lldb_private::Function
Definition: Function.h:413
lldb::eLanguageTypeJulia
@ eLanguageTypeJulia
Julia.
Definition: lldb-enumerations.h:470
lldb::eLanguageTypeC_plus_plus_03
@ eLanguageTypeC_plus_plus_03
ISO C++:2003.
Definition: lldb-enumerations.h:464
lldb::eLanguageTypeOCaml
@ eLanguageTypeOCaml
OCaml.
Definition: lldb-enumerations.h:466
lldb_private::ExecutionContextScope
Definition: ExecutionContextScope.h:32
language_name_pair
Definition: Language.cpp:153
lldb::eLanguageTypeOpenCL
@ eLanguageTypeOpenCL
OpenCL.
Definition: lldb-enumerations.h:460
language_names
struct language_name_pair language_names[]
Definition: Language.cpp:158
lldb::eLanguageTypeCobol74
@ eLanguageTypeCobol74
ISO Cobol:1974.
Definition: lldb-enumerations.h:442
lldb_private::Language::FunctionNameRepresentation
FunctionNameRepresentation
Definition: Language.h:142
lldb::eLanguageTypePython
@ eLanguageTypePython
Python.
Definition: lldb-enumerations.h:457
lldb::eLanguageTypeFortran77
@ eLanguageTypeFortran77
ISO Fortran 77.
Definition: lldb-enumerations.h:444
lldb_private::ConstString
Definition: ConstString.h:40
lldb::eLanguageTypeAda95
@ eLanguageTypeAda95
ISO Ada:1995.
Definition: lldb-enumerations.h:450
lldb::eLanguageTypeC89
@ eLanguageTypeC89
ISO C:1989.
Definition: lldb-enumerations.h:438
lldb::eLanguageTypeC11
@ eLanguageTypeC11
ISO C:2011.
Definition: lldb-enumerations.h:468
lldb::DynamicValueType
DynamicValueType
Definition: lldb-enumerations.h:494
language_name_pair::name
const char * name
Definition: Language.cpp:154
lldb::eLanguageTypeObjC
@ eLanguageTypeObjC
Objective-C.
Definition: lldb-enumerations.h:453
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb::eLanguageTypeObjC_plus_plus
@ eLanguageTypeObjC_plus_plus
Objective-C++.
Definition: lldb-enumerations.h:454
lldb_private::Language::GetLanguageType
virtual lldb::LanguageType GetLanguageType() const =0
lldb::eLanguageTypeJava
@ eLanguageTypeJava
Java.
Definition: lldb-enumerations.h:448
TypeList.h
GetLanguagesMap
static LanguagesMap & GetLanguagesMap()
Definition: Language.cpp:30
lldb_private::Status
Definition: Status.h:44
lldb_private::ValueObject
ValueObject:
Definition: ValueObject.h:105
lldb::eLanguageTypeAda83
@ eLanguageTypeAda83
ISO Ada:1983.
Definition: lldb-enumerations.h:440
lldb::eLanguageTypeUnknown
@ eLanguageTypeUnknown
Unknown or invalid language value.
Definition: lldb-enumerations.h:437
lldb::eLanguageTypeExtRenderScript
@ eLanguageTypeExtRenderScript
RenderScript.
Definition: lldb-enumerations.h:481
uint32_t
lldb_private::Language
Definition: Language.h:29
lldb_private::TypeList::FindTypes
TypeList FindTypes(ConstString name)
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
lldb::eLanguageTypePLI
@ eLanguageTypePLI
ANSI PL/I:1976.
Definition: lldb-enumerations.h:452
lldb::eLanguageTypeC_plus_plus_14
@ eLanguageTypeC_plus_plus_14
ISO C++:2014.
Definition: lldb-enumerations.h:472
PluginManager.h
LanguageUP
std::unique_ptr< Language > LanguageUP
Definition: Language.cpp:27
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:33
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::formatters
Definition: CXXFunctionPointer.h:15
lldb::eLanguageTypeC
@ eLanguageTypeC
Non-standardized C, such as K&R.
Definition: lldb-enumerations.h:439
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::eLazyBoolCalculate
@ eLazyBoolCalculate
Definition: lldb-private-enumerations.h:115
lldb_private::ExecutionContextScope::CalculateTarget
virtual lldb::TargetSP CalculateTarget()=0
lldb_private::TypeList
Definition: TypeList.h:20
lldb::eLanguageTypeFortran08
@ eLanguageTypeFortran08
ISO Fortran 2008.
Definition: lldb-enumerations.h:474
LanguagesMap
std::map< lldb::LanguageType, LanguageUP > LanguagesMap
Definition: Language.cpp:28
lldb_private::LanguageSet
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition: TypeSystem.h:40
Stream.h
lldb_private::TypeList::Types
TypeIterable Types()
Definition: TypeList.h:45
lldb::eLanguageTypeHaskell
@ eLanguageTypeHaskell
Haskell.
Definition: lldb-enumerations.h:463
lldb::eLanguageTypeCobol85
@ eLanguageTypeCobol85
ISO Cobol:1985.
Definition: lldb-enumerations.h:443
lldb::eLanguageTypeFortran90
@ eLanguageTypeFortran90
ISO Fortran 90.
Definition: lldb-enumerations.h:445
GetLanguagesMutex
static std::mutex & GetLanguagesMutex()
Definition: Language.cpp:41
lldb
Definition: SBAddress.h:15
SymbolFile.h
language_name_pair::type
LanguageType type
Definition: Language.cpp:155
lldb_private::HardcodedFormatters::HardcodedSyntheticFinder
HardcodedFormatterFinders< SyntheticChildren > HardcodedSyntheticFinder
Definition: FormatClasses.h:41
lldb::eLanguageTypeSwift
@ eLanguageTypeSwift
Swift.
Definition: lldb-enumerations.h:469
lldb::eLanguageTypeC_plus_plus
@ eLanguageTypeC_plus_plus
ISO C++:1998.
Definition: lldb-enumerations.h:441