//===-- Language.cpp -------------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include #include #include #include "lldb/Target/Language.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Stream.h" using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; typedef std::unique_ptr LanguageUP; typedef std::map LanguagesMap; static LanguagesMap& GetLanguagesMap () { static LanguagesMap *g_map = nullptr; static std::once_flag g_initialize; std::call_once(g_initialize, [] { g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global destructor chain }); return *g_map; } static std::mutex & GetLanguagesMutex() { static std::mutex *g_mutex = nullptr; static std::once_flag g_initialize; std::call_once(g_initialize, [] { g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain }); return *g_mutex; } Language* Language::FindPlugin (lldb::LanguageType language) { std::lock_guard guard(GetLanguagesMutex()); LanguagesMap& map(GetLanguagesMap()); auto iter = map.find(language), end = map.end(); if (iter != end) return iter->second.get(); Language *language_ptr = nullptr; LanguageCreateInstance create_callback; for (uint32_t idx = 0; (create_callback = PluginManager::GetLanguageCreateCallbackAtIndex(idx)) != nullptr; ++idx) { language_ptr = create_callback(language); if (language_ptr) { map[language] = std::unique_ptr(language_ptr); return language_ptr; } } return nullptr; } void Language::ForEach (std::function callback) { std::lock_guard guard(GetLanguagesMutex()); LanguagesMap& map(GetLanguagesMap()); for (const auto& entry : map) { if (!callback(entry.second.get())) break; } } bool Language::IsTopLevelFunction (Function& function) { return false; } lldb::TypeCategoryImplSP Language::GetFormatters () { return nullptr; } HardcodedFormatters::HardcodedFormatFinder Language::GetHardcodedFormats () { return {}; } HardcodedFormatters::HardcodedSummaryFinder Language::GetHardcodedSummaries () { return {}; } HardcodedFormatters::HardcodedSyntheticFinder Language::GetHardcodedSynthetics () { return {}; } HardcodedFormatters::HardcodedValidatorFinder Language::GetHardcodedValidators () { return {}; } std::vector Language::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic) { return {}; } lldb_private::formatters::StringPrinter::EscapingHelper Language::GetStringPrinterEscapingHelper (lldb_private::formatters::StringPrinter::GetPrintableElementType elem_type) { return StringPrinter::GetDefaultEscapingHelper(elem_type); } struct language_name_pair { const char *name; LanguageType type; }; struct language_name_pair language_names[] = { // To allow GetNameForLanguageType to be a simple array lookup, the first // part of this array must follow enum LanguageType exactly. { "unknown", eLanguageTypeUnknown }, { "c89", eLanguageTypeC89 }, { "c", eLanguageTypeC }, { "ada83", eLanguageTypeAda83 }, { "c++", eLanguageTypeC_plus_plus }, { "cobol74", eLanguageTypeCobol74 }, { "cobol85", eLanguageTypeCobol85 }, { "fortran77", eLanguageTypeFortran77 }, { "fortran90", eLanguageTypeFortran90 }, { "pascal83", eLanguageTypePascal83 }, { "modula2", eLanguageTypeModula2 }, { "java", eLanguageTypeJava }, { "c99", eLanguageTypeC99 }, { "ada95", eLanguageTypeAda95 }, { "fortran95", eLanguageTypeFortran95 }, { "pli", eLanguageTypePLI }, { "objective-c", eLanguageTypeObjC }, { "objective-c++", eLanguageTypeObjC_plus_plus }, { "upc", eLanguageTypeUPC }, { "d", eLanguageTypeD }, { "python", eLanguageTypePython }, { "opencl", eLanguageTypeOpenCL }, { "go", eLanguageTypeGo }, { "modula3", eLanguageTypeModula3 }, { "haskell", eLanguageTypeHaskell }, { "c++03", eLanguageTypeC_plus_plus_03 }, { "c++11", eLanguageTypeC_plus_plus_11 }, { "ocaml", eLanguageTypeOCaml }, { "rust", eLanguageTypeRust }, { "c11", eLanguageTypeC11 }, { "swift", eLanguageTypeSwift }, { "julia", eLanguageTypeJulia }, { "dylan", eLanguageTypeDylan }, { "c++14", eLanguageTypeC_plus_plus_14 }, { "fortran03", eLanguageTypeFortran03 }, { "fortran08", eLanguageTypeFortran08 }, // Vendor Extensions { "mipsassem", eLanguageTypeMipsAssembler }, { "renderscript", eLanguageTypeExtRenderScript}, // Now synonyms, in arbitrary order { "objc", eLanguageTypeObjC }, { "objc++", eLanguageTypeObjC_plus_plus }, { "pascal", eLanguageTypePascal83 } }; static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair); LanguageType Language::GetLanguageTypeFromString (const char *string) { for (uint32_t i = 0; i < num_languages; i++) { if (strcasecmp (language_names[i].name, string) == 0) return (LanguageType) language_names[i].type; } return eLanguageTypeUnknown; } const char * Language::GetNameForLanguageType (LanguageType language) { if (language < num_languages) return language_names[language].name; else return language_names[eLanguageTypeUnknown].name; } void Language::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix) { for (uint32_t i = 1; i < num_languages; i++) { s.Printf("%s%s%s", prefix, language_names[i].name, suffix); } } void Language::ForAllLanguages (std::function callback) { for (uint32_t i = 1; i < num_languages; i++) { if (!callback(language_names[i].type)) break; } } bool Language::LanguageIsCPlusPlus (LanguageType language) { switch (language) { case eLanguageTypeC_plus_plus: case eLanguageTypeC_plus_plus_03: case eLanguageTypeC_plus_plus_11: case eLanguageTypeC_plus_plus_14: case eLanguageTypeObjC_plus_plus: return true; default: return false; } } bool Language::LanguageIsObjC (LanguageType language) { switch (language) { case eLanguageTypeObjC: case eLanguageTypeObjC_plus_plus: return true; default: return false; } } bool Language::LanguageIsC (LanguageType language) { switch (language) { case eLanguageTypeC: case eLanguageTypeC89: case eLanguageTypeC99: case eLanguageTypeC11: return true; default: return false; } } bool Language::LanguageIsPascal (LanguageType language) { switch (language) { case eLanguageTypePascal83: return true; default: return false; } } LanguageType Language::GetPrimaryLanguage (LanguageType language) { switch (language) { case eLanguageTypeC_plus_plus: case eLanguageTypeC_plus_plus_03: case eLanguageTypeC_plus_plus_11: case eLanguageTypeC_plus_plus_14: return eLanguageTypeC_plus_plus; case eLanguageTypeC: case eLanguageTypeC89: case eLanguageTypeC99: case eLanguageTypeC11: return eLanguageTypeC; case eLanguageTypeObjC: case eLanguageTypeObjC_plus_plus: return eLanguageTypeObjC; case eLanguageTypePascal83: case eLanguageTypeCobol74: case eLanguageTypeCobol85: case eLanguageTypeFortran77: case eLanguageTypeFortran90: case eLanguageTypeFortran95: case eLanguageTypeFortran03: case eLanguageTypeFortran08: case eLanguageTypeAda83: case eLanguageTypeAda95: case eLanguageTypeModula2: case eLanguageTypeJava: case eLanguageTypePLI: case eLanguageTypeUPC: case eLanguageTypeD: case eLanguageTypePython: case eLanguageTypeOpenCL: case eLanguageTypeGo: case eLanguageTypeModula3: case eLanguageTypeHaskell: case eLanguageTypeOCaml: case eLanguageTypeRust: case eLanguageTypeSwift: case eLanguageTypeJulia: case eLanguageTypeDylan: case eLanguageTypeMipsAssembler: case eLanguageTypeExtRenderScript: case eLanguageTypeUnknown: default: return language; } } void Language::GetLanguagesSupportingTypeSystems (std::set &languages, std::set &languages_for_expressions) { uint32_t idx = 0; while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++)) { (*enumerate)(languages, languages_for_expressions); } } void Language::GetLanguagesSupportingREPLs (std::set &languages) { uint32_t idx = 0; while (REPLEnumerateSupportedLanguages enumerate = PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(idx++)) { (*enumerate)(languages); } } std::unique_ptr Language::GetTypeScavenger () { return nullptr; } const char* Language::GetLanguageSpecificTypeLookupHelp () { return nullptr; } size_t Language::TypeScavenger::Find (ExecutionContextScope *exe_scope, const char *key, ResultSet &results, bool append) { if (!exe_scope || !exe_scope->CalculateTarget().get()) return false; if (!key || !key[0]) return false; if (!append) results.clear(); size_t old_size = results.size(); if (this->Find_Impl(exe_scope, key, results)) return results.size() - old_size; return 0; } bool Language::GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint, std::string& prefix, std::string& suffix) { return false; } DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper () { return nullptr; } LazyBool Language::IsLogicalTrue (ValueObject& valobj, Error& error) { return eLazyBoolCalculate; } bool Language::IsNilReference (ValueObject& valobj) { return false; } bool Language::IsUninitializedReference (ValueObject& valobj) { return false; } bool Language::GetFunctionDisplayName (const SymbolContext *sc, const ExecutionContext *exe_ctx, FunctionNameRepresentation representation, Stream& s) { return false; } void Language::GetExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s) { GetDefaultExceptionResolverDescription(catch_on, throw_on, s); } void Language::GetDefaultExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s) { s.Printf ("Exception breakpoint (catch: %s throw: %s)", catch_on ? "on" : "off", throw_on ? "on" : "off"); } //---------------------------------------------------------------------- // Constructor //---------------------------------------------------------------------- Language::Language() { } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- Language::~Language() { }