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