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
14
19#include "lldb/Target/Target.h"
20#include "lldb/Utility/Stream.h"
21
22#include "llvm/Support/Threading.h"
23
24using namespace lldb;
25using namespace lldb_private;
26using namespace lldb_private::formatters;
27
28typedef std::unique_ptr<Language> LanguageUP;
29typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;
30
31#define LLDB_PROPERTIES_language
32#include "TargetProperties.inc"
33
34enum {
35#define LLDB_PROPERTIES_language
36#include "TargetPropertiesEnum.inc"
37};
38
40 static LanguageProperties g_settings;
41 return g_settings;
42}
43
45 static constexpr llvm::StringLiteral g_setting_name("language");
46 return g_setting_name;
47}
48
50 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
51 m_collection_sp->Initialize(g_language_properties);
52}
53
55 const uint32_t idx = ePropertyEnableFilterForLineBreakpoints;
56 return GetPropertyAtIndexAs<bool>(
57 idx, g_language_properties[idx].default_uint_value != 0);
58}
59
61 static LanguagesMap *g_map = nullptr;
62 static llvm::once_flag g_initialize;
63
64 llvm::call_once(g_initialize, [] {
65 g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global
66 // destructor chain
67 });
68
69 return *g_map;
70}
71static std::mutex &GetLanguagesMutex() {
72 static std::mutex *g_mutex = nullptr;
73 static llvm::once_flag g_initialize;
74
75 llvm::call_once(g_initialize, [] {
76 g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global
77 // destructor chain
78 });
79
80 return *g_mutex;
81}
82
84 std::lock_guard<std::mutex> guard(GetLanguagesMutex());
86 auto iter = map.find(language), end = map.end();
87 if (iter != end)
88 return iter->second.get();
89
90 Language *language_ptr = nullptr;
91 LanguageCreateInstance create_callback;
92
93 for (uint32_t idx = 0;
94 (create_callback =
96 ++idx) {
97 language_ptr = create_callback(language);
98
99 if (language_ptr) {
100 map[language] = std::unique_ptr<Language>(language_ptr);
101 return language_ptr;
102 }
103 }
104
105 return nullptr;
106}
107
108Language *Language::FindPlugin(llvm::StringRef file_path) {
109 Language *result = nullptr;
110 ForEach([&result, file_path](Language *language) {
111 if (language->IsSourceFile(file_path)) {
112 result = language;
113 return false;
114 }
115 return true;
116 });
117 return result;
118}
119
121 llvm::StringRef file_path) {
122 Language *result = FindPlugin(language);
123 // Finding a language by file path is slower, we so we use this as the
124 // fallback.
125 if (!result)
126 result = FindPlugin(file_path);
127 return result;
128}
129
130void Language::ForEach(std::function<bool(Language *)> callback) {
131 // If we want to iterate over all languages, we first have to complete the
132 // LanguagesMap.
133 static llvm::once_flag g_initialize;
134 llvm::call_once(g_initialize, [] {
135 for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes;
136 ++lang) {
137 FindPlugin(static_cast<lldb::LanguageType>(lang));
138 }
139 });
140
141 // callback may call a method in Language that attempts to acquire the same
142 // lock (such as Language::ForEach or Language::FindPlugin). To avoid a
143 // deadlock, we do not use callback while holding the lock.
144 std::vector<Language *> loaded_plugins;
145 {
146 std::lock_guard<std::mutex> guard(GetLanguagesMutex());
148 for (const auto &entry : map) {
149 if (entry.second)
150 loaded_plugins.push_back(entry.second.get());
151 }
152 }
153
154 for (auto *lang : loaded_plugins) {
155 if (!callback(lang))
156 break;
157 }
158}
159
160bool Language::IsTopLevelFunction(Function &function) { return false; }
161
163
165 return {};
166}
167
169 return {};
170}
171
174 return {};
175}
176
177std::vector<FormattersMatchCandidate>
179 lldb::DynamicValueType use_dynamic) {
180 return {};
181}
182
184 const char *name;
186};
187
189 // To allow GetNameForLanguageType to be a simple array lookup, the first
190 // part of this array must follow enum LanguageType exactly.
191 {"unknown", eLanguageTypeUnknown},
192 {"c89", eLanguageTypeC89},
193 {"c", eLanguageTypeC},
194 {"ada83", eLanguageTypeAda83},
196 {"cobol74", eLanguageTypeCobol74},
197 {"cobol85", eLanguageTypeCobol85},
198 {"fortran77", eLanguageTypeFortran77},
199 {"fortran90", eLanguageTypeFortran90},
200 {"pascal83", eLanguageTypePascal83},
201 {"modula2", eLanguageTypeModula2},
202 {"java", eLanguageTypeJava},
203 {"c99", eLanguageTypeC99},
204 {"ada95", eLanguageTypeAda95},
205 {"fortran95", eLanguageTypeFortran95},
206 {"pli", eLanguageTypePLI},
207 {"objective-c", eLanguageTypeObjC},
208 {"objective-c++", eLanguageTypeObjC_plus_plus},
209 {"upc", eLanguageTypeUPC},
210 {"d", eLanguageTypeD},
211 {"python", eLanguageTypePython},
212 {"opencl", eLanguageTypeOpenCL},
213 {"go", eLanguageTypeGo},
214 {"modula3", eLanguageTypeModula3},
215 {"haskell", eLanguageTypeHaskell},
218 {"ocaml", eLanguageTypeOCaml},
219 {"rust", eLanguageTypeRust},
220 {"c11", eLanguageTypeC11},
221 {"swift", eLanguageTypeSwift},
222 {"julia", eLanguageTypeJulia},
223 {"dylan", eLanguageTypeDylan},
225 {"fortran03", eLanguageTypeFortran03},
226 {"fortran08", eLanguageTypeFortran08},
227 {"renderscript", eLanguageTypeRenderScript},
228 {"bliss", eLanguageTypeBLISS},
229 {"kotlin", eLanguageTypeKotlin},
230 {"zig", eLanguageTypeZig},
231 {"crystal", eLanguageTypeCrystal},
232 {"<invalid language>",
233 static_cast<LanguageType>(
234 0x0029)}, // Not yet taken by any language in the DWARF spec
235 // and thus has no entry in LanguageType
238 {"c17", eLanguageTypeC17},
239 {"fortran18", eLanguageTypeFortran18},
240 {"ada2005", eLanguageTypeAda2005},
241 {"ada2012", eLanguageTypeAda2012},
242 {"HIP", eLanguageTypeHIP},
243 {"assembly", eLanguageTypeAssembly},
244 {"c-sharp", eLanguageTypeC_sharp},
245 {"mojo", eLanguageTypeMojo},
246 // Vendor Extensions
247 {"assembler", eLanguageTypeMipsAssembler},
248 // Now synonyms, in arbitrary order
249 {"objc", eLanguageTypeObjC},
250 {"objc++", eLanguageTypeObjC_plus_plus},
251 {"pascal", eLanguageTypePascal83}};
252
253static uint32_t num_languages =
254 sizeof(language_names) / sizeof(struct language_name_pair);
255
257 for (const auto &L : language_names) {
258 if (string.equals_insensitive(L.name))
259 return static_cast<LanguageType>(L.type);
260 }
261
263}
264
266 if (language < num_languages)
267 return language_names[language].name;
268 else
270}
271
273 llvm::StringRef prefix,
274 llvm::StringRef suffix) {
276 for (size_t idx = 0; idx < num_languages; ++idx) {
277 auto const &lang = language_names[idx];
278 if (supported[lang.type])
279 s << prefix << lang.name << suffix;
280 }
281}
282
283void Language::PrintAllLanguages(Stream &s, const char *prefix,
284 const char *suffix) {
285 for (uint32_t i = 1; i < num_languages; i++) {
286 s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
287 }
288}
289
291 std::function<bool(lldb::LanguageType)> callback) {
292 for (uint32_t i = 1; i < num_languages; i++) {
293 if (!callback(language_names[i].type))
294 break;
295 }
296}
297
299 switch (language) {
307 return true;
308 default:
309 return false;
310 }
311}
312
314 switch (language) {
317 return true;
318 default:
319 return false;
320 }
321}
322
324 switch (language) {
325 case eLanguageTypeC:
326 case eLanguageTypeC89:
327 case eLanguageTypeC99:
328 case eLanguageTypeC11:
329 return true;
330 default:
331 return false;
332 }
333}
334
336 switch (language) {
337 case eLanguageTypeC:
338 case eLanguageTypeC89:
339 case eLanguageTypeC99:
340 case eLanguageTypeC11:
349 return true;
350 default:
351 return false;
352 }
353}
354
356 switch (language) {
358 return true;
359 default:
360 return false;
361 }
362}
363
365 switch (language) {
373 case eLanguageTypeC:
374 case eLanguageTypeC89:
375 case eLanguageTypeC99:
376 case eLanguageTypeC11:
377 return eLanguageTypeC;
380 return eLanguageTypeObjC;
393 case eLanguageTypePLI:
394 case eLanguageTypeUPC:
395 case eLanguageTypeD:
398 case eLanguageTypeGo:
409 default:
410 return language;
411 }
412}
413
414std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
415 std::set<lldb::LanguageType> supported_languages;
416 ForEach([&](Language *lang) {
417 supported_languages.emplace(lang->GetLanguageType());
418 return true;
419 });
420 return supported_languages;
421}
422
425}
426
429}
430
433}
434
435std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
436 return nullptr;
437}
438
439const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
440
442 const char *key, ResultSet &results,
443 bool append) {
444 if (!exe_scope || !exe_scope->CalculateTarget().get())
445 return false;
446
447 if (!key || !key[0])
448 return false;
449
450 if (!append)
451 results.clear();
452
453 size_t old_size = results.size();
454
455 if (this->Find_Impl(exe_scope, key, results))
456 return results.size() - old_size;
457 return 0;
458}
459
461 ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
462 bool result = false;
463
464 Target *target = exe_scope->CalculateTarget().get();
465 if (target) {
466 const auto &images(target->GetImages());
467 TypeQuery query(key);
468 TypeResults type_results;
469 images.FindTypes(nullptr, query, type_results);
470 for (const auto &match : type_results.GetTypeMap().Types()) {
471 if (match) {
472 CompilerType compiler_type(match->GetFullCompilerType());
473 compiler_type = AdjustForInclusion(compiler_type);
474 if (!compiler_type)
475 continue;
476 std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
477 new Result(compiler_type));
478 results.insert(std::move(scavengeresult));
479 result = true;
480 }
481 }
482 }
483
484 return result;
485}
486
487std::pair<llvm::StringRef, llvm::StringRef>
488Language::GetFormatterPrefixSuffix(llvm::StringRef type_hint) {
489 return std::pair<llvm::StringRef, llvm::StringRef>();
490}
491
492bool Language::DemangledNameContainsPath(llvm::StringRef path,
493 ConstString demangled) const {
494 // The base implementation does a simple contains comparision:
495 if (path.empty())
496 return false;
497 return demangled.GetStringRef().contains(path);
498}
499
501 return nullptr;
502}
503
505 return eLazyBoolCalculate;
506}
507
508bool Language::IsNilReference(ValueObject &valobj) { return false; }
509
510bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
511
513 const ExecutionContext *exe_ctx,
514 FunctionNameRepresentation representation,
515 Stream &s) {
516 return false;
517}
518
519void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
520 Stream &s) {
521 GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
522}
523
525 bool throw_on,
526 Stream &s) {
527 s.Printf("Exception breakpoint (catch: %s throw: %s)",
528 catch_on ? "on" : "off", throw_on ? "on" : "off");
529}
530// Constructor
531Language::Language() = default;
532
533// Destructor
534Language::~Language() = default;
static llvm::raw_ostream & error(Stream &strm)
struct language_name_pair language_names[]
Definition: Language.cpp:188
std::map< lldb::LanguageType, LanguageUP > LanguagesMap
Definition: Language.cpp:29
static LanguagesMap & GetLanguagesMap()
Definition: Language.cpp:60
static uint32_t num_languages
Definition: Language.cpp:253
static std::mutex & GetLanguagesMutex()
Definition: Language.cpp:71
std::unique_ptr< Language > LanguageUP
Definition: Language.cpp:28
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
A uniqued constant string class.
Definition: ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:197
std::function< bool(ConstString, ConstString, const DumpValueObjectOptions &, Stream &)> DeclPrintingHelper
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
virtual lldb::TargetSP CalculateTarget()=0
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A class that describes a function.
Definition: Function.h:399
HardcodedFormatterFinders< SyntheticChildren > HardcodedSyntheticFinder
Definition: FormatClasses.h:42
HardcodedFormatterFinders< TypeSummaryImpl > HardcodedSummaryFinder
Definition: FormatClasses.h:41
HardcodedFormatterFinders< TypeFormatImpl > HardcodedFormatFinder
Definition: FormatClasses.h:40
static llvm::StringRef GetSettingName()
Definition: Language.cpp:44
bool GetEnableFilterForLineBreakpoints() const
Definition: Language.cpp:54
bool Find_Impl(ExecutionContextScope *exe_scope, const char *key, ResultSet &results) override
Definition: Language.cpp:460
std::set< std::unique_ptr< Result > > ResultSet
Definition: Language.h:52
virtual bool Find_Impl(ExecutionContextScope *exe_scope, const char *key, ResultSet &results)=0
size_t Find(ExecutionContextScope *exe_scope, const char *key, ResultSet &results, bool append=true)
Definition: Language.cpp:441
virtual bool IsSourceFile(llvm::StringRef file_path) const =0
static void PrintSupportedLanguagesForExpressions(Stream &s, llvm::StringRef prefix, llvm::StringRef suffix)
Prints to the specified stream 's' each language type that the current target supports for expression...
Definition: Language.cpp:272
static LanguageSet GetLanguagesSupportingREPLs()
Definition: Language.cpp:431
static LanguageSet GetLanguagesSupportingTypeSystems()
Definition: Language.cpp:423
virtual std::vector< FormattersMatchCandidate > GetPossibleFormattersMatches(ValueObject &valobj, lldb::DynamicValueType use_dynamic)
Definition: Language.cpp:178
virtual lldb::TypeCategoryImplSP GetFormatters()
Definition: Language.cpp:162
static Language * FindPlugin(lldb::LanguageType language)
Definition: Language.cpp:83
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition: Language.cpp:265
virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper()
Definition: Language.cpp:500
static LanguageProperties & GetGlobalLanguageProperties()
Definition: Language.cpp:39
virtual LazyBool IsLogicalTrue(ValueObject &valobj, Status &error)
Definition: Language.cpp:504
virtual const char * GetLanguageSpecificTypeLookupHelp()
Definition: Language.cpp:439
virtual std::pair< llvm::StringRef, llvm::StringRef > GetFormatterPrefixSuffix(llvm::StringRef type_hint)
An individual data formatter may apply to several types and cross language boundaries.
Definition: Language.cpp:488
static bool LanguageIsC(lldb::LanguageType language)
Definition: Language.cpp:323
virtual lldb::LanguageType GetLanguageType() const =0
virtual HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries()
Definition: Language.cpp:168
static void GetDefaultExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s)
Definition: Language.cpp:524
virtual bool DemangledNameContainsPath(llvm::StringRef path, ConstString demangled) const
Definition: Language.cpp:492
static bool LanguageIsCPlusPlus(lldb::LanguageType language)
Definition: Language.cpp:298
static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language)
Definition: Language.cpp:364
static bool LanguageIsPascal(lldb::LanguageType language)
Definition: Language.cpp:355
virtual bool IsNilReference(ValueObject &valobj)
Definition: Language.cpp:508
static void ForAllLanguages(std::function< bool(lldb::LanguageType)> callback)
Definition: Language.cpp:290
virtual bool IsUninitializedReference(ValueObject &valobj)
Definition: Language.cpp:510
virtual bool GetFunctionDisplayName(const SymbolContext *sc, const ExecutionContext *exe_ctx, FunctionNameRepresentation representation, Stream &s)
Definition: Language.cpp:512
static void PrintAllLanguages(Stream &s, const char *prefix, const char *suffix)
Definition: Language.cpp:283
virtual HardcodedFormatters::HardcodedSyntheticFinder GetHardcodedSynthetics()
Definition: Language.cpp:173
virtual std::unique_ptr< TypeScavenger > GetTypeScavenger()
Definition: Language.cpp:435
static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions()
Definition: Language.cpp:427
virtual bool IsTopLevelFunction(Function &function)
Definition: Language.cpp:160
virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s)
Definition: Language.cpp:519
static lldb::LanguageType GetLanguageTypeFromString(const char *string)=delete
static void ForEach(std::function< bool(Language *)> callback)
Definition: Language.cpp:130
static bool LanguageIsCFamily(lldb::LanguageType language)
Equivalent to LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
Definition: Language.cpp:335
static std::set< lldb::LanguageType > GetSupportedLanguages()
Definition: Language.cpp:414
virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats()
Definition: Language.cpp:164
static bool LanguageIsObjC(lldb::LanguageType language)
Definition: Language.cpp:313
static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions()
static LanguageSet GetREPLAllTypeSystemSupportedLanguages()
static LanguageCreateInstance GetLanguageCreateCallbackAtIndex(uint32_t idx)
static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes()
lldb::OptionValuePropertiesSP m_collection_sp
An error handling class.
Definition: Status.h:44
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:972
TypeIterable Types() const
Definition: TypeMap.h:49
A class that contains all state required for type lookups.
Definition: Type.h:96
This class tracks the state and results of a TypeQuery.
Definition: Type.h:304
TypeMap & GetTypeMap()
Definition: Type.h:346
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Language *(* LanguageCreateInstance)(lldb::LanguageType language)
Definition: SBAddress.h:15
LanguageType
Programming language type.
@ eLanguageTypeC_plus_plus_20
ISO C++:2020.
@ eLanguageTypeC_plus_plus_14
ISO C++:2014.
@ eLanguageTypeHaskell
Haskell.
@ eLanguageTypeRenderScript
@ eLanguageTypePLI
ANSI PL/I:1976.
@ eLanguageTypeC11
ISO C:2011.
@ eLanguageTypeJava
Java.
@ eLanguageTypeFortran08
ISO Fortran 2008.
@ eLanguageTypeFortran18
@ eLanguageTypeC99
ISO C:1999.
@ eLanguageTypePascal83
ISO Pascal:1983.
@ eLanguageTypeModula3
Modula 3.
@ eLanguageTypeModula2
ISO Modula-2:1996.
@ eLanguageTypeOCaml
OCaml.
@ eLanguageTypeMipsAssembler
Mips_Assembler.
@ eLanguageTypeZig
@ eLanguageTypeC_plus_plus_03
ISO C++:2003.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeRust
Rust.
@ eLanguageTypeC17
@ eLanguageTypeFortran95
ISO Fortran 95.
@ eLanguageTypeC_sharp
@ eLanguageTypeMojo
@ eLanguageTypeAda2012
@ eLanguageTypeC_plus_plus_17
ISO C++:2017.
@ eLanguageTypeCrystal
@ eLanguageTypeObjC_plus_plus
Objective-C++.
@ eLanguageTypeC_plus_plus_11
ISO C++:2011.
@ eNumLanguageTypes
@ eLanguageTypeSwift
Swift.
@ eLanguageTypeC89
ISO C:1989.
@ eLanguageTypeAda83
ISO Ada:1983.
@ eLanguageTypeJulia
Julia.
@ eLanguageTypeGo
Go.
@ eLanguageTypeFortran77
ISO Fortran 77.
@ eLanguageTypeBLISS
@ eLanguageTypeKotlin
@ eLanguageTypeCobol85
ISO Cobol:1985.
@ eLanguageTypeUPC
Unified Parallel C.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeAda95
ISO Ada:1995.
@ eLanguageTypeCobol74
ISO Cobol:1974.
@ eLanguageTypePython
Python.
@ eLanguageTypeAda2005
@ eLanguageTypeOpenCL
OpenCL.
@ eLanguageTypeAssembly
@ eLanguageTypeD
D.
@ eLanguageTypeFortran90
ISO Fortran 90.
@ eLanguageTypeHIP
@ eLanguageTypeObjC
Objective-C.
@ eLanguageTypeC_plus_plus
ISO C++:1998.
@ eLanguageTypeDylan
Dylan.
@ eLanguageTypeFortran03
ISO Fortran 2003.
std::shared_ptr< lldb_private::TypeCategoryImpl > TypeCategoryImplSP
Definition: lldb-forward.h:451
LanguageType type
Definition: Language.cpp:185
const char * name
Definition: Language.cpp:184
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition: Type.h:36