forked from OSchip/llvm-project
466 lines
12 KiB
C++
466 lines
12 KiB
C++
//===-- 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 <functional>
|
|
#include <map>
|
|
#include <mutex>
|
|
|
|
#include "lldb/Target/Language.h"
|
|
|
|
#include "lldb/Host/Mutex.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<Language> LanguageUP;
|
|
typedef std::map<lldb::LanguageType, LanguageUP> 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 Mutex&
|
|
GetLanguagesMutex ()
|
|
{
|
|
static Mutex *g_mutex = nullptr;
|
|
static std::once_flag g_initialize;
|
|
|
|
std::call_once(g_initialize, [] {
|
|
g_mutex = new Mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain
|
|
});
|
|
|
|
return *g_mutex;
|
|
}
|
|
|
|
Language*
|
|
Language::FindPlugin (lldb::LanguageType language)
|
|
{
|
|
Mutex::Locker locker(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>(language_ptr);
|
|
return language_ptr;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void
|
|
Language::ForEach (std::function<bool(Language*)> callback)
|
|
{
|
|
Mutex::Locker locker(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<ConstString>
|
|
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<bool(lldb::LanguageType)> 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<lldb::LanguageType> &languages,
|
|
std::set<lldb::LanguageType> &languages_for_expressions)
|
|
{
|
|
uint32_t idx = 0;
|
|
|
|
while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++))
|
|
{
|
|
(*enumerate)(languages, languages_for_expressions);
|
|
}
|
|
}
|
|
|
|
void
|
|
Language::GetLanguagesSupportingREPLs (std::set<lldb::LanguageType> &languages)
|
|
{
|
|
uint32_t idx = 0;
|
|
|
|
while (REPLEnumerateSupportedLanguages enumerate = PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(idx++))
|
|
{
|
|
(*enumerate)(languages);
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<Language::TypeScavenger>
|
|
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()
|
|
{
|
|
}
|