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
18#include "lldb/Target/Target.h"
19#include "lldb/Utility/Stream.h"
20
21#include "llvm/Support/Threading.h"
22
23using namespace lldb;
24using namespace lldb_private;
25using namespace lldb_private::formatters;
26
27typedef std::unique_ptr<Language> LanguageUP;
28typedef 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}
41static 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
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 =
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
78Language *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
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
100void 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
130bool Language::IsTopLevelFunction(Function &function) { return false; }
131
133
135 return {};
136}
137
139 return {};
140}
141
144 return {};
145}
146
147std::vector<FormattersMatchCandidate>
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},
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},
188 {"ocaml", eLanguageTypeOCaml},
189 {"rust", eLanguageTypeRust},
190 {"c11", eLanguageTypeC11},
191 {"swift", eLanguageTypeSwift},
192 {"julia", eLanguageTypeJulia},
193 {"dylan", eLanguageTypeDylan},
195 {"fortran03", eLanguageTypeFortran03},
196 {"fortran08", eLanguageTypeFortran08},
197 {"renderscript", eLanguageTypeRenderScript},
198 {"bliss", eLanguageTypeBLISS},
199 {"kotlin", eLanguageTypeKotlin},
200 {"zig", eLanguageTypeZig},
201 {"crystal", eLanguageTypeCrystal},
202 {"<invalid language>",
203 static_cast<LanguageType>(
204 0x0029)}, // Not yet taken by any language in the DWARF spec
205 // and thus has no entry in LanguageType
208 {"c17", eLanguageTypeC17},
209 {"fortran18", eLanguageTypeFortran18},
210 {"ada2005", eLanguageTypeAda2005},
211 {"ada2012", eLanguageTypeAda2012},
212 {"HIP", eLanguageTypeHIP},
213 {"assembly", eLanguageTypeAssembly},
214 {"c-sharp", eLanguageTypeC_sharp},
215 {"mojo", eLanguageTypeMojo},
216 // Vendor Extensions
217 {"assembler", eLanguageTypeMipsAssembler},
218 // Now synonyms, in arbitrary order
219 {"objc", eLanguageTypeObjC},
220 {"objc++", eLanguageTypeObjC_plus_plus},
221 {"pascal", eLanguageTypePascal83}};
222
223static uint32_t num_languages =
224 sizeof(language_names) / sizeof(struct language_name_pair);
225
227 for (const auto &L : language_names) {
228 if (string.equals_insensitive(L.name))
229 return static_cast<LanguageType>(L.type);
230 }
231
233}
234
236 if (language < num_languages)
237 return language_names[language].name;
238 else
240}
241
243 llvm::StringRef prefix,
244 llvm::StringRef suffix) {
246 for (size_t idx = 0; idx < num_languages; ++idx) {
247 auto const &lang = language_names[idx];
248 if (supported[lang.type])
249 s << prefix << lang.name << suffix;
250 }
251}
252
253void Language::PrintAllLanguages(Stream &s, const char *prefix,
254 const char *suffix) {
255 for (uint32_t i = 1; i < num_languages; i++) {
256 s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
257 }
258}
259
261 std::function<bool(lldb::LanguageType)> callback) {
262 for (uint32_t i = 1; i < num_languages; i++) {
263 if (!callback(language_names[i].type))
264 break;
265 }
266}
267
269 switch (language) {
277 return true;
278 default:
279 return false;
280 }
281}
282
284 switch (language) {
287 return true;
288 default:
289 return false;
290 }
291}
292
294 switch (language) {
295 case eLanguageTypeC:
296 case eLanguageTypeC89:
297 case eLanguageTypeC99:
298 case eLanguageTypeC11:
299 return true;
300 default:
301 return false;
302 }
303}
304
306 switch (language) {
307 case eLanguageTypeC:
308 case eLanguageTypeC89:
309 case eLanguageTypeC99:
310 case eLanguageTypeC11:
319 return true;
320 default:
321 return false;
322 }
323}
324
326 switch (language) {
328 return true;
329 default:
330 return false;
331 }
332}
333
335 switch (language) {
343 case eLanguageTypeC:
344 case eLanguageTypeC89:
345 case eLanguageTypeC99:
346 case eLanguageTypeC11:
347 return eLanguageTypeC;
350 return eLanguageTypeObjC;
363 case eLanguageTypePLI:
364 case eLanguageTypeUPC:
365 case eLanguageTypeD:
368 case eLanguageTypeGo:
379 default:
380 return language;
381 }
382}
383
384std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
385 std::set<lldb::LanguageType> supported_languages;
386 ForEach([&](Language *lang) {
387 supported_languages.emplace(lang->GetLanguageType());
388 return true;
389 });
390 return supported_languages;
391}
392
395}
396
399}
400
403}
404
405std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
406 return nullptr;
407}
408
409const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
410
412 const char *key, ResultSet &results,
413 bool append) {
414 if (!exe_scope || !exe_scope->CalculateTarget().get())
415 return false;
416
417 if (!key || !key[0])
418 return false;
419
420 if (!append)
421 results.clear();
422
423 size_t old_size = results.size();
424
425 if (this->Find_Impl(exe_scope, key, results))
426 return results.size() - old_size;
427 return 0;
428}
429
431 ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
432 bool result = false;
433
434 Target *target = exe_scope->CalculateTarget().get();
435 if (target) {
436 const auto &images(target->GetImages());
437 ConstString cs_key(key);
438 llvm::DenseSet<SymbolFile *> searched_sym_files;
439 TypeList matches;
440 images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files,
441 matches);
442 for (const auto &match : matches.Types()) {
443 if (match) {
444 CompilerType compiler_type(match->GetFullCompilerType());
445 compiler_type = AdjustForInclusion(compiler_type);
446 if (!compiler_type)
447 continue;
448 std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
449 new Result(compiler_type));
450 results.insert(std::move(scavengeresult));
451 result = true;
452 }
453 }
454 }
455
456 return result;
457}
458
459std::pair<llvm::StringRef, llvm::StringRef>
460Language::GetFormatterPrefixSuffix(llvm::StringRef type_hint) {
461 return std::pair<llvm::StringRef, llvm::StringRef>();
462}
463
464bool Language::DemangledNameContainsPath(llvm::StringRef path,
465 ConstString demangled) const {
466 // The base implementation does a simple contains comparision:
467 if (path.empty())
468 return false;
469 return demangled.GetStringRef().contains(path);
470}
471
473 return nullptr;
474}
475
477 return eLazyBoolCalculate;
478}
479
480bool Language::IsNilReference(ValueObject &valobj) { return false; }
481
482bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
483
485 const ExecutionContext *exe_ctx,
486 FunctionNameRepresentation representation,
487 Stream &s) {
488 return false;
489}
490
491void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
492 Stream &s) {
493 GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
494}
495
497 bool throw_on,
498 Stream &s) {
499 s.Printf("Exception breakpoint (catch: %s throw: %s)",
500 catch_on ? "on" : "off", throw_on ? "on" : "off");
501}
502// Constructor
503Language::Language() = default;
504
505// Destructor
506Language::~Language() = default;
static llvm::raw_ostream & error(Stream &strm)
struct language_name_pair language_names[]
Definition: Language.cpp:158
std::map< lldb::LanguageType, LanguageUP > LanguagesMap
Definition: Language.cpp:28
static LanguagesMap & GetLanguagesMap()
Definition: Language.cpp:30
static uint32_t num_languages
Definition: Language.cpp:223
static std::mutex & GetLanguagesMutex()
Definition: Language.cpp:41
std::unique_ptr< Language > LanguageUP
Definition: Language.cpp:27
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:191
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
bool Find_Impl(ExecutionContextScope *exe_scope, const char *key, ResultSet &results) override
Definition: Language.cpp:430
std::set< std::unique_ptr< Result > > ResultSet
Definition: Language.h:43
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:411
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:242
static LanguageSet GetLanguagesSupportingREPLs()
Definition: Language.cpp:401
static LanguageSet GetLanguagesSupportingTypeSystems()
Definition: Language.cpp:393
virtual std::vector< FormattersMatchCandidate > GetPossibleFormattersMatches(ValueObject &valobj, lldb::DynamicValueType use_dynamic)
Definition: Language.cpp:148
virtual lldb::TypeCategoryImplSP GetFormatters()
Definition: Language.cpp:132
static Language * FindPlugin(lldb::LanguageType language)
Definition: Language.cpp:53
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition: Language.cpp:235
virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper()
Definition: Language.cpp:472
virtual LazyBool IsLogicalTrue(ValueObject &valobj, Status &error)
Definition: Language.cpp:476
virtual const char * GetLanguageSpecificTypeLookupHelp()
Definition: Language.cpp:409
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:460
static bool LanguageIsC(lldb::LanguageType language)
Definition: Language.cpp:293
virtual lldb::LanguageType GetLanguageType() const =0
virtual HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries()
Definition: Language.cpp:138
static void GetDefaultExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s)
Definition: Language.cpp:496
virtual bool DemangledNameContainsPath(llvm::StringRef path, ConstString demangled) const
Definition: Language.cpp:464
static bool LanguageIsCPlusPlus(lldb::LanguageType language)
Definition: Language.cpp:268
static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language)
Definition: Language.cpp:334
static bool LanguageIsPascal(lldb::LanguageType language)
Definition: Language.cpp:325
virtual bool IsNilReference(ValueObject &valobj)
Definition: Language.cpp:480
static void ForAllLanguages(std::function< bool(lldb::LanguageType)> callback)
Definition: Language.cpp:260
virtual bool IsUninitializedReference(ValueObject &valobj)
Definition: Language.cpp:482
virtual bool GetFunctionDisplayName(const SymbolContext *sc, const ExecutionContext *exe_ctx, FunctionNameRepresentation representation, Stream &s)
Definition: Language.cpp:484
static void PrintAllLanguages(Stream &s, const char *prefix, const char *suffix)
Definition: Language.cpp:253
virtual HardcodedFormatters::HardcodedSyntheticFinder GetHardcodedSynthetics()
Definition: Language.cpp:143
virtual std::unique_ptr< TypeScavenger > GetTypeScavenger()
Definition: Language.cpp:405
static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions()
Definition: Language.cpp:397
virtual bool IsTopLevelFunction(Function &function)
Definition: Language.cpp:130
virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s)
Definition: Language.cpp:491
static lldb::LanguageType GetLanguageTypeFromString(const char *string)=delete
static void ForEach(std::function< bool(Language *)> callback)
Definition: Language.cpp:100
static bool LanguageIsCFamily(lldb::LanguageType language)
Equivalent to LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
Definition: Language.cpp:305
static std::set< lldb::LanguageType > GetSupportedLanguages()
Definition: Language.cpp:384
virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats()
Definition: Language.cpp:134
static bool LanguageIsObjC(lldb::LanguageType language)
Definition: Language.cpp:283
static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions()
static LanguageSet GetREPLAllTypeSystemSupportedLanguages()
static LanguageCreateInstance GetLanguageCreateCallbackAtIndex(uint32_t idx)
static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes()
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:107
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:967
TypeList FindTypes(ConstString name)
TypeIterable Types()
Definition: TypeList.h:45
#define UINT32_MAX
Definition: lldb-defines.h:19
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:438
LanguageType type
Definition: Language.cpp:155
const char * name
Definition: Language.cpp:154
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
Definition: TypeSystem.h:45