blob: 30a0492a39a27db7b6a810f5ee06a357612afbae [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
Jim Ingham0e0984e2015-09-02 01:06:46 +000097struct language_name_pair {
98 const char *name;
99 LanguageType type;
100};
101
102struct language_name_pair language_names[] =
103{
104 // To allow GetNameForLanguageType to be a simple array lookup, the first
105 // part of this array must follow enum LanguageType exactly.
106 { "unknown", eLanguageTypeUnknown },
107 { "c89", eLanguageTypeC89 },
108 { "c", eLanguageTypeC },
109 { "ada83", eLanguageTypeAda83 },
110 { "c++", eLanguageTypeC_plus_plus },
111 { "cobol74", eLanguageTypeCobol74 },
112 { "cobol85", eLanguageTypeCobol85 },
113 { "fortran77", eLanguageTypeFortran77 },
114 { "fortran90", eLanguageTypeFortran90 },
115 { "pascal83", eLanguageTypePascal83 },
116 { "modula2", eLanguageTypeModula2 },
117 { "java", eLanguageTypeJava },
118 { "c99", eLanguageTypeC99 },
119 { "ada95", eLanguageTypeAda95 },
120 { "fortran95", eLanguageTypeFortran95 },
121 { "pli", eLanguageTypePLI },
122 { "objective-c", eLanguageTypeObjC },
123 { "objective-c++", eLanguageTypeObjC_plus_plus },
124 { "upc", eLanguageTypeUPC },
125 { "d", eLanguageTypeD },
126 { "python", eLanguageTypePython },
127 { "opencl", eLanguageTypeOpenCL },
128 { "go", eLanguageTypeGo },
129 { "modula3", eLanguageTypeModula3 },
130 { "haskell", eLanguageTypeHaskell },
131 { "c++03", eLanguageTypeC_plus_plus_03 },
132 { "c++11", eLanguageTypeC_plus_plus_11 },
133 { "ocaml", eLanguageTypeOCaml },
134 { "rust", eLanguageTypeRust },
135 { "c11", eLanguageTypeC11 },
136 { "swift", eLanguageTypeSwift },
137 { "julia", eLanguageTypeJulia },
138 { "dylan", eLanguageTypeDylan },
139 { "c++14", eLanguageTypeC_plus_plus_14 },
140 { "fortran03", eLanguageTypeFortran03 },
141 { "fortran08", eLanguageTypeFortran08 },
142 // Vendor Extensions
143 { "mipsassem", eLanguageTypeMipsAssembler },
144 { "renderscript", eLanguageTypeExtRenderScript},
145 // Now synonyms, in arbitrary order
146 { "objc", eLanguageTypeObjC },
147 { "objc++", eLanguageTypeObjC_plus_plus },
148 { "pascal", eLanguageTypePascal83 }
149};
150
151static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
152
153LanguageType
154Language::GetLanguageTypeFromString (const char *string)
155{
156 for (uint32_t i = 0; i < num_languages; i++)
157 {
158 if (strcasecmp (language_names[i].name, string) == 0)
159 return (LanguageType) language_names[i].type;
160 }
161 return eLanguageTypeUnknown;
162}
163
164const char *
165Language::GetNameForLanguageType (LanguageType language)
166{
167 if (language < num_languages)
168 return language_names[language].name;
169 else
170 return language_names[eLanguageTypeUnknown].name;
171}
172
173void
174Language::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix)
175{
176 for (uint32_t i = 1; i < num_languages; i++)
177 {
178 s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
179 }
180}
181
182bool
183Language::LanguageIsCPlusPlus (LanguageType language)
184{
185 switch (language)
186 {
187 case eLanguageTypeC_plus_plus:
188 case eLanguageTypeC_plus_plus_03:
189 case eLanguageTypeC_plus_plus_11:
190 case eLanguageTypeC_plus_plus_14:
191 return true;
192 default:
193 return false;
194 }
195}
196
197bool
198Language::LanguageIsObjC (LanguageType language)
199{
200 switch (language)
201 {
202 case eLanguageTypeObjC:
203 case eLanguageTypeObjC_plus_plus:
204 return true;
205 default:
206 return false;
207 }
208}
209
210bool
211Language::LanguageIsC (LanguageType language)
212{
213 switch (language)
214 {
215 case eLanguageTypeC:
216 case eLanguageTypeC89:
217 case eLanguageTypeC99:
218 case eLanguageTypeC11:
219 return true;
220 default:
221 return false;
222 }
223}
224
225bool
226Language::LanguageIsPascal (LanguageType language)
227{
228 switch (language)
229 {
230 case eLanguageTypePascal83:
231 return true;
232 default:
233 return false;
234 }
235}
236
Enrico Granata5f9d3102015-08-27 21:33:50 +0000237//----------------------------------------------------------------------
238// Constructor
239//----------------------------------------------------------------------
240Language::Language()
241{
242}
243
244//----------------------------------------------------------------------
245// Destructor
246//----------------------------------------------------------------------
247Language::~Language()
248{
249}