blob: 3c3ef2841d44490b6db84c8c2da3c3ada8270cea [file] [log] [blame]
Kate Stoneb9c1b512016-09-06 20:57:50 +00001//===-- Language.cpp -------------------------------------------------*- C++
2//-*-===//
Enrico Granata5f9d3102015-08-27 21:33:50 +00003//
Chandler Carruth2946cd72019-01-19 08:50:56 +00004// 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
Enrico Granata5f9d3102015-08-27 21:33:50 +00007//
8//===----------------------------------------------------------------------===//
9
10#include <functional>
11#include <map>
Enrico Granata2996d822015-08-27 22:14:06 +000012#include <mutex>
Enrico Granata5f9d3102015-08-27 21:33:50 +000013
14#include "lldb/Target/Language.h"
15
Enrico Granata5f9d3102015-08-27 21:33:50 +000016#include "lldb/Core/PluginManager.h"
Enrico Granata63db2392016-11-01 18:50:49 +000017#include "lldb/Symbol/SymbolFile.h"
18#include "lldb/Symbol/TypeList.h"
19#include "lldb/Target/Target.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000020#include "lldb/Utility/Stream.h"
Enrico Granata5f9d3102015-08-27 21:33:50 +000021
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000022#include "llvm/Support/Threading.h"
23
Enrico Granata5f9d3102015-08-27 21:33:50 +000024using namespace lldb;
25using namespace lldb_private;
Enrico Granataac494532015-09-09 22:30:24 +000026using namespace lldb_private::formatters;
Enrico Granata5f9d3102015-08-27 21:33:50 +000027
28typedef std::unique_ptr<Language> LanguageUP;
29typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;
30
Kate Stoneb9c1b512016-09-06 20:57:50 +000031static LanguagesMap &GetLanguagesMap() {
32 static LanguagesMap *g_map = nullptr;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000033 static llvm::once_flag g_initialize;
Kate Stoneb9c1b512016-09-06 20:57:50 +000034
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000035 llvm::call_once(g_initialize, [] {
Kate Stoneb9c1b512016-09-06 20:57:50 +000036 g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global
37 // destructor chain
38 });
39
40 return *g_map;
Enrico Granata5f9d3102015-08-27 21:33:50 +000041}
Kate Stoneb9c1b512016-09-06 20:57:50 +000042static std::mutex &GetLanguagesMutex() {
43 static std::mutex *g_mutex = nullptr;
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000044 static llvm::once_flag g_initialize;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000045
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000046 llvm::call_once(g_initialize, [] {
Kate Stoneb9c1b512016-09-06 20:57:50 +000047 g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global
48 // destructor chain
49 });
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051 return *g_mutex;
Enrico Granata5f9d3102015-08-27 21:33:50 +000052}
53
Kate Stoneb9c1b512016-09-06 20:57:50 +000054Language *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;
Enrico Granata5f9d3102015-08-27 21:33:50 +000073 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 }
75
76 return nullptr;
Enrico Granata5f9d3102015-08-27 21:33:50 +000077}
78
Raphael Isemann566afa02018-08-02 00:30:15 +000079Language *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
91Language *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
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101void Language::ForEach(std::function<bool(Language *)> callback) {
Raphael Isemann566afa02018-08-02 00:30:15 +0000102 // 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
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112 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 }
Enrico Granata5f9d3102015-08-27 21:33:50 +0000118}
119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120bool Language::IsTopLevelFunction(Function &function) { return false; }
121
122lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; }
123
124HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats() {
125 return {};
Enrico Granata6754e042015-09-30 23:12:22 +0000126}
127
Kate Stoneb9c1b512016-09-06 20:57:50 +0000128HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries() {
129 return {};
Enrico Granata7cb59e12015-09-16 18:28:11 +0000130}
131
132HardcodedFormatters::HardcodedSyntheticFinder
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133Language::GetHardcodedSynthetics() {
134 return {};
Enrico Granata7cb59e12015-09-16 18:28:11 +0000135}
136
137HardcodedFormatters::HardcodedValidatorFinder
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138Language::GetHardcodedValidators() {
139 return {};
Enrico Granata7cb59e12015-09-16 18:28:11 +0000140}
141
Enrico Granatad3233c12015-09-09 01:10:46 +0000142std::vector<ConstString>
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143Language::GetPossibleFormattersMatches(ValueObject &valobj,
144 lldb::DynamicValueType use_dynamic) {
145 return {};
Enrico Granatad3233c12015-09-09 01:10:46 +0000146}
147
Enrico Granataac494532015-09-09 22:30:24 +0000148lldb_private::formatters::StringPrinter::EscapingHelper
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149Language::GetStringPrinterEscapingHelper(
150 lldb_private::formatters::StringPrinter::GetPrintableElementType
151 elem_type) {
152 return StringPrinter::GetDefaultEscapingHelper(elem_type);
Enrico Granataac494532015-09-09 22:30:24 +0000153}
154
Jim Ingham0e0984e2015-09-02 01:06:46 +0000155struct language_name_pair {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156 const char *name;
157 LanguageType type;
Jim Ingham0e0984e2015-09-02 01:06:46 +0000158};
159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160struct language_name_pair language_names[] = {
Jim Ingham0e0984e2015-09-02 01:06:46 +0000161 // To allow GetNameForLanguageType to be a simple array lookup, the first
162 // part of this array must follow enum LanguageType exactly.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 {"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},
Jim Ingham0e0984e2015-09-02 01:06:46 +0000199 // Vendor Extensions
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 {"mipsassem", eLanguageTypeMipsAssembler},
201 {"renderscript", eLanguageTypeExtRenderScript},
Jim Ingham0e0984e2015-09-02 01:06:46 +0000202 // Now synonyms, in arbitrary order
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203 {"objc", eLanguageTypeObjC},
204 {"objc++", eLanguageTypeObjC_plus_plus},
205 {"pascal", eLanguageTypePascal83}};
Jim Ingham0e0984e2015-09-02 01:06:46 +0000206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207static uint32_t num_languages =
208 sizeof(language_names) / sizeof(struct language_name_pair);
Jim Ingham0e0984e2015-09-02 01:06:46 +0000209
Zachary Turner6fa7681b2016-09-17 02:00:02 +0000210LanguageType 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);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 }
Zachary Turner6fa7681b2016-09-17 02:00:02 +0000215
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 return eLanguageTypeUnknown;
Jim Ingham0e0984e2015-09-02 01:06:46 +0000217}
218
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219const char *Language::GetNameForLanguageType(LanguageType language) {
220 if (language < num_languages)
221 return language_names[language].name;
222 else
223 return language_names[eLanguageTypeUnknown].name;
Jim Ingham0e0984e2015-09-02 01:06:46 +0000224}
225
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226void 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 }
Jim Ingham0e0984e2015-09-02 01:06:46 +0000231}
232
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233void 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 }
Enrico Granata28b38312015-09-02 01:31:10 +0000239}
240
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241bool 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:
Enrico Granata675f49b2015-10-07 18:36:53 +0000250 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 }
Enrico Granata675f49b2015-10-07 18:36:53 +0000252}
253
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254bool Language::LanguageIsObjC(LanguageType language) {
255 switch (language) {
256 case eLanguageTypeObjC:
257 case eLanguageTypeObjC_plus_plus:
258 return true;
259 default:
Enrico Granata608d67c2015-11-10 22:39:15 +0000260 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261 }
Enrico Granata608d67c2015-11-10 22:39:15 +0000262}
263
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264bool Language::LanguageIsC(LanguageType language) {
265 switch (language) {
266 case eLanguageTypeC:
267 case eLanguageTypeC89:
268 case eLanguageTypeC99:
269 case eLanguageTypeC11:
270 return true;
271 default:
Enrico Granata608d67c2015-11-10 22:39:15 +0000272 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273 }
Enrico Granata608d67c2015-11-10 22:39:15 +0000274}
275
Adrian Prantlde2cc0122019-05-16 20:03:05 +0000276bool 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
Kate Stoneb9c1b512016-09-06 20:57:50 +0000294bool Language::LanguageIsPascal(LanguageType language) {
295 switch (language) {
296 case eLanguageTypePascal83:
297 return true;
298 default:
Enrico Granatad4129b42015-11-19 01:11:53 +0000299 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300 }
Enrico Granatad4129b42015-11-19 01:11:53 +0000301}
302
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303LanguageType 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 }
Jim Inghama2023572015-12-18 02:14:04 +0000349}
350
Alex Langford03e1a822019-05-29 18:08:22 +0000351std::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
Adrian Prantlb0416022019-08-22 20:41:16 +0000360void 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 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369}
370
Adrian Prantlb0416022019-08-22 20:41:16 +0000371void Language::GetLanguagesSupportingREPLs(
372 std::set<lldb::LanguageType> &languages) {
373 uint32_t idx = 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374
Adrian Prantlb0416022019-08-22 20:41:16 +0000375 while (REPLEnumerateSupportedLanguages enumerate =
376 PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(
377 idx++)) {
378 (*enumerate)(languages);
379 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000380}
381
382std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
383 return nullptr;
384}
385
386const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
387
388size_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
Enrico Granata63db2392016-11-01 18:50:49 +0000407bool 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());
Enrico Granata63db2392016-11-01 18:50:49 +0000414 ConstString cs_key(key);
415 llvm::DenseSet<SymbolFile *> searched_sym_files;
416 TypeList matches;
Zachary Turner576495e2019-01-14 22:41:21 +0000417 images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files,
Enrico Granata63db2392016-11-01 18:50:49 +0000418 matches);
419 for (const auto &match : matches.Types()) {
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000420 if (match) {
Enrico Granata63db2392016-11-01 18:50:49 +0000421 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
Kate Stoneb9c1b512016-09-06 20:57:50 +0000436bool Language::GetFormatterPrefixSuffix(ValueObject &valobj,
437 ConstString type_hint,
438 std::string &prefix,
439 std::string &suffix) {
440 return false;
441}
442
443DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() {
444 return nullptr;
445}
446
Zachary Turner97206d52017-05-12 04:51:55 +0000447LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448 return eLazyBoolCalculate;
449}
450
451bool Language::IsNilReference(ValueObject &valobj) { return false; }
452
453bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
454
455bool Language::GetFunctionDisplayName(const SymbolContext *sc,
456 const ExecutionContext *exe_ctx,
457 FunctionNameRepresentation representation,
458 Stream &s) {
459 return false;
460}
461
462void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
463 Stream &s) {
464 GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
465}
466
467void 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");
Jim Inghama2023572015-12-18 02:14:04 +0000472}
Enrico Granata5f9d3102015-08-27 21:33:50 +0000473// Constructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000474Language::Language() {}
Enrico Granata5f9d3102015-08-27 21:33:50 +0000475
Enrico Granata5f9d3102015-08-27 21:33:50 +0000476// Destructor
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477Language::~Language() {}