blob: 5c7a4097dd6ff42260ee61dc6a944f3ac3ad0a90 [file] [log] [blame]
Kate Stoneb9c1b512016-09-06 20:57:50 +00001//===-- Language.cpp -------------------------------------------------*- C++
2//-*-===//
Enrico Granata5f9d3102015-08-27 21:33:50 +00003//
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>
Enrico Granata2996d822015-08-27 22:14:06 +000013#include <mutex>
Enrico Granata5f9d3102015-08-27 21:33:50 +000014
15#include "lldb/Target/Language.h"
16
Enrico Granata5f9d3102015-08-27 21:33:50 +000017#include "lldb/Core/PluginManager.h"
Enrico Granata63db2392016-11-01 18:50:49 +000018#include "lldb/Symbol/SymbolFile.h"
19#include "lldb/Symbol/TypeList.h"
20#include "lldb/Target/Target.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000021#include "lldb/Utility/Stream.h"
Enrico Granata5f9d3102015-08-27 21:33:50 +000022
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000023#include "llvm/Support/Threading.h"
24
Enrico Granata5f9d3102015-08-27 21:33:50 +000025using namespace lldb;
26using namespace lldb_private;
Enrico Granataac494532015-09-09 22:30:24 +000027using namespace lldb_private::formatters;
Enrico Granata5f9d3102015-08-27 21:33:50 +000028
29typedef std::unique_ptr<Language> LanguageUP;
30typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;
31
Kate Stoneb9c1b512016-09-06 20:57:50 +000032static LanguagesMap &GetLanguagesMap() {
33 static LanguagesMap *g_map = nullptr;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000034 static llvm::once_flag g_initialize;
Kate Stoneb9c1b512016-09-06 20:57:50 +000035
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000036 llvm::call_once(g_initialize, [] {
Kate Stoneb9c1b512016-09-06 20:57:50 +000037 g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global
38 // destructor chain
39 });
40
41 return *g_map;
Enrico Granata5f9d3102015-08-27 21:33:50 +000042}
Kate Stoneb9c1b512016-09-06 20:57:50 +000043static std::mutex &GetLanguagesMutex() {
44 static std::mutex *g_mutex = nullptr;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000045 static llvm::once_flag g_initialize;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000046
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000047 llvm::call_once(g_initialize, [] {
Kate Stoneb9c1b512016-09-06 20:57:50 +000048 g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global
49 // destructor chain
50 });
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000051
Kate Stoneb9c1b512016-09-06 20:57:50 +000052 return *g_mutex;
Enrico Granata5f9d3102015-08-27 21:33:50 +000053}
54
Kate Stoneb9c1b512016-09-06 20:57:50 +000055Language *Language::FindPlugin(lldb::LanguageType language) {
56 std::lock_guard<std::mutex> guard(GetLanguagesMutex());
57 LanguagesMap &map(GetLanguagesMap());
58 auto iter = map.find(language), end = map.end();
59 if (iter != end)
60 return iter->second.get();
61
62 Language *language_ptr = nullptr;
63 LanguageCreateInstance create_callback;
64
65 for (uint32_t idx = 0;
66 (create_callback =
67 PluginManager::GetLanguageCreateCallbackAtIndex(idx)) != nullptr;
68 ++idx) {
69 language_ptr = create_callback(language);
70
71 if (language_ptr) {
72 map[language] = std::unique_ptr<Language>(language_ptr);
73 return language_ptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +000074 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 }
76
77 return nullptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +000078}
79
Raphael Isemann566afa02018-08-02 00:30:15 +000080Language *Language::FindPlugin(llvm::StringRef file_path) {
81 Language *result = nullptr;
82 ForEach([&result, file_path](Language *language) {
83 if (language->IsSourceFile(file_path)) {
84 result = language;
85 return false;
86 }
87 return true;
88 });
89 return result;
90}
91
92Language *Language::FindPlugin(LanguageType language,
93 llvm::StringRef file_path) {
94 Language *result = FindPlugin(language);
95 // Finding a language by file path is slower, we so we use this as the
96 // fallback.
97 if (!result)
98 result = FindPlugin(file_path);
99 return result;
100}
101
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102void Language::ForEach(std::function<bool(Language *)> callback) {
Raphael Isemann566afa02018-08-02 00:30:15 +0000103 // If we want to iterate over all languages, we first have to complete the
104 // LanguagesMap.
105 static llvm::once_flag g_initialize;
106 llvm::call_once(g_initialize, [] {
107 for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes;
108 ++lang) {
109 FindPlugin(static_cast<lldb::LanguageType>(lang));
110 }
111 });
112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 std::lock_guard<std::mutex> guard(GetLanguagesMutex());
114 LanguagesMap &map(GetLanguagesMap());
115 for (const auto &entry : map) {
116 if (!callback(entry.second.get()))
117 break;
118 }
Enrico Granata5f9d3102015-08-27 21:33:50 +0000119}
120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121bool Language::IsTopLevelFunction(Function &function) { return false; }
122
123lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; }
124
125HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats() {
126 return {};
Enrico Granata6754e042015-09-30 23:12:22 +0000127}
128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries() {
130 return {};
Enrico Granata7cb59e12015-09-16 18:28:11 +0000131}
132
133HardcodedFormatters::HardcodedSyntheticFinder
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134Language::GetHardcodedSynthetics() {
135 return {};
Enrico Granata7cb59e12015-09-16 18:28:11 +0000136}
137
138HardcodedFormatters::HardcodedValidatorFinder
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139Language::GetHardcodedValidators() {
140 return {};
Enrico Granata7cb59e12015-09-16 18:28:11 +0000141}
142
Enrico Granatad3233c12015-09-09 01:10:46 +0000143std::vector<ConstString>
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144Language::GetPossibleFormattersMatches(ValueObject &valobj,
145 lldb::DynamicValueType use_dynamic) {
146 return {};
Enrico Granatad3233c12015-09-09 01:10:46 +0000147}
148
Enrico Granataac494532015-09-09 22:30:24 +0000149lldb_private::formatters::StringPrinter::EscapingHelper
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150Language::GetStringPrinterEscapingHelper(
151 lldb_private::formatters::StringPrinter::GetPrintableElementType
152 elem_type) {
153 return StringPrinter::GetDefaultEscapingHelper(elem_type);
Enrico Granataac494532015-09-09 22:30:24 +0000154}
155
Jim Ingham0e0984e2015-09-02 01:06:46 +0000156struct language_name_pair {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157 const char *name;
158 LanguageType type;
Jim Ingham0e0984e2015-09-02 01:06:46 +0000159};
160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161struct language_name_pair language_names[] = {
Jim Ingham0e0984e2015-09-02 01:06:46 +0000162 // To allow GetNameForLanguageType to be a simple array lookup, the first
163 // part of this array must follow enum LanguageType exactly.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 {"unknown", eLanguageTypeUnknown},
165 {"c89", eLanguageTypeC89},
166 {"c", eLanguageTypeC},
167 {"ada83", eLanguageTypeAda83},
168 {"c++", eLanguageTypeC_plus_plus},
169 {"cobol74", eLanguageTypeCobol74},
170 {"cobol85", eLanguageTypeCobol85},
171 {"fortran77", eLanguageTypeFortran77},
172 {"fortran90", eLanguageTypeFortran90},
173 {"pascal83", eLanguageTypePascal83},
174 {"modula2", eLanguageTypeModula2},
175 {"java", eLanguageTypeJava},
176 {"c99", eLanguageTypeC99},
177 {"ada95", eLanguageTypeAda95},
178 {"fortran95", eLanguageTypeFortran95},
179 {"pli", eLanguageTypePLI},
180 {"objective-c", eLanguageTypeObjC},
181 {"objective-c++", eLanguageTypeObjC_plus_plus},
182 {"upc", eLanguageTypeUPC},
183 {"d", eLanguageTypeD},
184 {"python", eLanguageTypePython},
185 {"opencl", eLanguageTypeOpenCL},
186 {"go", eLanguageTypeGo},
187 {"modula3", eLanguageTypeModula3},
188 {"haskell", eLanguageTypeHaskell},
189 {"c++03", eLanguageTypeC_plus_plus_03},
190 {"c++11", eLanguageTypeC_plus_plus_11},
191 {"ocaml", eLanguageTypeOCaml},
192 {"rust", eLanguageTypeRust},
193 {"c11", eLanguageTypeC11},
194 {"swift", eLanguageTypeSwift},
195 {"julia", eLanguageTypeJulia},
196 {"dylan", eLanguageTypeDylan},
197 {"c++14", eLanguageTypeC_plus_plus_14},
198 {"fortran03", eLanguageTypeFortran03},
199 {"fortran08", eLanguageTypeFortran08},
Jim Ingham0e0984e2015-09-02 01:06:46 +0000200 // Vendor Extensions
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 {"mipsassem", eLanguageTypeMipsAssembler},
202 {"renderscript", eLanguageTypeExtRenderScript},
Jim Ingham0e0984e2015-09-02 01:06:46 +0000203 // Now synonyms, in arbitrary order
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204 {"objc", eLanguageTypeObjC},
205 {"objc++", eLanguageTypeObjC_plus_plus},
206 {"pascal", eLanguageTypePascal83}};
Jim Ingham0e0984e2015-09-02 01:06:46 +0000207
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208static uint32_t num_languages =
209 sizeof(language_names) / sizeof(struct language_name_pair);
Jim Ingham0e0984e2015-09-02 01:06:46 +0000210
Zachary Turner6fa7681b2016-09-17 02:00:02 +0000211LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) {
212 for (const auto &L : language_names) {
213 if (string.equals_lower(L.name))
214 return static_cast<LanguageType>(L.type);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215 }
Zachary Turner6fa7681b2016-09-17 02:00:02 +0000216
Kate Stoneb9c1b512016-09-06 20:57:50 +0000217 return eLanguageTypeUnknown;
Jim Ingham0e0984e2015-09-02 01:06:46 +0000218}
219
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220const char *Language::GetNameForLanguageType(LanguageType language) {
221 if (language < num_languages)
222 return language_names[language].name;
223 else
224 return language_names[eLanguageTypeUnknown].name;
Jim Ingham0e0984e2015-09-02 01:06:46 +0000225}
226
Kate Stoneb9c1b512016-09-06 20:57:50 +0000227void Language::PrintAllLanguages(Stream &s, const char *prefix,
228 const char *suffix) {
229 for (uint32_t i = 1; i < num_languages; i++) {
230 s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
231 }
Jim Ingham0e0984e2015-09-02 01:06:46 +0000232}
233
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234void Language::ForAllLanguages(
235 std::function<bool(lldb::LanguageType)> callback) {
236 for (uint32_t i = 1; i < num_languages; i++) {
237 if (!callback(language_names[i].type))
238 break;
239 }
Enrico Granata28b38312015-09-02 01:31:10 +0000240}
241
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242bool Language::LanguageIsCPlusPlus(LanguageType language) {
243 switch (language) {
244 case eLanguageTypeC_plus_plus:
245 case eLanguageTypeC_plus_plus_03:
246 case eLanguageTypeC_plus_plus_11:
247 case eLanguageTypeC_plus_plus_14:
248 case eLanguageTypeObjC_plus_plus:
249 return true;
250 default:
Enrico Granata675f49b2015-10-07 18:36:53 +0000251 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000252 }
Enrico Granata675f49b2015-10-07 18:36:53 +0000253}
254
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255bool Language::LanguageIsObjC(LanguageType language) {
256 switch (language) {
257 case eLanguageTypeObjC:
258 case eLanguageTypeObjC_plus_plus:
259 return true;
260 default:
Enrico Granata608d67c2015-11-10 22:39:15 +0000261 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262 }
Enrico Granata608d67c2015-11-10 22:39:15 +0000263}
264
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265bool Language::LanguageIsC(LanguageType language) {
266 switch (language) {
267 case eLanguageTypeC:
268 case eLanguageTypeC89:
269 case eLanguageTypeC99:
270 case eLanguageTypeC11:
271 return true;
272 default:
Enrico Granata608d67c2015-11-10 22:39:15 +0000273 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 }
Enrico Granata608d67c2015-11-10 22:39:15 +0000275}
276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277bool Language::LanguageIsPascal(LanguageType language) {
278 switch (language) {
279 case eLanguageTypePascal83:
280 return true;
281 default:
Enrico Granatad4129b42015-11-19 01:11:53 +0000282 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000283 }
Enrico Granatad4129b42015-11-19 01:11:53 +0000284}
285
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286LanguageType Language::GetPrimaryLanguage(LanguageType language) {
287 switch (language) {
288 case eLanguageTypeC_plus_plus:
289 case eLanguageTypeC_plus_plus_03:
290 case eLanguageTypeC_plus_plus_11:
291 case eLanguageTypeC_plus_plus_14:
292 return eLanguageTypeC_plus_plus;
293 case eLanguageTypeC:
294 case eLanguageTypeC89:
295 case eLanguageTypeC99:
296 case eLanguageTypeC11:
297 return eLanguageTypeC;
298 case eLanguageTypeObjC:
299 case eLanguageTypeObjC_plus_plus:
300 return eLanguageTypeObjC;
301 case eLanguageTypePascal83:
302 case eLanguageTypeCobol74:
303 case eLanguageTypeCobol85:
304 case eLanguageTypeFortran77:
305 case eLanguageTypeFortran90:
306 case eLanguageTypeFortran95:
307 case eLanguageTypeFortran03:
308 case eLanguageTypeFortran08:
309 case eLanguageTypeAda83:
310 case eLanguageTypeAda95:
311 case eLanguageTypeModula2:
312 case eLanguageTypeJava:
313 case eLanguageTypePLI:
314 case eLanguageTypeUPC:
315 case eLanguageTypeD:
316 case eLanguageTypePython:
317 case eLanguageTypeOpenCL:
318 case eLanguageTypeGo:
319 case eLanguageTypeModula3:
320 case eLanguageTypeHaskell:
321 case eLanguageTypeOCaml:
322 case eLanguageTypeRust:
323 case eLanguageTypeSwift:
324 case eLanguageTypeJulia:
325 case eLanguageTypeDylan:
326 case eLanguageTypeMipsAssembler:
327 case eLanguageTypeExtRenderScript:
328 case eLanguageTypeUnknown:
329 default:
330 return language;
331 }
Jim Inghama2023572015-12-18 02:14:04 +0000332}
333
Kate Stoneb9c1b512016-09-06 20:57:50 +0000334void Language::GetLanguagesSupportingTypeSystems(
335 std::set<lldb::LanguageType> &languages,
336 std::set<lldb::LanguageType> &languages_for_expressions) {
337 uint32_t idx = 0;
338
339 while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager::
340 GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++)) {
341 (*enumerate)(languages, languages_for_expressions);
342 }
343}
344
345void Language::GetLanguagesSupportingREPLs(
346 std::set<lldb::LanguageType> &languages) {
347 uint32_t idx = 0;
348
349 while (REPLEnumerateSupportedLanguages enumerate =
350 PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(
351 idx++)) {
352 (*enumerate)(languages);
353 }
354}
355
356std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
357 return nullptr;
358}
359
360const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
361
362size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope,
363 const char *key, ResultSet &results,
364 bool append) {
365 if (!exe_scope || !exe_scope->CalculateTarget().get())
366 return false;
367
368 if (!key || !key[0])
369 return false;
370
371 if (!append)
372 results.clear();
373
374 size_t old_size = results.size();
375
376 if (this->Find_Impl(exe_scope, key, results))
377 return results.size() - old_size;
378 return 0;
379}
380
Enrico Granata63db2392016-11-01 18:50:49 +0000381bool Language::ImageListTypeScavenger::Find_Impl(
382 ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
383 bool result = false;
384
385 Target *target = exe_scope->CalculateTarget().get();
386 if (target) {
387 const auto &images(target->GetImages());
Enrico Granata63db2392016-11-01 18:50:49 +0000388 ConstString cs_key(key);
389 llvm::DenseSet<SymbolFile *> searched_sym_files;
390 TypeList matches;
Zachary Turner576495e2019-01-14 22:41:21 +0000391 images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files,
Enrico Granata63db2392016-11-01 18:50:49 +0000392 matches);
393 for (const auto &match : matches.Types()) {
394 if (match.get()) {
395 CompilerType compiler_type(match->GetFullCompilerType());
396 compiler_type = AdjustForInclusion(compiler_type);
397 if (!compiler_type)
398 continue;
399 std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
400 new Result(compiler_type));
401 results.insert(std::move(scavengeresult));
402 result = true;
403 }
404 }
405 }
406
407 return result;
408}
409
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410bool Language::GetFormatterPrefixSuffix(ValueObject &valobj,
411 ConstString type_hint,
412 std::string &prefix,
413 std::string &suffix) {
414 return false;
415}
416
417DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() {
418 return nullptr;
419}
420
Zachary Turner97206d52017-05-12 04:51:55 +0000421LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 return eLazyBoolCalculate;
423}
424
425bool Language::IsNilReference(ValueObject &valobj) { return false; }
426
427bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
428
429bool Language::GetFunctionDisplayName(const SymbolContext *sc,
430 const ExecutionContext *exe_ctx,
431 FunctionNameRepresentation representation,
432 Stream &s) {
433 return false;
434}
435
436void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
437 Stream &s) {
438 GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
439}
440
441void Language::GetDefaultExceptionResolverDescription(bool catch_on,
442 bool throw_on,
443 Stream &s) {
444 s.Printf("Exception breakpoint (catch: %s throw: %s)",
445 catch_on ? "on" : "off", throw_on ? "on" : "off");
Jim Inghama2023572015-12-18 02:14:04 +0000446}
Enrico Granata5f9d3102015-08-27 21:33:50 +0000447//----------------------------------------------------------------------
448// Constructor
449//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450Language::Language() {}
Enrico Granata5f9d3102015-08-27 21:33:50 +0000451
452//----------------------------------------------------------------------
453// Destructor
454//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000455Language::~Language() {}