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/BinaryFormat/Dwarf.h"
23#include "llvm/Support/Threading.h"
24
25using namespace lldb;
26using namespace lldb_private;
27using namespace lldb_private::formatters;
28
29typedef std::unique_ptr<Language> LanguageUP;
30typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;
31
32#define LLDB_PROPERTIES_language
33#include "TargetProperties.inc"
34
35enum {
36#define LLDB_PROPERTIES_language
37#include "TargetPropertiesEnum.inc"
38};
39
41 static LanguageProperties g_settings;
42 return g_settings;
43}
44
46 static constexpr llvm::StringLiteral g_setting_name("language");
47 return g_setting_name;
48}
49
51 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
52 m_collection_sp->Initialize(g_language_properties);
53}
54
56 const uint32_t idx = ePropertyEnableFilterForLineBreakpoints;
57 return GetPropertyAtIndexAs<bool>(
58 idx, g_language_properties[idx].default_uint_value != 0);
59}
60
62 static LanguagesMap *g_map = nullptr;
63 static llvm::once_flag g_initialize;
64
65 llvm::call_once(g_initialize, [] {
66 g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global
67 // destructor chain
68 });
69
70 return *g_map;
71}
72static std::mutex &GetLanguagesMutex() {
73 static std::mutex *g_mutex = nullptr;
74 static llvm::once_flag g_initialize;
75
76 llvm::call_once(g_initialize, [] {
77 g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global
78 // destructor chain
79 });
80
81 return *g_mutex;
82}
83
85 std::lock_guard<std::mutex> guard(GetLanguagesMutex());
87 auto iter = map.find(language), end = map.end();
88 if (iter != end)
89 return iter->second.get();
90
91 Language *language_ptr = nullptr;
92 LanguageCreateInstance create_callback;
93
94 for (uint32_t idx = 0;
95 (create_callback =
97 ++idx) {
98 language_ptr = create_callback(language);
99
100 if (language_ptr) {
101 map[language] = std::unique_ptr<Language>(language_ptr);
102 return language_ptr;
103 }
104 }
105
106 return nullptr;
107}
108
109Language *Language::FindPlugin(llvm::StringRef file_path) {
110 Language *result = nullptr;
111 ForEach([&result, file_path](Language *language) {
112 if (language->IsSourceFile(file_path)) {
113 result = language;
114 return false;
115 }
116 return true;
117 });
118 return result;
119}
120
122 llvm::StringRef file_path) {
123 Language *result = FindPlugin(language);
124 // Finding a language by file path is slower, we so we use this as the
125 // fallback.
126 if (!result)
127 result = FindPlugin(file_path);
128 return result;
129}
130
131void Language::ForEach(std::function<bool(Language *)> callback) {
132 // If we want to iterate over all languages, we first have to complete the
133 // LanguagesMap.
134 static llvm::once_flag g_initialize;
135 llvm::call_once(g_initialize, [] {
136 for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes;
137 ++lang) {
138 FindPlugin(static_cast<lldb::LanguageType>(lang));
139 }
140 });
141
142 // callback may call a method in Language that attempts to acquire the same
143 // lock (such as Language::ForEach or Language::FindPlugin). To avoid a
144 // deadlock, we do not use callback while holding the lock.
145 std::vector<Language *> loaded_plugins;
146 {
147 std::lock_guard<std::mutex> guard(GetLanguagesMutex());
149 for (const auto &entry : map) {
150 if (entry.second)
151 loaded_plugins.push_back(entry.second.get());
152 }
153 }
154
155 for (auto *lang : loaded_plugins) {
156 if (!callback(lang))
157 break;
158 }
159}
160
161bool Language::IsTopLevelFunction(Function &function) { return false; }
162
164
166 return {};
167}
168
170 return {};
171}
172
175 return {};
176}
177
178std::vector<FormattersMatchCandidate>
180 lldb::DynamicValueType use_dynamic) {
181 return {};
182}
183
185 const char *name;
187};
188
190 // To allow GetNameForLanguageType to be a simple array lookup, the first
191 // part of this array must follow enum LanguageType exactly.
192 {"unknown", eLanguageTypeUnknown},
193 {"c89", eLanguageTypeC89},
194 {"c", eLanguageTypeC},
195 {"ada83", eLanguageTypeAda83},
197 {"cobol74", eLanguageTypeCobol74},
198 {"cobol85", eLanguageTypeCobol85},
199 {"fortran77", eLanguageTypeFortran77},
200 {"fortran90", eLanguageTypeFortran90},
201 {"pascal83", eLanguageTypePascal83},
202 {"modula2", eLanguageTypeModula2},
203 {"java", eLanguageTypeJava},
204 {"c99", eLanguageTypeC99},
205 {"ada95", eLanguageTypeAda95},
206 {"fortran95", eLanguageTypeFortran95},
207 {"pli", eLanguageTypePLI},
208 {"objective-c", eLanguageTypeObjC},
209 {"objective-c++", eLanguageTypeObjC_plus_plus},
210 {"upc", eLanguageTypeUPC},
211 {"d", eLanguageTypeD},
212 {"python", eLanguageTypePython},
213 {"opencl", eLanguageTypeOpenCL},
214 {"go", eLanguageTypeGo},
215 {"modula3", eLanguageTypeModula3},
216 {"haskell", eLanguageTypeHaskell},
219 {"ocaml", eLanguageTypeOCaml},
220 {"rust", eLanguageTypeRust},
221 {"c11", eLanguageTypeC11},
222 {"swift", eLanguageTypeSwift},
223 {"julia", eLanguageTypeJulia},
224 {"dylan", eLanguageTypeDylan},
226 {"fortran03", eLanguageTypeFortran03},
227 {"fortran08", eLanguageTypeFortran08},
228 {"renderscript", eLanguageTypeRenderScript},
229 {"bliss", eLanguageTypeBLISS},
230 {"kotlin", eLanguageTypeKotlin},
231 {"zig", eLanguageTypeZig},
232 {"crystal", eLanguageTypeCrystal},
233 {"<invalid language>",
234 static_cast<LanguageType>(
235 0x0029)}, // Not yet taken by any language in the DWARF spec
236 // and thus has no entry in LanguageType
239 {"c17", eLanguageTypeC17},
240 {"fortran18", eLanguageTypeFortran18},
241 {"ada2005", eLanguageTypeAda2005},
242 {"ada2012", eLanguageTypeAda2012},
243 {"HIP", eLanguageTypeHIP},
244 {"assembly", eLanguageTypeAssembly},
245 {"c-sharp", eLanguageTypeC_sharp},
246 {"mojo", eLanguageTypeMojo},
247 // Vendor Extensions
248 {"assembler", eLanguageTypeMipsAssembler},
249 // Now synonyms, in arbitrary order
250 {"objc", eLanguageTypeObjC},
251 {"objc++", eLanguageTypeObjC_plus_plus},
252 {"pascal", eLanguageTypePascal83}};
253
254static uint32_t num_languages =
255 sizeof(language_names) / sizeof(struct language_name_pair);
256
258 for (const auto &L : language_names) {
259 if (string.equals_insensitive(L.name))
260 return static_cast<LanguageType>(L.type);
261 }
262
264}
265
267 if (language < num_languages)
268 return language_names[language].name;
269 else
271}
272
274 llvm::StringRef prefix,
275 llvm::StringRef suffix) {
277 for (size_t idx = 0; idx < num_languages; ++idx) {
278 auto const &lang = language_names[idx];
279 if (supported[lang.type])
280 s << prefix << lang.name << suffix;
281 }
282}
283
284void Language::PrintAllLanguages(Stream &s, const char *prefix,
285 const char *suffix) {
286 for (uint32_t i = 1; i < num_languages; i++) {
287 s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
288 }
289}
290
292 std::function<bool(lldb::LanguageType)> callback) {
293 for (uint32_t i = 1; i < num_languages; i++) {
294 if (!callback(language_names[i].type))
295 break;
296 }
297}
298
300 switch (language) {
308 return true;
309 default:
310 return false;
311 }
312}
313
315 switch (language) {
318 return true;
319 default:
320 return false;
321 }
322}
323
325 switch (language) {
326 case eLanguageTypeC:
327 case eLanguageTypeC89:
328 case eLanguageTypeC99:
329 case eLanguageTypeC11:
330 return true;
331 default:
332 return false;
333 }
334}
335
337 switch (language) {
338 case eLanguageTypeC:
339 case eLanguageTypeC89:
340 case eLanguageTypeC99:
341 case eLanguageTypeC11:
350 return true;
351 default:
352 return false;
353 }
354}
355
357 switch (language) {
359 return true;
360 default:
361 return false;
362 }
363}
364
366 switch (language) {
374 case eLanguageTypeC:
375 case eLanguageTypeC89:
376 case eLanguageTypeC99:
377 case eLanguageTypeC11:
378 return eLanguageTypeC;
381 return eLanguageTypeObjC;
394 case eLanguageTypePLI:
395 case eLanguageTypeUPC:
396 case eLanguageTypeD:
399 case eLanguageTypeGo:
410 default:
411 return language;
412 }
413}
414
415std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
416 std::set<lldb::LanguageType> supported_languages;
417 ForEach([&](Language *lang) {
418 supported_languages.emplace(lang->GetLanguageType());
419 return true;
420 });
421 return supported_languages;
422}
423
426}
427
430}
431
434}
435
436std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
437 return nullptr;
438}
439
440const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
441
443 const char *key, ResultSet &results,
444 bool append) {
445 if (!exe_scope || !exe_scope->CalculateTarget().get())
446 return false;
447
448 if (!key || !key[0])
449 return false;
450
451 if (!append)
452 results.clear();
453
454 size_t old_size = results.size();
455
456 if (this->Find_Impl(exe_scope, key, results))
457 return results.size() - old_size;
458 return 0;
459}
460
462 ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
463 bool result = false;
464
465 Target *target = exe_scope->CalculateTarget().get();
466 if (target) {
467 const auto &images(target->GetImages());
468 TypeQuery query(key);
469 TypeResults type_results;
470 images.FindTypes(nullptr, query, type_results);
471 for (const auto &match : type_results.GetTypeMap().Types()) {
472 if (match) {
473 CompilerType compiler_type(match->GetFullCompilerType());
474 compiler_type = AdjustForInclusion(compiler_type);
475 if (!compiler_type)
476 continue;
477 std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
478 new Result(compiler_type));
479 results.insert(std::move(scavengeresult));
480 result = true;
481 }
482 }
483 }
484
485 return result;
486}
487
488std::pair<llvm::StringRef, llvm::StringRef>
489Language::GetFormatterPrefixSuffix(llvm::StringRef type_hint) {
490 return std::pair<llvm::StringRef, llvm::StringRef>();
491}
492
493bool Language::DemangledNameContainsPath(llvm::StringRef path,
494 ConstString demangled) const {
495 // The base implementation does a simple contains comparision:
496 if (path.empty())
497 return false;
498 return demangled.GetStringRef().contains(path);
499}
500
502 return nullptr;
503}
504
506 return eLazyBoolCalculate;
507}
508
509bool Language::IsNilReference(ValueObject &valobj) { return false; }
510
511bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
512
514 const ExecutionContext *exe_ctx,
515 FunctionNameRepresentation representation,
516 Stream &s) {
517 return false;
518}
519
520void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
521 Stream &s) {
522 GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
523}
524
526 bool throw_on,
527 Stream &s) {
528 s.Printf("Exception breakpoint (catch: %s throw: %s)",
529 catch_on ? "on" : "off", throw_on ? "on" : "off");
530}
531// Constructor
532Language::Language() = default;
533
534// Destructor
535Language::~Language() = default;
536
538 auto lname =
539 llvm::dwarf::toDW_LNAME((llvm::dwarf::SourceLanguage)language_type);
540 if (!lname)
541 return;
542 name = lname->first;
543 version = lname->second;
544}
545
547 if (auto lang = llvm::dwarf::toDW_LANG((llvm::dwarf::SourceLanguageName)name,
548 version))
549 return (lldb::LanguageType)*lang;
551}
552
553llvm::StringRef SourceLanguage::GetDescription() const {
554 LanguageType type = AsLanguageType();
555 if (type)
557 return llvm::dwarf::LanguageDescription(
558 (llvm::dwarf::SourceLanguageName)name);
559}
560bool SourceLanguage::IsC() const { return name == llvm::dwarf::DW_LNAME_C; }
561
563 return name == llvm::dwarf::DW_LNAME_ObjC;
564}
565
567 return name == llvm::dwarf::DW_LNAME_C_plus_plus;
568}
static llvm::raw_ostream & error(Stream &strm)
struct language_name_pair language_names[]
Definition: Language.cpp:189
std::map< lldb::LanguageType, LanguageUP > LanguagesMap
Definition: Language.cpp:30
static LanguagesMap & GetLanguagesMap()
Definition: Language.cpp:61
static uint32_t num_languages
Definition: Language.cpp:254
static std::mutex & GetLanguagesMutex()
Definition: Language.cpp:72
std::unique_ptr< Language > LanguageUP
Definition: Language.cpp:29
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:45
bool GetEnableFilterForLineBreakpoints() const
Definition: Language.cpp:55
bool Find_Impl(ExecutionContextScope *exe_scope, const char *key, ResultSet &results) override
Definition: Language.cpp:461
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:442
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:273
static LanguageSet GetLanguagesSupportingREPLs()
Definition: Language.cpp:432
static LanguageSet GetLanguagesSupportingTypeSystems()
Definition: Language.cpp:424
virtual std::vector< FormattersMatchCandidate > GetPossibleFormattersMatches(ValueObject &valobj, lldb::DynamicValueType use_dynamic)
Definition: Language.cpp:179
virtual lldb::TypeCategoryImplSP GetFormatters()
Definition: Language.cpp:163
static Language * FindPlugin(lldb::LanguageType language)
Definition: Language.cpp:84
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition: Language.cpp:266
virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper()
Definition: Language.cpp:501
static LanguageProperties & GetGlobalLanguageProperties()
Definition: Language.cpp:40
virtual LazyBool IsLogicalTrue(ValueObject &valobj, Status &error)
Definition: Language.cpp:505
virtual const char * GetLanguageSpecificTypeLookupHelp()
Definition: Language.cpp:440
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:489
static bool LanguageIsC(lldb::LanguageType language)
Definition: Language.cpp:324
virtual lldb::LanguageType GetLanguageType() const =0
virtual HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries()
Definition: Language.cpp:169
static void GetDefaultExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s)
Definition: Language.cpp:525
virtual bool DemangledNameContainsPath(llvm::StringRef path, ConstString demangled) const
Definition: Language.cpp:493
static bool LanguageIsCPlusPlus(lldb::LanguageType language)
Definition: Language.cpp:299
static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language)
Definition: Language.cpp:365
static bool LanguageIsPascal(lldb::LanguageType language)
Definition: Language.cpp:356
virtual bool IsNilReference(ValueObject &valobj)
Definition: Language.cpp:509
static void ForAllLanguages(std::function< bool(lldb::LanguageType)> callback)
Definition: Language.cpp:291
virtual bool IsUninitializedReference(ValueObject &valobj)
Definition: Language.cpp:511
virtual bool GetFunctionDisplayName(const SymbolContext *sc, const ExecutionContext *exe_ctx, FunctionNameRepresentation representation, Stream &s)
Definition: Language.cpp:513
static void PrintAllLanguages(Stream &s, const char *prefix, const char *suffix)
Definition: Language.cpp:284
virtual HardcodedFormatters::HardcodedSyntheticFinder GetHardcodedSynthetics()
Definition: Language.cpp:174
virtual std::unique_ptr< TypeScavenger > GetTypeScavenger()
Definition: Language.cpp:436
static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions()
Definition: Language.cpp:428
virtual bool IsTopLevelFunction(Function &function)
Definition: Language.cpp:161
virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s)
Definition: Language.cpp:520
static lldb::LanguageType GetLanguageTypeFromString(const char *string)=delete
static void ForEach(std::function< bool(Language *)> callback)
Definition: Language.cpp:131
static bool LanguageIsCFamily(lldb::LanguageType language)
Equivalent to LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
Definition: Language.cpp:336
static std::set< lldb::LanguageType > GetSupportedLanguages()
Definition: Language.cpp:415
virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats()
Definition: Language.cpp:165
static bool LanguageIsObjC(lldb::LanguageType language)
Definition: Language.cpp:314
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:981
TypeIterable Types() const
Definition: TypeMap.h:49
A class that contains all state required for type lookups.
Definition: Type.h:100
This class tracks the state and results of a TypeQuery.
Definition: Type.h:308
TypeMap & GetTypeMap()
Definition: Type.h:350
A class that represents a running process on the host machine.
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:457
LanguageType type
Definition: Language.cpp:186
const char * name
Definition: Language.cpp:185
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition: Type.h:38
lldb::LanguageType AsLanguageType() const
Definition: Language.cpp:546
llvm::StringRef GetDescription() const
Definition: Language.cpp:553