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 | |
13 | #include "lldb/Target/Language.h" |
14 | |
15 | #include "lldb/Core/PluginManager.h" |
16 | #include "lldb/Interpreter/OptionValueProperties.h" |
17 | #include "lldb/Symbol/SymbolFile.h" |
18 | #include "lldb/Symbol/TypeList.h" |
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 | |
25 | using namespace lldb; |
26 | using namespace lldb_private; |
27 | using namespace lldb_private::formatters; |
28 | |
29 | typedef std::unique_ptr<Language> LanguageUP; |
30 | typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap; |
31 | |
32 | #define LLDB_PROPERTIES_language |
33 | #include "TargetProperties.inc" |
34 | |
35 | enum { |
36 | #define LLDB_PROPERTIES_language |
37 | #include "TargetPropertiesEnum.inc" |
38 | }; |
39 | |
40 | LanguageProperties &Language::GetGlobalLanguageProperties() { |
41 | static LanguageProperties g_settings; |
42 | return g_settings; |
43 | } |
44 | |
45 | llvm::StringRef LanguageProperties::GetSettingName() { |
46 | static constexpr llvm::StringLiteral g_setting_name("language"); |
47 | return g_setting_name; |
48 | } |
49 | |
50 | LanguageProperties::LanguageProperties() { |
51 | m_collection_sp = std::make_shared<OptionValueProperties>(args: GetSettingName()); |
52 | m_collection_sp->Initialize(setting_definitions: g_language_properties); |
53 | } |
54 | |
55 | bool LanguageProperties::GetEnableFilterForLineBreakpoints() const { |
56 | const uint32_t idx = ePropertyEnableFilterForLineBreakpoints; |
57 | return GetPropertyAtIndexAs<bool>( |
58 | idx, g_language_properties[idx].default_uint_value != 0); |
59 | } |
60 | |
61 | static LanguagesMap &GetLanguagesMap() { |
62 | static LanguagesMap *g_map = nullptr; |
63 | static llvm::once_flag g_initialize; |
64 | |
65 | llvm::call_once(flag&: g_initialize, F: [] { |
66 | g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global |
67 | // destructor chain |
68 | }); |
69 | |
70 | return *g_map; |
71 | } |
72 | static std::mutex &GetLanguagesMutex() { |
73 | static std::mutex *g_mutex = nullptr; |
74 | static llvm::once_flag g_initialize; |
75 | |
76 | llvm::call_once(flag&: g_initialize, F: [] { |
77 | g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global |
78 | // destructor chain |
79 | }); |
80 | |
81 | return *g_mutex; |
82 | } |
83 | |
84 | Language *Language::FindPlugin(lldb::LanguageType language) { |
85 | std::lock_guard<std::mutex> guard(GetLanguagesMutex()); |
86 | LanguagesMap &map(GetLanguagesMap()); |
87 | auto iter = map.find(x: 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 = |
96 | PluginManager::GetLanguageCreateCallbackAtIndex(idx)) != nullptr; |
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 | |
109 | Language *Language::FindPlugin(llvm::StringRef file_path) { |
110 | Language *result = nullptr; |
111 | ForEach(callback: [&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 | |
121 | Language *Language::FindPlugin(LanguageType language, |
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 | |
131 | void 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(flag&: g_initialize, F: [] { |
136 | for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes; |
137 | ++lang) { |
138 | FindPlugin(language: 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()); |
148 | LanguagesMap &map(GetLanguagesMap()); |
149 | for (const auto &entry : map) { |
150 | if (entry.second) |
151 | loaded_plugins.push_back(x: entry.second.get()); |
152 | } |
153 | } |
154 | |
155 | for (auto *lang : loaded_plugins) { |
156 | if (!callback(lang)) |
157 | break; |
158 | } |
159 | } |
160 | |
161 | bool Language::IsTopLevelFunction(Function &function) { return false; } |
162 | |
163 | lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; } |
164 | |
165 | HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats() { |
166 | return {}; |
167 | } |
168 | |
169 | HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries() { |
170 | return {}; |
171 | } |
172 | |
173 | HardcodedFormatters::HardcodedSyntheticFinder |
174 | Language::GetHardcodedSynthetics() { |
175 | return {}; |
176 | } |
177 | |
178 | std::vector<FormattersMatchCandidate> |
179 | Language::GetPossibleFormattersMatches(ValueObject &valobj, |
180 | lldb::DynamicValueType use_dynamic) { |
181 | return {}; |
182 | } |
183 | |
184 | struct language_name_pair { |
185 | const char *name; |
186 | LanguageType type; |
187 | }; |
188 | |
189 | struct language_name_pair language_names[] = { |
190 | // To allow GetNameForLanguageType to be a simple array lookup, the first |
191 | // part of this array must follow enum LanguageType exactly. |
192 | {.name: "unknown", .type: eLanguageTypeUnknown}, |
193 | {.name: "c89", .type: eLanguageTypeC89}, |
194 | {.name: "c", .type: eLanguageTypeC}, |
195 | {.name: "ada83", .type: eLanguageTypeAda83}, |
196 | {.name: "c++", .type: eLanguageTypeC_plus_plus}, |
197 | {.name: "cobol74", .type: eLanguageTypeCobol74}, |
198 | {.name: "cobol85", .type: eLanguageTypeCobol85}, |
199 | {.name: "fortran77", .type: eLanguageTypeFortran77}, |
200 | {.name: "fortran90", .type: eLanguageTypeFortran90}, |
201 | {.name: "pascal83", .type: eLanguageTypePascal83}, |
202 | {.name: "modula2", .type: eLanguageTypeModula2}, |
203 | {.name: "java", .type: eLanguageTypeJava}, |
204 | {.name: "c99", .type: eLanguageTypeC99}, |
205 | {.name: "ada95", .type: eLanguageTypeAda95}, |
206 | {.name: "fortran95", .type: eLanguageTypeFortran95}, |
207 | {.name: "pli", .type: eLanguageTypePLI}, |
208 | {.name: "objective-c", .type: eLanguageTypeObjC}, |
209 | {.name: "objective-c++", .type: eLanguageTypeObjC_plus_plus}, |
210 | {.name: "upc", .type: eLanguageTypeUPC}, |
211 | {.name: "d", .type: eLanguageTypeD}, |
212 | {.name: "python", .type: eLanguageTypePython}, |
213 | {.name: "opencl", .type: eLanguageTypeOpenCL}, |
214 | {.name: "go", .type: eLanguageTypeGo}, |
215 | {.name: "modula3", .type: eLanguageTypeModula3}, |
216 | {.name: "haskell", .type: eLanguageTypeHaskell}, |
217 | {.name: "c++03", .type: eLanguageTypeC_plus_plus_03}, |
218 | {.name: "c++11", .type: eLanguageTypeC_plus_plus_11}, |
219 | {.name: "ocaml", .type: eLanguageTypeOCaml}, |
220 | {.name: "rust", .type: eLanguageTypeRust}, |
221 | {.name: "c11", .type: eLanguageTypeC11}, |
222 | {.name: "swift", .type: eLanguageTypeSwift}, |
223 | {.name: "julia", .type: eLanguageTypeJulia}, |
224 | {.name: "dylan", .type: eLanguageTypeDylan}, |
225 | {.name: "c++14", .type: eLanguageTypeC_plus_plus_14}, |
226 | {.name: "fortran03", .type: eLanguageTypeFortran03}, |
227 | {.name: "fortran08", .type: eLanguageTypeFortran08}, |
228 | {.name: "renderscript", .type: eLanguageTypeRenderScript}, |
229 | {.name: "bliss", .type: eLanguageTypeBLISS}, |
230 | {.name: "kotlin", .type: eLanguageTypeKotlin}, |
231 | {.name: "zig", .type: eLanguageTypeZig}, |
232 | {.name: "crystal", .type: eLanguageTypeCrystal}, |
233 | {.name: "<invalid language>", |
234 | .type: static_cast<LanguageType>( |
235 | 0x0029)}, // Not yet taken by any language in the DWARF spec |
236 | // and thus has no entry in LanguageType |
237 | {.name: "c++17", .type: eLanguageTypeC_plus_plus_17}, |
238 | {.name: "c++20", .type: eLanguageTypeC_plus_plus_20}, |
239 | {.name: "c17", .type: eLanguageTypeC17}, |
240 | {.name: "fortran18", .type: eLanguageTypeFortran18}, |
241 | {.name: "ada2005", .type: eLanguageTypeAda2005}, |
242 | {.name: "ada2012", .type: eLanguageTypeAda2012}, |
243 | {.name: "HIP", .type: eLanguageTypeHIP}, |
244 | {.name: "assembly", .type: eLanguageTypeAssembly}, |
245 | {.name: "c-sharp", .type: eLanguageTypeC_sharp}, |
246 | {.name: "mojo", .type: eLanguageTypeMojo}, |
247 | // Vendor Extensions |
248 | {.name: "assembler", .type: eLanguageTypeMipsAssembler}, |
249 | // Now synonyms, in arbitrary order |
250 | {.name: "objc", .type: eLanguageTypeObjC}, |
251 | {.name: "objc++", .type: eLanguageTypeObjC_plus_plus}, |
252 | {.name: "pascal", .type: eLanguageTypePascal83}}; |
253 | |
254 | static uint32_t num_languages = |
255 | sizeof(language_names) / sizeof(struct language_name_pair); |
256 | |
257 | LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) { |
258 | for (const auto &L : language_names) { |
259 | if (string.equals_insensitive(RHS: L.name)) |
260 | return static_cast<LanguageType>(L.type); |
261 | } |
262 | |
263 | return eLanguageTypeUnknown; |
264 | } |
265 | |
266 | const char *Language::GetNameForLanguageType(LanguageType language) { |
267 | if (language < num_languages) |
268 | return language_names[language].name; |
269 | else |
270 | return language_names[eLanguageTypeUnknown].name; |
271 | } |
272 | |
273 | void Language::PrintSupportedLanguagesForExpressions(Stream &s, |
274 | llvm::StringRef prefix, |
275 | llvm::StringRef suffix) { |
276 | auto supported = Language::GetLanguagesSupportingTypeSystemsForExpressions(); |
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 | |
284 | void Language::PrintAllLanguages(Stream &s, const char *prefix, |
285 | const char *suffix) { |
286 | for (uint32_t i = 1; i < num_languages; i++) { |
287 | s.Printf(format: "%s%s%s", prefix, language_names[i].name, suffix); |
288 | } |
289 | } |
290 | |
291 | void Language::ForAllLanguages( |
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 | |
299 | bool Language::LanguageIsCPlusPlus(LanguageType language) { |
300 | switch (language) { |
301 | case eLanguageTypeC_plus_plus: |
302 | case eLanguageTypeC_plus_plus_03: |
303 | case eLanguageTypeC_plus_plus_11: |
304 | case eLanguageTypeC_plus_plus_14: |
305 | case eLanguageTypeC_plus_plus_17: |
306 | case eLanguageTypeC_plus_plus_20: |
307 | case eLanguageTypeObjC_plus_plus: |
308 | return true; |
309 | default: |
310 | return false; |
311 | } |
312 | } |
313 | |
314 | bool Language::LanguageIsObjC(LanguageType language) { |
315 | switch (language) { |
316 | case eLanguageTypeObjC: |
317 | case eLanguageTypeObjC_plus_plus: |
318 | return true; |
319 | default: |
320 | return false; |
321 | } |
322 | } |
323 | |
324 | bool Language::LanguageIsC(LanguageType language) { |
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 | |
336 | bool Language::LanguageIsCFamily(LanguageType language) { |
337 | switch (language) { |
338 | case eLanguageTypeC: |
339 | case eLanguageTypeC89: |
340 | case eLanguageTypeC99: |
341 | case eLanguageTypeC11: |
342 | case eLanguageTypeC_plus_plus: |
343 | case eLanguageTypeC_plus_plus_03: |
344 | case eLanguageTypeC_plus_plus_11: |
345 | case eLanguageTypeC_plus_plus_14: |
346 | case eLanguageTypeC_plus_plus_17: |
347 | case eLanguageTypeC_plus_plus_20: |
348 | case eLanguageTypeObjC_plus_plus: |
349 | case eLanguageTypeObjC: |
350 | return true; |
351 | default: |
352 | return false; |
353 | } |
354 | } |
355 | |
356 | bool Language::LanguageIsPascal(LanguageType language) { |
357 | switch (language) { |
358 | case eLanguageTypePascal83: |
359 | return true; |
360 | default: |
361 | return false; |
362 | } |
363 | } |
364 | |
365 | LanguageType Language::GetPrimaryLanguage(LanguageType language) { |
366 | switch (language) { |
367 | case eLanguageTypeC_plus_plus: |
368 | case eLanguageTypeC_plus_plus_03: |
369 | case eLanguageTypeC_plus_plus_11: |
370 | case eLanguageTypeC_plus_plus_14: |
371 | case eLanguageTypeC_plus_plus_17: |
372 | case eLanguageTypeC_plus_plus_20: |
373 | return eLanguageTypeC_plus_plus; |
374 | case eLanguageTypeC: |
375 | case eLanguageTypeC89: |
376 | case eLanguageTypeC99: |
377 | case eLanguageTypeC11: |
378 | return eLanguageTypeC; |
379 | case eLanguageTypeObjC: |
380 | case eLanguageTypeObjC_plus_plus: |
381 | return eLanguageTypeObjC; |
382 | case eLanguageTypePascal83: |
383 | case eLanguageTypeCobol74: |
384 | case eLanguageTypeCobol85: |
385 | case eLanguageTypeFortran77: |
386 | case eLanguageTypeFortran90: |
387 | case eLanguageTypeFortran95: |
388 | case eLanguageTypeFortran03: |
389 | case eLanguageTypeFortran08: |
390 | case eLanguageTypeAda83: |
391 | case eLanguageTypeAda95: |
392 | case eLanguageTypeModula2: |
393 | case eLanguageTypeJava: |
394 | case eLanguageTypePLI: |
395 | case eLanguageTypeUPC: |
396 | case eLanguageTypeD: |
397 | case eLanguageTypePython: |
398 | case eLanguageTypeOpenCL: |
399 | case eLanguageTypeGo: |
400 | case eLanguageTypeModula3: |
401 | case eLanguageTypeHaskell: |
402 | case eLanguageTypeOCaml: |
403 | case eLanguageTypeRust: |
404 | case eLanguageTypeSwift: |
405 | case eLanguageTypeJulia: |
406 | case eLanguageTypeDylan: |
407 | case eLanguageTypeMipsAssembler: |
408 | case eLanguageTypeMojo: |
409 | case eLanguageTypeUnknown: |
410 | default: |
411 | return language; |
412 | } |
413 | } |
414 | |
415 | std::set<lldb::LanguageType> Language::GetSupportedLanguages() { |
416 | std::set<lldb::LanguageType> supported_languages; |
417 | ForEach(callback: [&](Language *lang) { |
418 | supported_languages.emplace(args: lang->GetLanguageType()); |
419 | return true; |
420 | }); |
421 | return supported_languages; |
422 | } |
423 | |
424 | LanguageSet Language::GetLanguagesSupportingTypeSystems() { |
425 | return PluginManager::GetAllTypeSystemSupportedLanguagesForTypes(); |
426 | } |
427 | |
428 | LanguageSet Language::GetLanguagesSupportingTypeSystemsForExpressions() { |
429 | return PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions(); |
430 | } |
431 | |
432 | LanguageSet Language::GetLanguagesSupportingREPLs() { |
433 | return PluginManager::GetREPLAllTypeSystemSupportedLanguages(); |
434 | } |
435 | |
436 | std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() { |
437 | return nullptr; |
438 | } |
439 | |
440 | const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; } |
441 | |
442 | size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope, |
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 | |
461 | bool Language::ImageListTypeScavenger::Find_Impl( |
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(search_first: nullptr, query, results&: type_results); |
471 | for (const auto &match : type_results.GetTypeMap().Types()) { |
472 | if (match) { |
473 | CompilerType compiler_type(match->GetFullCompilerType()); |
474 | compiler_type = AdjustForInclusion(candidate&: compiler_type); |
475 | if (!compiler_type) |
476 | continue; |
477 | std::unique_ptr<Language::TypeScavenger::Result> scavengeresult( |
478 | new Result(compiler_type)); |
479 | results.insert(x: std::move(scavengeresult)); |
480 | result = true; |
481 | } |
482 | } |
483 | } |
484 | |
485 | return result; |
486 | } |
487 | |
488 | std::pair<llvm::StringRef, llvm::StringRef> |
489 | Language::GetFormatterPrefixSuffix(llvm::StringRef type_hint) { |
490 | return std::pair<llvm::StringRef, llvm::StringRef>(); |
491 | } |
492 | |
493 | bool 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(Other: path); |
499 | } |
500 | |
501 | DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() { |
502 | return nullptr; |
503 | } |
504 | |
505 | LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) { |
506 | return eLazyBoolCalculate; |
507 | } |
508 | |
509 | bool Language::IsNilReference(ValueObject &valobj) { return false; } |
510 | |
511 | bool Language::IsUninitializedReference(ValueObject &valobj) { return false; } |
512 | |
513 | bool Language::GetFunctionDisplayName(const SymbolContext &sc, |
514 | const ExecutionContext *exe_ctx, |
515 | FunctionNameRepresentation representation, |
516 | Stream &s) { |
517 | return false; |
518 | } |
519 | |
520 | void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on, |
521 | Stream &s) { |
522 | GetDefaultExceptionResolverDescription(catch_on, throw_on, s); |
523 | } |
524 | |
525 | void Language::GetDefaultExceptionResolverDescription(bool catch_on, |
526 | bool throw_on, |
527 | Stream &s) { |
528 | s.Printf(format: "Exception breakpoint (catch: %s throw: %s)", |
529 | catch_on ? "on": "off", throw_on ? "on": "off"); |
530 | } |
531 | |
532 | std::optional<bool> Language::GetBooleanFromString(llvm::StringRef str) const { |
533 | return llvm::StringSwitch<std::optional<bool>>(str) |
534 | .Case(S: "true", Value: {true}) |
535 | .Case(S: "false", Value: {false}) |
536 | .Default(Value: {}); |
537 | } |
538 | |
539 | // Constructor |
540 | Language::Language() = default; |
541 | |
542 | // Destructor |
543 | Language::~Language() = default; |
544 | |
545 | SourceLanguage::SourceLanguage(lldb::LanguageType language_type) { |
546 | auto lname = |
547 | llvm::dwarf::toDW_LNAME(language: (llvm::dwarf::SourceLanguage)language_type); |
548 | if (!lname) |
549 | return; |
550 | name = lname->first; |
551 | version = lname->second; |
552 | } |
553 | |
554 | lldb::LanguageType SourceLanguage::AsLanguageType() const { |
555 | if (auto lang = llvm::dwarf::toDW_LANG(name: (llvm::dwarf::SourceLanguageName)name, |
556 | version)) |
557 | return (lldb::LanguageType)*lang; |
558 | return lldb::eLanguageTypeUnknown; |
559 | } |
560 | |
561 | llvm::StringRef SourceLanguage::GetDescription() const { |
562 | LanguageType type = AsLanguageType(); |
563 | if (type) |
564 | return Language::GetNameForLanguageType(language: type); |
565 | return llvm::dwarf::LanguageDescription( |
566 | name: (llvm::dwarf::SourceLanguageName)name); |
567 | } |
568 | bool SourceLanguage::IsC() const { return name == llvm::dwarf::DW_LNAME_C; } |
569 | |
570 | bool SourceLanguage::IsObjC() const { |
571 | return name == llvm::dwarf::DW_LNAME_ObjC; |
572 | } |
573 | |
574 | bool SourceLanguage::IsCPlusPlus() const { |
575 | return name == llvm::dwarf::DW_LNAME_C_plus_plus; |
576 | } |
577 |
Definitions
- GetGlobalLanguageProperties
- GetSettingName
- LanguageProperties
- GetEnableFilterForLineBreakpoints
- GetLanguagesMap
- GetLanguagesMutex
- FindPlugin
- FindPlugin
- FindPlugin
- ForEach
- IsTopLevelFunction
- GetFormatters
- GetHardcodedFormats
- GetHardcodedSummaries
- GetHardcodedSynthetics
- GetPossibleFormattersMatches
- language_name_pair
- language_names
- num_languages
- GetLanguageTypeFromString
- GetNameForLanguageType
- PrintSupportedLanguagesForExpressions
- PrintAllLanguages
- ForAllLanguages
- LanguageIsCPlusPlus
- LanguageIsObjC
- LanguageIsC
- LanguageIsCFamily
- LanguageIsPascal
- GetPrimaryLanguage
- GetSupportedLanguages
- GetLanguagesSupportingTypeSystems
- GetLanguagesSupportingTypeSystemsForExpressions
- GetLanguagesSupportingREPLs
- GetTypeScavenger
- GetLanguageSpecificTypeLookupHelp
- Find
- Find_Impl
- GetFormatterPrefixSuffix
- DemangledNameContainsPath
- GetDeclPrintingHelper
- IsLogicalTrue
- IsNilReference
- IsUninitializedReference
- GetFunctionDisplayName
- GetExceptionResolverDescription
- GetDefaultExceptionResolverDescription
- GetBooleanFromString
- Language
- ~Language
- SourceLanguage
- AsLanguageType
- GetDescription
- IsC
- IsObjC
Improve your Profiling and Debugging skills
Find out more