xref: /src/contrib/llvm-project/lldb/source/Target/Language.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1cfca06d7SDimitry Andric //===-- Language.cpp ------------------------------------------------------===//
2e81d9d49SDimitry Andric //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e81d9d49SDimitry Andric //
7e81d9d49SDimitry Andric //===----------------------------------------------------------------------===//
8e81d9d49SDimitry Andric 
9e81d9d49SDimitry Andric #include <functional>
10e81d9d49SDimitry Andric #include <map>
11e81d9d49SDimitry Andric #include <mutex>
12e81d9d49SDimitry Andric 
13e81d9d49SDimitry Andric #include "lldb/Target/Language.h"
14e81d9d49SDimitry Andric 
15e81d9d49SDimitry Andric #include "lldb/Core/PluginManager.h"
16ac9a064cSDimitry Andric #include "lldb/Interpreter/OptionValueProperties.h"
1714f1b3e8SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
1814f1b3e8SDimitry Andric #include "lldb/Symbol/TypeList.h"
1914f1b3e8SDimitry Andric #include "lldb/Target/Target.h"
2074a628f7SDimitry Andric #include "lldb/Utility/Stream.h"
2174a628f7SDimitry Andric 
22ac9a064cSDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
2374a628f7SDimitry Andric #include "llvm/Support/Threading.h"
24e81d9d49SDimitry Andric 
25e81d9d49SDimitry Andric using namespace lldb;
26e81d9d49SDimitry Andric using namespace lldb_private;
27e81d9d49SDimitry Andric using namespace lldb_private::formatters;
28e81d9d49SDimitry Andric 
29e81d9d49SDimitry Andric typedef std::unique_ptr<Language> LanguageUP;
30e81d9d49SDimitry Andric typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;
31e81d9d49SDimitry Andric 
32ac9a064cSDimitry Andric #define LLDB_PROPERTIES_language
33ac9a064cSDimitry Andric #include "TargetProperties.inc"
34ac9a064cSDimitry Andric 
35ac9a064cSDimitry Andric enum {
36ac9a064cSDimitry Andric #define LLDB_PROPERTIES_language
37ac9a064cSDimitry Andric #include "TargetPropertiesEnum.inc"
38ac9a064cSDimitry Andric };
39ac9a064cSDimitry Andric 
GetGlobalLanguageProperties()40ac9a064cSDimitry Andric LanguageProperties &Language::GetGlobalLanguageProperties() {
41ac9a064cSDimitry Andric   static LanguageProperties g_settings;
42ac9a064cSDimitry Andric   return g_settings;
43ac9a064cSDimitry Andric }
44ac9a064cSDimitry Andric 
GetSettingName()45ac9a064cSDimitry Andric llvm::StringRef LanguageProperties::GetSettingName() {
46ac9a064cSDimitry Andric   static constexpr llvm::StringLiteral g_setting_name("language");
47ac9a064cSDimitry Andric   return g_setting_name;
48ac9a064cSDimitry Andric }
49ac9a064cSDimitry Andric 
LanguageProperties()50ac9a064cSDimitry Andric LanguageProperties::LanguageProperties() {
51ac9a064cSDimitry Andric   m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
52ac9a064cSDimitry Andric   m_collection_sp->Initialize(g_language_properties);
53ac9a064cSDimitry Andric }
54ac9a064cSDimitry Andric 
GetEnableFilterForLineBreakpoints() const55ac9a064cSDimitry Andric bool LanguageProperties::GetEnableFilterForLineBreakpoints() const {
56ac9a064cSDimitry Andric   const uint32_t idx = ePropertyEnableFilterForLineBreakpoints;
57ac9a064cSDimitry Andric   return GetPropertyAtIndexAs<bool>(
58ac9a064cSDimitry Andric       idx, g_language_properties[idx].default_uint_value != 0);
59ac9a064cSDimitry Andric }
60ac9a064cSDimitry Andric 
GetLanguagesMap()6114f1b3e8SDimitry Andric static LanguagesMap &GetLanguagesMap() {
62e81d9d49SDimitry Andric   static LanguagesMap *g_map = nullptr;
6374a628f7SDimitry Andric   static llvm::once_flag g_initialize;
64e81d9d49SDimitry Andric 
6574a628f7SDimitry Andric   llvm::call_once(g_initialize, [] {
6614f1b3e8SDimitry Andric     g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global
6714f1b3e8SDimitry Andric                                 // destructor chain
68e81d9d49SDimitry Andric   });
69e81d9d49SDimitry Andric 
70e81d9d49SDimitry Andric   return *g_map;
71e81d9d49SDimitry Andric }
GetLanguagesMutex()7214f1b3e8SDimitry Andric static std::mutex &GetLanguagesMutex() {
73f3fbd1c0SDimitry Andric   static std::mutex *g_mutex = nullptr;
7474a628f7SDimitry Andric   static llvm::once_flag g_initialize;
75e81d9d49SDimitry Andric 
7674a628f7SDimitry Andric   llvm::call_once(g_initialize, [] {
7714f1b3e8SDimitry Andric     g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global
7814f1b3e8SDimitry Andric                                 // destructor chain
79e81d9d49SDimitry Andric   });
80e81d9d49SDimitry Andric 
81e81d9d49SDimitry Andric   return *g_mutex;
82e81d9d49SDimitry Andric }
83e81d9d49SDimitry Andric 
FindPlugin(lldb::LanguageType language)8414f1b3e8SDimitry Andric Language *Language::FindPlugin(lldb::LanguageType language) {
85f3fbd1c0SDimitry Andric   std::lock_guard<std::mutex> guard(GetLanguagesMutex());
86e81d9d49SDimitry Andric   LanguagesMap &map(GetLanguagesMap());
87e81d9d49SDimitry Andric   auto iter = map.find(language), end = map.end();
88e81d9d49SDimitry Andric   if (iter != end)
89e81d9d49SDimitry Andric     return iter->second.get();
90e81d9d49SDimitry Andric 
91e81d9d49SDimitry Andric   Language *language_ptr = nullptr;
92e81d9d49SDimitry Andric   LanguageCreateInstance create_callback;
93e81d9d49SDimitry Andric 
94e81d9d49SDimitry Andric   for (uint32_t idx = 0;
9514f1b3e8SDimitry Andric        (create_callback =
9614f1b3e8SDimitry Andric             PluginManager::GetLanguageCreateCallbackAtIndex(idx)) != nullptr;
9714f1b3e8SDimitry Andric        ++idx) {
98e81d9d49SDimitry Andric     language_ptr = create_callback(language);
99e81d9d49SDimitry Andric 
10014f1b3e8SDimitry Andric     if (language_ptr) {
101e81d9d49SDimitry Andric       map[language] = std::unique_ptr<Language>(language_ptr);
102e81d9d49SDimitry Andric       return language_ptr;
103e81d9d49SDimitry Andric     }
104e81d9d49SDimitry Andric   }
105e81d9d49SDimitry Andric 
106e81d9d49SDimitry Andric   return nullptr;
107e81d9d49SDimitry Andric }
108e81d9d49SDimitry Andric 
FindPlugin(llvm::StringRef file_path)10994994d37SDimitry Andric Language *Language::FindPlugin(llvm::StringRef file_path) {
11094994d37SDimitry Andric   Language *result = nullptr;
11194994d37SDimitry Andric   ForEach([&result, file_path](Language *language) {
11294994d37SDimitry Andric     if (language->IsSourceFile(file_path)) {
11394994d37SDimitry Andric       result = language;
11494994d37SDimitry Andric       return false;
11594994d37SDimitry Andric     }
11694994d37SDimitry Andric     return true;
11794994d37SDimitry Andric   });
11894994d37SDimitry Andric   return result;
11994994d37SDimitry Andric }
12094994d37SDimitry Andric 
FindPlugin(LanguageType language,llvm::StringRef file_path)12194994d37SDimitry Andric Language *Language::FindPlugin(LanguageType language,
12294994d37SDimitry Andric                                llvm::StringRef file_path) {
12394994d37SDimitry Andric   Language *result = FindPlugin(language);
12494994d37SDimitry Andric   // Finding a language by file path is slower, we so we use this as the
12594994d37SDimitry Andric   // fallback.
12694994d37SDimitry Andric   if (!result)
12794994d37SDimitry Andric     result = FindPlugin(file_path);
12894994d37SDimitry Andric   return result;
12994994d37SDimitry Andric }
13094994d37SDimitry Andric 
ForEach(std::function<bool (Language *)> callback)13114f1b3e8SDimitry Andric void Language::ForEach(std::function<bool(Language *)> callback) {
13294994d37SDimitry Andric   // If we want to iterate over all languages, we first have to complete the
13394994d37SDimitry Andric   // LanguagesMap.
13494994d37SDimitry Andric   static llvm::once_flag g_initialize;
13594994d37SDimitry Andric   llvm::call_once(g_initialize, [] {
13694994d37SDimitry Andric     for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes;
13794994d37SDimitry Andric          ++lang) {
13894994d37SDimitry Andric       FindPlugin(static_cast<lldb::LanguageType>(lang));
13994994d37SDimitry Andric     }
14094994d37SDimitry Andric   });
14194994d37SDimitry Andric 
142c0981da4SDimitry Andric   // callback may call a method in Language that attempts to acquire the same
143c0981da4SDimitry Andric   // lock (such as Language::ForEach or Language::FindPlugin). To avoid a
144c0981da4SDimitry Andric   // deadlock, we do not use callback while holding the lock.
145c0981da4SDimitry Andric   std::vector<Language *> loaded_plugins;
146c0981da4SDimitry Andric   {
147f3fbd1c0SDimitry Andric     std::lock_guard<std::mutex> guard(GetLanguagesMutex());
148e81d9d49SDimitry Andric     LanguagesMap &map(GetLanguagesMap());
14914f1b3e8SDimitry Andric     for (const auto &entry : map) {
150c0981da4SDimitry Andric       if (entry.second)
151c0981da4SDimitry Andric         loaded_plugins.push_back(entry.second.get());
152c0981da4SDimitry Andric     }
153c0981da4SDimitry Andric   }
154c0981da4SDimitry Andric 
155c0981da4SDimitry Andric   for (auto *lang : loaded_plugins) {
156c0981da4SDimitry Andric     if (!callback(lang))
157e81d9d49SDimitry Andric       break;
158e81d9d49SDimitry Andric   }
159e81d9d49SDimitry Andric }
160e81d9d49SDimitry Andric 
IsTopLevelFunction(Function & function)16114f1b3e8SDimitry Andric bool Language::IsTopLevelFunction(Function &function) { return false; }
162e81d9d49SDimitry Andric 
GetFormatters()16314f1b3e8SDimitry Andric lldb::TypeCategoryImplSP Language::GetFormatters() { return nullptr; }
164e81d9d49SDimitry Andric 
GetHardcodedFormats()16514f1b3e8SDimitry Andric HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats() {
166e81d9d49SDimitry Andric   return {};
167e81d9d49SDimitry Andric }
168e81d9d49SDimitry Andric 
GetHardcodedSummaries()16914f1b3e8SDimitry Andric HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries() {
170e81d9d49SDimitry Andric   return {};
171e81d9d49SDimitry Andric }
172e81d9d49SDimitry Andric 
173e81d9d49SDimitry Andric HardcodedFormatters::HardcodedSyntheticFinder
GetHardcodedSynthetics()17414f1b3e8SDimitry Andric Language::GetHardcodedSynthetics() {
175e81d9d49SDimitry Andric   return {};
176e81d9d49SDimitry Andric }
177e81d9d49SDimitry Andric 
178e3b55780SDimitry Andric std::vector<FormattersMatchCandidate>
GetPossibleFormattersMatches(ValueObject & valobj,lldb::DynamicValueType use_dynamic)17914f1b3e8SDimitry Andric Language::GetPossibleFormattersMatches(ValueObject &valobj,
18014f1b3e8SDimitry Andric                                        lldb::DynamicValueType use_dynamic) {
181e81d9d49SDimitry Andric   return {};
182e81d9d49SDimitry Andric }
183e81d9d49SDimitry Andric 
184e81d9d49SDimitry Andric struct language_name_pair {
185e81d9d49SDimitry Andric   const char *name;
186e81d9d49SDimitry Andric   LanguageType type;
187e81d9d49SDimitry Andric };
188e81d9d49SDimitry Andric 
18914f1b3e8SDimitry Andric struct language_name_pair language_names[] = {
190e81d9d49SDimitry Andric     // To allow GetNameForLanguageType to be a simple array lookup, the first
191e81d9d49SDimitry Andric     // part of this array must follow enum LanguageType exactly.
192e81d9d49SDimitry Andric     {"unknown", eLanguageTypeUnknown},
193e81d9d49SDimitry Andric     {"c89", eLanguageTypeC89},
194e81d9d49SDimitry Andric     {"c", eLanguageTypeC},
195e81d9d49SDimitry Andric     {"ada83", eLanguageTypeAda83},
196e81d9d49SDimitry Andric     {"c++", eLanguageTypeC_plus_plus},
197e81d9d49SDimitry Andric     {"cobol74", eLanguageTypeCobol74},
198e81d9d49SDimitry Andric     {"cobol85", eLanguageTypeCobol85},
199e81d9d49SDimitry Andric     {"fortran77", eLanguageTypeFortran77},
200e81d9d49SDimitry Andric     {"fortran90", eLanguageTypeFortran90},
201e81d9d49SDimitry Andric     {"pascal83", eLanguageTypePascal83},
202e81d9d49SDimitry Andric     {"modula2", eLanguageTypeModula2},
203e81d9d49SDimitry Andric     {"java", eLanguageTypeJava},
204e81d9d49SDimitry Andric     {"c99", eLanguageTypeC99},
205e81d9d49SDimitry Andric     {"ada95", eLanguageTypeAda95},
206e81d9d49SDimitry Andric     {"fortran95", eLanguageTypeFortran95},
207e81d9d49SDimitry Andric     {"pli", eLanguageTypePLI},
208e81d9d49SDimitry Andric     {"objective-c", eLanguageTypeObjC},
209e81d9d49SDimitry Andric     {"objective-c++", eLanguageTypeObjC_plus_plus},
210e81d9d49SDimitry Andric     {"upc", eLanguageTypeUPC},
211e81d9d49SDimitry Andric     {"d", eLanguageTypeD},
212e81d9d49SDimitry Andric     {"python", eLanguageTypePython},
213e81d9d49SDimitry Andric     {"opencl", eLanguageTypeOpenCL},
214e81d9d49SDimitry Andric     {"go", eLanguageTypeGo},
215e81d9d49SDimitry Andric     {"modula3", eLanguageTypeModula3},
216e81d9d49SDimitry Andric     {"haskell", eLanguageTypeHaskell},
217e81d9d49SDimitry Andric     {"c++03", eLanguageTypeC_plus_plus_03},
218e81d9d49SDimitry Andric     {"c++11", eLanguageTypeC_plus_plus_11},
219e81d9d49SDimitry Andric     {"ocaml", eLanguageTypeOCaml},
220e81d9d49SDimitry Andric     {"rust", eLanguageTypeRust},
221e81d9d49SDimitry Andric     {"c11", eLanguageTypeC11},
222e81d9d49SDimitry Andric     {"swift", eLanguageTypeSwift},
223e81d9d49SDimitry Andric     {"julia", eLanguageTypeJulia},
224e81d9d49SDimitry Andric     {"dylan", eLanguageTypeDylan},
225e81d9d49SDimitry Andric     {"c++14", eLanguageTypeC_plus_plus_14},
226e81d9d49SDimitry Andric     {"fortran03", eLanguageTypeFortran03},
227e81d9d49SDimitry Andric     {"fortran08", eLanguageTypeFortran08},
2287fa27ce4SDimitry Andric     {"renderscript", eLanguageTypeRenderScript},
2297fa27ce4SDimitry Andric     {"bliss", eLanguageTypeBLISS},
2307fa27ce4SDimitry Andric     {"kotlin", eLanguageTypeKotlin},
2317fa27ce4SDimitry Andric     {"zig", eLanguageTypeZig},
2327fa27ce4SDimitry Andric     {"crystal", eLanguageTypeCrystal},
2337fa27ce4SDimitry Andric     {"<invalid language>",
2347fa27ce4SDimitry Andric      static_cast<LanguageType>(
2357fa27ce4SDimitry Andric          0x0029)}, // Not yet taken by any language in the DWARF spec
2367fa27ce4SDimitry Andric                    // and thus has no entry in LanguageType
2377fa27ce4SDimitry Andric     {"c++17", eLanguageTypeC_plus_plus_17},
2387fa27ce4SDimitry Andric     {"c++20", eLanguageTypeC_plus_plus_20},
2397fa27ce4SDimitry Andric     {"c17", eLanguageTypeC17},
2407fa27ce4SDimitry Andric     {"fortran18", eLanguageTypeFortran18},
2417fa27ce4SDimitry Andric     {"ada2005", eLanguageTypeAda2005},
2427fa27ce4SDimitry Andric     {"ada2012", eLanguageTypeAda2012},
2437fa27ce4SDimitry Andric     {"HIP", eLanguageTypeHIP},
2447fa27ce4SDimitry Andric     {"assembly", eLanguageTypeAssembly},
2457fa27ce4SDimitry Andric     {"c-sharp", eLanguageTypeC_sharp},
2467fa27ce4SDimitry Andric     {"mojo", eLanguageTypeMojo},
247e81d9d49SDimitry Andric     // Vendor Extensions
248344a3780SDimitry Andric     {"assembler", eLanguageTypeMipsAssembler},
249e81d9d49SDimitry Andric     // Now synonyms, in arbitrary order
250e81d9d49SDimitry Andric     {"objc", eLanguageTypeObjC},
251e81d9d49SDimitry Andric     {"objc++", eLanguageTypeObjC_plus_plus},
25214f1b3e8SDimitry Andric     {"pascal", eLanguageTypePascal83}};
253e81d9d49SDimitry Andric 
25414f1b3e8SDimitry Andric static uint32_t num_languages =
25514f1b3e8SDimitry Andric     sizeof(language_names) / sizeof(struct language_name_pair);
256e81d9d49SDimitry Andric 
GetLanguageTypeFromString(llvm::StringRef string)25714f1b3e8SDimitry Andric LanguageType Language::GetLanguageTypeFromString(llvm::StringRef string) {
25814f1b3e8SDimitry Andric   for (const auto &L : language_names) {
259344a3780SDimitry Andric     if (string.equals_insensitive(L.name))
26014f1b3e8SDimitry Andric       return static_cast<LanguageType>(L.type);
261e81d9d49SDimitry Andric   }
26214f1b3e8SDimitry Andric 
263e81d9d49SDimitry Andric   return eLanguageTypeUnknown;
264e81d9d49SDimitry Andric }
265e81d9d49SDimitry Andric 
GetNameForLanguageType(LanguageType language)26614f1b3e8SDimitry Andric const char *Language::GetNameForLanguageType(LanguageType language) {
267e81d9d49SDimitry Andric   if (language < num_languages)
268e81d9d49SDimitry Andric     return language_names[language].name;
269e81d9d49SDimitry Andric   else
270e81d9d49SDimitry Andric     return language_names[eLanguageTypeUnknown].name;
271e81d9d49SDimitry Andric }
272e81d9d49SDimitry Andric 
PrintSupportedLanguagesForExpressions(Stream & s,llvm::StringRef prefix,llvm::StringRef suffix)273e3b55780SDimitry Andric void Language::PrintSupportedLanguagesForExpressions(Stream &s,
274e3b55780SDimitry Andric                                                      llvm::StringRef prefix,
275e3b55780SDimitry Andric                                                      llvm::StringRef suffix) {
276e3b55780SDimitry Andric   auto supported = Language::GetLanguagesSupportingTypeSystemsForExpressions();
277e3b55780SDimitry Andric   for (size_t idx = 0; idx < num_languages; ++idx) {
278e3b55780SDimitry Andric     auto const &lang = language_names[idx];
279e3b55780SDimitry Andric     if (supported[lang.type])
280e3b55780SDimitry Andric       s << prefix << lang.name << suffix;
281e3b55780SDimitry Andric   }
282e3b55780SDimitry Andric }
283e3b55780SDimitry Andric 
PrintAllLanguages(Stream & s,const char * prefix,const char * suffix)28414f1b3e8SDimitry Andric void Language::PrintAllLanguages(Stream &s, const char *prefix,
28514f1b3e8SDimitry Andric                                  const char *suffix) {
28614f1b3e8SDimitry Andric   for (uint32_t i = 1; i < num_languages; i++) {
287e81d9d49SDimitry Andric     s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
288e81d9d49SDimitry Andric   }
289e81d9d49SDimitry Andric }
290e81d9d49SDimitry Andric 
ForAllLanguages(std::function<bool (lldb::LanguageType)> callback)29114f1b3e8SDimitry Andric void Language::ForAllLanguages(
29214f1b3e8SDimitry Andric     std::function<bool(lldb::LanguageType)> callback) {
29314f1b3e8SDimitry Andric   for (uint32_t i = 1; i < num_languages; i++) {
294e81d9d49SDimitry Andric     if (!callback(language_names[i].type))
295e81d9d49SDimitry Andric       break;
296e81d9d49SDimitry Andric   }
297e81d9d49SDimitry Andric }
298e81d9d49SDimitry Andric 
LanguageIsCPlusPlus(LanguageType language)29914f1b3e8SDimitry Andric bool Language::LanguageIsCPlusPlus(LanguageType language) {
30014f1b3e8SDimitry Andric   switch (language) {
301e81d9d49SDimitry Andric   case eLanguageTypeC_plus_plus:
302e81d9d49SDimitry Andric   case eLanguageTypeC_plus_plus_03:
303e81d9d49SDimitry Andric   case eLanguageTypeC_plus_plus_11:
304e81d9d49SDimitry Andric   case eLanguageTypeC_plus_plus_14:
3057fa27ce4SDimitry Andric   case eLanguageTypeC_plus_plus_17:
3067fa27ce4SDimitry Andric   case eLanguageTypeC_plus_plus_20:
307f3fbd1c0SDimitry Andric   case eLanguageTypeObjC_plus_plus:
308e81d9d49SDimitry Andric     return true;
309e81d9d49SDimitry Andric   default:
310e81d9d49SDimitry Andric     return false;
311e81d9d49SDimitry Andric   }
312e81d9d49SDimitry Andric }
313e81d9d49SDimitry Andric 
LanguageIsObjC(LanguageType language)31414f1b3e8SDimitry Andric bool Language::LanguageIsObjC(LanguageType language) {
31514f1b3e8SDimitry Andric   switch (language) {
316e81d9d49SDimitry Andric   case eLanguageTypeObjC:
317e81d9d49SDimitry Andric   case eLanguageTypeObjC_plus_plus:
318e81d9d49SDimitry Andric     return true;
319e81d9d49SDimitry Andric   default:
320e81d9d49SDimitry Andric     return false;
321e81d9d49SDimitry Andric   }
322e81d9d49SDimitry Andric }
323e81d9d49SDimitry Andric 
LanguageIsC(LanguageType language)32414f1b3e8SDimitry Andric bool Language::LanguageIsC(LanguageType language) {
32514f1b3e8SDimitry Andric   switch (language) {
326e81d9d49SDimitry Andric   case eLanguageTypeC:
327e81d9d49SDimitry Andric   case eLanguageTypeC89:
328e81d9d49SDimitry Andric   case eLanguageTypeC99:
329e81d9d49SDimitry Andric   case eLanguageTypeC11:
330e81d9d49SDimitry Andric     return true;
331e81d9d49SDimitry Andric   default:
332e81d9d49SDimitry Andric     return false;
333e81d9d49SDimitry Andric   }
334e81d9d49SDimitry Andric }
335e81d9d49SDimitry Andric 
LanguageIsCFamily(LanguageType language)3365f29bb8aSDimitry Andric bool Language::LanguageIsCFamily(LanguageType language) {
3375f29bb8aSDimitry Andric   switch (language) {
3385f29bb8aSDimitry Andric   case eLanguageTypeC:
3395f29bb8aSDimitry Andric   case eLanguageTypeC89:
3405f29bb8aSDimitry Andric   case eLanguageTypeC99:
3415f29bb8aSDimitry Andric   case eLanguageTypeC11:
3425f29bb8aSDimitry Andric   case eLanguageTypeC_plus_plus:
3435f29bb8aSDimitry Andric   case eLanguageTypeC_plus_plus_03:
3445f29bb8aSDimitry Andric   case eLanguageTypeC_plus_plus_11:
3455f29bb8aSDimitry Andric   case eLanguageTypeC_plus_plus_14:
3467fa27ce4SDimitry Andric   case eLanguageTypeC_plus_plus_17:
3477fa27ce4SDimitry Andric   case eLanguageTypeC_plus_plus_20:
3485f29bb8aSDimitry Andric   case eLanguageTypeObjC_plus_plus:
3495f29bb8aSDimitry Andric   case eLanguageTypeObjC:
3505f29bb8aSDimitry Andric     return true;
3515f29bb8aSDimitry Andric   default:
3525f29bb8aSDimitry Andric     return false;
3535f29bb8aSDimitry Andric   }
3545f29bb8aSDimitry Andric }
3555f29bb8aSDimitry Andric 
LanguageIsPascal(LanguageType language)35614f1b3e8SDimitry Andric bool Language::LanguageIsPascal(LanguageType language) {
35714f1b3e8SDimitry Andric   switch (language) {
358e81d9d49SDimitry Andric   case eLanguageTypePascal83:
359e81d9d49SDimitry Andric     return true;
360e81d9d49SDimitry Andric   default:
361e81d9d49SDimitry Andric     return false;
362e81d9d49SDimitry Andric   }
363e81d9d49SDimitry Andric }
364e81d9d49SDimitry Andric 
GetPrimaryLanguage(LanguageType language)36514f1b3e8SDimitry Andric LanguageType Language::GetPrimaryLanguage(LanguageType language) {
36614f1b3e8SDimitry Andric   switch (language) {
367e81d9d49SDimitry Andric   case eLanguageTypeC_plus_plus:
368e81d9d49SDimitry Andric   case eLanguageTypeC_plus_plus_03:
369e81d9d49SDimitry Andric   case eLanguageTypeC_plus_plus_11:
370e81d9d49SDimitry Andric   case eLanguageTypeC_plus_plus_14:
3717fa27ce4SDimitry Andric   case eLanguageTypeC_plus_plus_17:
3727fa27ce4SDimitry Andric   case eLanguageTypeC_plus_plus_20:
373e81d9d49SDimitry Andric     return eLanguageTypeC_plus_plus;
374e81d9d49SDimitry Andric   case eLanguageTypeC:
375e81d9d49SDimitry Andric   case eLanguageTypeC89:
376e81d9d49SDimitry Andric   case eLanguageTypeC99:
377e81d9d49SDimitry Andric   case eLanguageTypeC11:
378e81d9d49SDimitry Andric     return eLanguageTypeC;
379e81d9d49SDimitry Andric   case eLanguageTypeObjC:
380e81d9d49SDimitry Andric   case eLanguageTypeObjC_plus_plus:
381e81d9d49SDimitry Andric     return eLanguageTypeObjC;
382e81d9d49SDimitry Andric   case eLanguageTypePascal83:
383e81d9d49SDimitry Andric   case eLanguageTypeCobol74:
384e81d9d49SDimitry Andric   case eLanguageTypeCobol85:
385e81d9d49SDimitry Andric   case eLanguageTypeFortran77:
386e81d9d49SDimitry Andric   case eLanguageTypeFortran90:
387e81d9d49SDimitry Andric   case eLanguageTypeFortran95:
388e81d9d49SDimitry Andric   case eLanguageTypeFortran03:
389e81d9d49SDimitry Andric   case eLanguageTypeFortran08:
390e81d9d49SDimitry Andric   case eLanguageTypeAda83:
391e81d9d49SDimitry Andric   case eLanguageTypeAda95:
392e81d9d49SDimitry Andric   case eLanguageTypeModula2:
393e81d9d49SDimitry Andric   case eLanguageTypeJava:
394e81d9d49SDimitry Andric   case eLanguageTypePLI:
395e81d9d49SDimitry Andric   case eLanguageTypeUPC:
396e81d9d49SDimitry Andric   case eLanguageTypeD:
397e81d9d49SDimitry Andric   case eLanguageTypePython:
398e81d9d49SDimitry Andric   case eLanguageTypeOpenCL:
399e81d9d49SDimitry Andric   case eLanguageTypeGo:
400e81d9d49SDimitry Andric   case eLanguageTypeModula3:
401e81d9d49SDimitry Andric   case eLanguageTypeHaskell:
402e81d9d49SDimitry Andric   case eLanguageTypeOCaml:
403e81d9d49SDimitry Andric   case eLanguageTypeRust:
404e81d9d49SDimitry Andric   case eLanguageTypeSwift:
405e81d9d49SDimitry Andric   case eLanguageTypeJulia:
406e81d9d49SDimitry Andric   case eLanguageTypeDylan:
407e81d9d49SDimitry Andric   case eLanguageTypeMipsAssembler:
408b1c73532SDimitry Andric   case eLanguageTypeMojo:
409e81d9d49SDimitry Andric   case eLanguageTypeUnknown:
410e81d9d49SDimitry Andric   default:
411e81d9d49SDimitry Andric     return language;
412e81d9d49SDimitry Andric   }
413e81d9d49SDimitry Andric }
414e81d9d49SDimitry Andric 
GetSupportedLanguages()4155f29bb8aSDimitry Andric std::set<lldb::LanguageType> Language::GetSupportedLanguages() {
4165f29bb8aSDimitry Andric   std::set<lldb::LanguageType> supported_languages;
4175f29bb8aSDimitry Andric   ForEach([&](Language *lang) {
4185f29bb8aSDimitry Andric     supported_languages.emplace(lang->GetLanguageType());
4195f29bb8aSDimitry Andric     return true;
4205f29bb8aSDimitry Andric   });
4215f29bb8aSDimitry Andric   return supported_languages;
4225f29bb8aSDimitry Andric }
4235f29bb8aSDimitry Andric 
GetLanguagesSupportingTypeSystems()424ead24645SDimitry Andric LanguageSet Language::GetLanguagesSupportingTypeSystems() {
425ead24645SDimitry Andric   return PluginManager::GetAllTypeSystemSupportedLanguagesForTypes();
426e81d9d49SDimitry Andric }
427e81d9d49SDimitry Andric 
GetLanguagesSupportingTypeSystemsForExpressions()428ead24645SDimitry Andric LanguageSet Language::GetLanguagesSupportingTypeSystemsForExpressions() {
429ead24645SDimitry Andric   return PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions();
430e81d9d49SDimitry Andric }
431ead24645SDimitry Andric 
GetLanguagesSupportingREPLs()432ead24645SDimitry Andric LanguageSet Language::GetLanguagesSupportingREPLs() {
433ead24645SDimitry Andric   return PluginManager::GetREPLAllTypeSystemSupportedLanguages();
434e81d9d49SDimitry Andric }
435e81d9d49SDimitry Andric 
GetTypeScavenger()43614f1b3e8SDimitry Andric std::unique_ptr<Language::TypeScavenger> Language::GetTypeScavenger() {
437e81d9d49SDimitry Andric   return nullptr;
438e81d9d49SDimitry Andric }
439e81d9d49SDimitry Andric 
GetLanguageSpecificTypeLookupHelp()44014f1b3e8SDimitry Andric const char *Language::GetLanguageSpecificTypeLookupHelp() { return nullptr; }
441f3fbd1c0SDimitry Andric 
Find(ExecutionContextScope * exe_scope,const char * key,ResultSet & results,bool append)44214f1b3e8SDimitry Andric size_t Language::TypeScavenger::Find(ExecutionContextScope *exe_scope,
44314f1b3e8SDimitry Andric                                      const char *key, ResultSet &results,
44414f1b3e8SDimitry Andric                                      bool append) {
445e81d9d49SDimitry Andric   if (!exe_scope || !exe_scope->CalculateTarget().get())
446e81d9d49SDimitry Andric     return false;
447e81d9d49SDimitry Andric 
448e81d9d49SDimitry Andric   if (!key || !key[0])
449e81d9d49SDimitry Andric     return false;
450e81d9d49SDimitry Andric 
451e81d9d49SDimitry Andric   if (!append)
452e81d9d49SDimitry Andric     results.clear();
453e81d9d49SDimitry Andric 
454e81d9d49SDimitry Andric   size_t old_size = results.size();
455e81d9d49SDimitry Andric 
456e81d9d49SDimitry Andric   if (this->Find_Impl(exe_scope, key, results))
457e81d9d49SDimitry Andric     return results.size() - old_size;
458e81d9d49SDimitry Andric   return 0;
459e81d9d49SDimitry Andric }
460e81d9d49SDimitry Andric 
Find_Impl(ExecutionContextScope * exe_scope,const char * key,ResultSet & results)46114f1b3e8SDimitry Andric bool Language::ImageListTypeScavenger::Find_Impl(
46214f1b3e8SDimitry Andric     ExecutionContextScope *exe_scope, const char *key, ResultSet &results) {
46314f1b3e8SDimitry Andric   bool result = false;
46414f1b3e8SDimitry Andric 
46514f1b3e8SDimitry Andric   Target *target = exe_scope->CalculateTarget().get();
46614f1b3e8SDimitry Andric   if (target) {
46714f1b3e8SDimitry Andric     const auto &images(target->GetImages());
468312c0ed1SDimitry Andric     TypeQuery query(key);
469312c0ed1SDimitry Andric     TypeResults type_results;
470312c0ed1SDimitry Andric     images.FindTypes(nullptr, query, type_results);
471312c0ed1SDimitry Andric     for (const auto &match : type_results.GetTypeMap().Types()) {
4725f29bb8aSDimitry Andric       if (match) {
47314f1b3e8SDimitry Andric         CompilerType compiler_type(match->GetFullCompilerType());
47414f1b3e8SDimitry Andric         compiler_type = AdjustForInclusion(compiler_type);
47514f1b3e8SDimitry Andric         if (!compiler_type)
47614f1b3e8SDimitry Andric           continue;
47714f1b3e8SDimitry Andric         std::unique_ptr<Language::TypeScavenger::Result> scavengeresult(
47814f1b3e8SDimitry Andric             new Result(compiler_type));
47914f1b3e8SDimitry Andric         results.insert(std::move(scavengeresult));
48014f1b3e8SDimitry Andric         result = true;
48114f1b3e8SDimitry Andric       }
48214f1b3e8SDimitry Andric     }
48314f1b3e8SDimitry Andric   }
48414f1b3e8SDimitry Andric 
48514f1b3e8SDimitry Andric   return result;
48614f1b3e8SDimitry Andric }
48714f1b3e8SDimitry Andric 
4887fa27ce4SDimitry Andric std::pair<llvm::StringRef, llvm::StringRef>
GetFormatterPrefixSuffix(llvm::StringRef type_hint)4897fa27ce4SDimitry Andric Language::GetFormatterPrefixSuffix(llvm::StringRef type_hint) {
4907fa27ce4SDimitry Andric   return std::pair<llvm::StringRef, llvm::StringRef>();
491e81d9d49SDimitry Andric }
492e81d9d49SDimitry Andric 
DemangledNameContainsPath(llvm::StringRef path,ConstString demangled) const493145449b1SDimitry Andric bool Language::DemangledNameContainsPath(llvm::StringRef path,
494145449b1SDimitry Andric                                          ConstString demangled) const {
495145449b1SDimitry Andric   // The base implementation does a simple contains comparision:
496145449b1SDimitry Andric   if (path.empty())
497145449b1SDimitry Andric     return false;
498145449b1SDimitry Andric   return demangled.GetStringRef().contains(path);
499145449b1SDimitry Andric }
500145449b1SDimitry Andric 
GetDeclPrintingHelper()50114f1b3e8SDimitry Andric DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() {
502e81d9d49SDimitry Andric   return nullptr;
503e81d9d49SDimitry Andric }
504e81d9d49SDimitry Andric 
IsLogicalTrue(ValueObject & valobj,Status & error)505b76161e4SDimitry Andric LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) {
506e81d9d49SDimitry Andric   return eLazyBoolCalculate;
507e81d9d49SDimitry Andric }
508e81d9d49SDimitry Andric 
IsNilReference(ValueObject & valobj)50914f1b3e8SDimitry Andric bool Language::IsNilReference(ValueObject &valobj) { return false; }
510e81d9d49SDimitry Andric 
IsUninitializedReference(ValueObject & valobj)51114f1b3e8SDimitry Andric bool Language::IsUninitializedReference(ValueObject &valobj) { return false; }
512e81d9d49SDimitry Andric 
GetFunctionDisplayName(const SymbolContext * sc,const ExecutionContext * exe_ctx,FunctionNameRepresentation representation,Stream & s)51314f1b3e8SDimitry Andric bool Language::GetFunctionDisplayName(const SymbolContext *sc,
514e81d9d49SDimitry Andric                                       const ExecutionContext *exe_ctx,
515e81d9d49SDimitry Andric                                       FunctionNameRepresentation representation,
51614f1b3e8SDimitry Andric                                       Stream &s) {
517e81d9d49SDimitry Andric   return false;
518e81d9d49SDimitry Andric }
519e81d9d49SDimitry Andric 
GetExceptionResolverDescription(bool catch_on,bool throw_on,Stream & s)52014f1b3e8SDimitry Andric void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on,
52114f1b3e8SDimitry Andric                                                Stream &s) {
522e81d9d49SDimitry Andric   GetDefaultExceptionResolverDescription(catch_on, throw_on, s);
523e81d9d49SDimitry Andric }
524e81d9d49SDimitry Andric 
GetDefaultExceptionResolverDescription(bool catch_on,bool throw_on,Stream & s)52514f1b3e8SDimitry Andric void Language::GetDefaultExceptionResolverDescription(bool catch_on,
52614f1b3e8SDimitry Andric                                                       bool throw_on,
52714f1b3e8SDimitry Andric                                                       Stream &s) {
528e81d9d49SDimitry Andric   s.Printf("Exception breakpoint (catch: %s throw: %s)",
52914f1b3e8SDimitry Andric            catch_on ? "on" : "off", throw_on ? "on" : "off");
530e81d9d49SDimitry Andric }
531e81d9d49SDimitry Andric // Constructor
532344a3780SDimitry Andric Language::Language() = default;
533e81d9d49SDimitry Andric 
534e81d9d49SDimitry Andric // Destructor
535344a3780SDimitry Andric Language::~Language() = default;
536ac9a064cSDimitry Andric 
SourceLanguage(lldb::LanguageType language_type)537ac9a064cSDimitry Andric SourceLanguage::SourceLanguage(lldb::LanguageType language_type) {
538ac9a064cSDimitry Andric   auto lname =
539ac9a064cSDimitry Andric       llvm::dwarf::toDW_LNAME((llvm::dwarf::SourceLanguage)language_type);
540ac9a064cSDimitry Andric   if (!lname)
541ac9a064cSDimitry Andric     return;
542ac9a064cSDimitry Andric   name = lname->first;
543ac9a064cSDimitry Andric   version = lname->second;
544ac9a064cSDimitry Andric }
545ac9a064cSDimitry Andric 
AsLanguageType() const546ac9a064cSDimitry Andric lldb::LanguageType SourceLanguage::AsLanguageType() const {
547ac9a064cSDimitry Andric   if (auto lang = llvm::dwarf::toDW_LANG((llvm::dwarf::SourceLanguageName)name,
548ac9a064cSDimitry Andric                                          version))
549ac9a064cSDimitry Andric     return (lldb::LanguageType)*lang;
550ac9a064cSDimitry Andric   return lldb::eLanguageTypeUnknown;
551ac9a064cSDimitry Andric }
552ac9a064cSDimitry Andric 
GetDescription() const553ac9a064cSDimitry Andric llvm::StringRef SourceLanguage::GetDescription() const {
554ac9a064cSDimitry Andric   LanguageType type = AsLanguageType();
555ac9a064cSDimitry Andric   if (type)
556ac9a064cSDimitry Andric     return Language::GetNameForLanguageType(type);
557ac9a064cSDimitry Andric   return llvm::dwarf::LanguageDescription(
558ac9a064cSDimitry Andric       (llvm::dwarf::SourceLanguageName)name);
559ac9a064cSDimitry Andric }
IsC() const560ac9a064cSDimitry Andric bool SourceLanguage::IsC() const { return name == llvm::dwarf::DW_LNAME_C; }
561ac9a064cSDimitry Andric 
IsObjC() const562ac9a064cSDimitry Andric bool SourceLanguage::IsObjC() const {
563ac9a064cSDimitry Andric   return name == llvm::dwarf::DW_LNAME_ObjC;
564ac9a064cSDimitry Andric }
565ac9a064cSDimitry Andric 
IsCPlusPlus() const566ac9a064cSDimitry Andric bool SourceLanguage::IsCPlusPlus() const {
567ac9a064cSDimitry Andric   return name == llvm::dwarf::DW_LNAME_C_plus_plus;
568ac9a064cSDimitry Andric }
569