blob: dea0dd83005d2fa843eef67b5dae5b13aecbcbd7 [file] [log] [blame]
Enrico Granata5f9d3102015-08-27 21:33:50 +00001//===-- Language.cpp -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <functional>
11#include <map>
Enrico Granata2996d822015-08-27 22:14:06 +000012#include <mutex>
Enrico Granata5f9d3102015-08-27 21:33:50 +000013
14#include "lldb/Target/Language.h"
15
16#include "lldb/Host/Mutex.h"
17#include "lldb/Core/PluginManager.h"
Jim Ingham0e0984e2015-09-02 01:06:46 +000018#include "lldb/Core/Stream.h"
Enrico Granata5f9d3102015-08-27 21:33:50 +000019
20using namespace lldb;
21using namespace lldb_private;
Enrico Granataac494532015-09-09 22:30:24 +000022using namespace lldb_private::formatters;
Enrico Granata5f9d3102015-08-27 21:33:50 +000023
24typedef std::unique_ptr<Language> LanguageUP;
25typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap;
26
27static LanguagesMap&
28GetLanguagesMap ()
29{
30 static LanguagesMap *g_map = nullptr;
31 static std::once_flag g_initialize;
32
33 std::call_once(g_initialize, [] {
34 g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global destructor chain
35 });
36
37 return *g_map;
38}
39static Mutex&
40GetLanguagesMutex ()
41{
42 static Mutex *g_mutex = nullptr;
43 static std::once_flag g_initialize;
44
45 std::call_once(g_initialize, [] {
46 g_mutex = new Mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain
47 });
48
49 return *g_mutex;
50}
51
52Language*
53Language::FindPlugin (lldb::LanguageType language)
54{
55 Mutex::Locker locker(GetLanguagesMutex());
56 LanguagesMap& map(GetLanguagesMap());
57 auto iter = map.find(language), end = map.end();
58 if (iter != end)
59 return iter->second.get();
60
61 Language *language_ptr = nullptr;
62 LanguageCreateInstance create_callback;
63
64 for (uint32_t idx = 0;
65 (create_callback = PluginManager::GetLanguageCreateCallbackAtIndex(idx)) != nullptr;
66 ++idx)
67 {
68 language_ptr = create_callback(language);
69
70 if (language_ptr)
71 {
72 map[language] = std::unique_ptr<Language>(language_ptr);
73 return language_ptr;
74 }
75 }
76
77 return nullptr;
78}
79
80void
81Language::ForEach (std::function<bool(Language*)> callback)
82{
83 Mutex::Locker locker(GetLanguagesMutex());
84 LanguagesMap& map(GetLanguagesMap());
85 for (const auto& entry : map)
86 {
87 if (!callback(entry.second.get()))
88 break;
89 }
90}
91
Enrico Granata980c0482015-09-01 18:22:39 +000092lldb::TypeCategoryImplSP
93Language::GetFormatters ()
94{
95 return nullptr;
96}
97
Enrico Granatad3233c12015-09-09 01:10:46 +000098std::vector<ConstString>
99Language::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
100{
101 return {};
102}
103
Enrico Granataac494532015-09-09 22:30:24 +0000104lldb_private::formatters::StringPrinter::EscapingHelper
105Language::GetStringPrinterEscapingHelper (lldb_private::formatters::StringPrinter::GetPrintableElementType elem_type)
106{
107 return StringPrinter::GetDefaultEscapingHelper(elem_type);
108}
109
Jim Ingham0e0984e2015-09-02 01:06:46 +0000110struct language_name_pair {
111 const char *name;
112 LanguageType type;
113};
114
115struct language_name_pair language_names[] =
116{
117 // To allow GetNameForLanguageType to be a simple array lookup, the first
118 // part of this array must follow enum LanguageType exactly.
119 { "unknown", eLanguageTypeUnknown },
120 { "c89", eLanguageTypeC89 },
121 { "c", eLanguageTypeC },
122 { "ada83", eLanguageTypeAda83 },
123 { "c++", eLanguageTypeC_plus_plus },
124 { "cobol74", eLanguageTypeCobol74 },
125 { "cobol85", eLanguageTypeCobol85 },
126 { "fortran77", eLanguageTypeFortran77 },
127 { "fortran90", eLanguageTypeFortran90 },
128 { "pascal83", eLanguageTypePascal83 },
129 { "modula2", eLanguageTypeModula2 },
130 { "java", eLanguageTypeJava },
131 { "c99", eLanguageTypeC99 },
132 { "ada95", eLanguageTypeAda95 },
133 { "fortran95", eLanguageTypeFortran95 },
134 { "pli", eLanguageTypePLI },
135 { "objective-c", eLanguageTypeObjC },
136 { "objective-c++", eLanguageTypeObjC_plus_plus },
137 { "upc", eLanguageTypeUPC },
138 { "d", eLanguageTypeD },
139 { "python", eLanguageTypePython },
140 { "opencl", eLanguageTypeOpenCL },
141 { "go", eLanguageTypeGo },
142 { "modula3", eLanguageTypeModula3 },
143 { "haskell", eLanguageTypeHaskell },
144 { "c++03", eLanguageTypeC_plus_plus_03 },
145 { "c++11", eLanguageTypeC_plus_plus_11 },
146 { "ocaml", eLanguageTypeOCaml },
147 { "rust", eLanguageTypeRust },
148 { "c11", eLanguageTypeC11 },
149 { "swift", eLanguageTypeSwift },
150 { "julia", eLanguageTypeJulia },
151 { "dylan", eLanguageTypeDylan },
152 { "c++14", eLanguageTypeC_plus_plus_14 },
153 { "fortran03", eLanguageTypeFortran03 },
154 { "fortran08", eLanguageTypeFortran08 },
155 // Vendor Extensions
156 { "mipsassem", eLanguageTypeMipsAssembler },
157 { "renderscript", eLanguageTypeExtRenderScript},
158 // Now synonyms, in arbitrary order
159 { "objc", eLanguageTypeObjC },
160 { "objc++", eLanguageTypeObjC_plus_plus },
161 { "pascal", eLanguageTypePascal83 }
162};
163
164static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
165
166LanguageType
167Language::GetLanguageTypeFromString (const char *string)
168{
169 for (uint32_t i = 0; i < num_languages; i++)
170 {
171 if (strcasecmp (language_names[i].name, string) == 0)
172 return (LanguageType) language_names[i].type;
173 }
174 return eLanguageTypeUnknown;
175}
176
177const char *
178Language::GetNameForLanguageType (LanguageType language)
179{
180 if (language < num_languages)
181 return language_names[language].name;
182 else
183 return language_names[eLanguageTypeUnknown].name;
184}
185
186void
187Language::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix)
188{
189 for (uint32_t i = 1; i < num_languages; i++)
190 {
191 s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
192 }
193}
194
Enrico Granata28b38312015-09-02 01:31:10 +0000195void
196Language::ForAllLanguages (std::function<bool(lldb::LanguageType)> callback)
197{
198 for (uint32_t i = 1; i < num_languages; i++)
199 {
200 if (!callback(language_names[i].type))
201 break;
202 }
203}
204
Jim Ingham0e0984e2015-09-02 01:06:46 +0000205bool
206Language::LanguageIsCPlusPlus (LanguageType language)
207{
208 switch (language)
209 {
210 case eLanguageTypeC_plus_plus:
211 case eLanguageTypeC_plus_plus_03:
212 case eLanguageTypeC_plus_plus_11:
213 case eLanguageTypeC_plus_plus_14:
214 return true;
215 default:
216 return false;
217 }
218}
219
220bool
221Language::LanguageIsObjC (LanguageType language)
222{
223 switch (language)
224 {
225 case eLanguageTypeObjC:
226 case eLanguageTypeObjC_plus_plus:
227 return true;
228 default:
229 return false;
230 }
231}
232
233bool
234Language::LanguageIsC (LanguageType language)
235{
236 switch (language)
237 {
238 case eLanguageTypeC:
239 case eLanguageTypeC89:
240 case eLanguageTypeC99:
241 case eLanguageTypeC11:
242 return true;
243 default:
244 return false;
245 }
246}
247
248bool
249Language::LanguageIsPascal (LanguageType language)
250{
251 switch (language)
252 {
253 case eLanguageTypePascal83:
254 return true;
255 default:
256 return false;
257 }
258}
259
Enrico Granata5f9d3102015-08-27 21:33:50 +0000260//----------------------------------------------------------------------
261// Constructor
262//----------------------------------------------------------------------
263Language::Language()
264{
265}
266
267//----------------------------------------------------------------------
268// Destructor
269//----------------------------------------------------------------------
270Language::~Language()
271{
272}