1 //===-- 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> 12 #include <mutex> 13 14 #include "lldb/Target/Language.h" 15 16 #include "lldb/Host/Mutex.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Stream.h" 19 20 using namespace lldb; 21 using namespace lldb_private; 22 using namespace lldb_private::formatters; 23 24 typedef std::unique_ptr<Language> LanguageUP; 25 typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap; 26 27 static LanguagesMap& 28 GetLanguagesMap () 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 } 39 static Mutex& 40 GetLanguagesMutex () 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 52 Language* 53 Language::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 80 void 81 Language::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 92 lldb::TypeCategoryImplSP 93 Language::GetFormatters () 94 { 95 return nullptr; 96 } 97 98 HardcodedFormatters::HardcodedFormatFinder 99 Language::GetHardcodedFormats () 100 { 101 return {}; 102 } 103 104 HardcodedFormatters::HardcodedSummaryFinder 105 Language::GetHardcodedSummaries () 106 { 107 return {}; 108 } 109 110 HardcodedFormatters::HardcodedSyntheticFinder 111 Language::GetHardcodedSynthetics () 112 { 113 return {}; 114 } 115 116 HardcodedFormatters::HardcodedValidatorFinder 117 Language::GetHardcodedValidators () 118 { 119 return {}; 120 } 121 122 std::vector<ConstString> 123 Language::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic) 124 { 125 return {}; 126 } 127 128 lldb_private::formatters::StringPrinter::EscapingHelper 129 Language::GetStringPrinterEscapingHelper (lldb_private::formatters::StringPrinter::GetPrintableElementType elem_type) 130 { 131 return StringPrinter::GetDefaultEscapingHelper(elem_type); 132 } 133 134 struct language_name_pair { 135 const char *name; 136 LanguageType type; 137 }; 138 139 struct language_name_pair language_names[] = 140 { 141 // To allow GetNameForLanguageType to be a simple array lookup, the first 142 // part of this array must follow enum LanguageType exactly. 143 { "unknown", eLanguageTypeUnknown }, 144 { "c89", eLanguageTypeC89 }, 145 { "c", eLanguageTypeC }, 146 { "ada83", eLanguageTypeAda83 }, 147 { "c++", eLanguageTypeC_plus_plus }, 148 { "cobol74", eLanguageTypeCobol74 }, 149 { "cobol85", eLanguageTypeCobol85 }, 150 { "fortran77", eLanguageTypeFortran77 }, 151 { "fortran90", eLanguageTypeFortran90 }, 152 { "pascal83", eLanguageTypePascal83 }, 153 { "modula2", eLanguageTypeModula2 }, 154 { "java", eLanguageTypeJava }, 155 { "c99", eLanguageTypeC99 }, 156 { "ada95", eLanguageTypeAda95 }, 157 { "fortran95", eLanguageTypeFortran95 }, 158 { "pli", eLanguageTypePLI }, 159 { "objective-c", eLanguageTypeObjC }, 160 { "objective-c++", eLanguageTypeObjC_plus_plus }, 161 { "upc", eLanguageTypeUPC }, 162 { "d", eLanguageTypeD }, 163 { "python", eLanguageTypePython }, 164 { "opencl", eLanguageTypeOpenCL }, 165 { "go", eLanguageTypeGo }, 166 { "modula3", eLanguageTypeModula3 }, 167 { "haskell", eLanguageTypeHaskell }, 168 { "c++03", eLanguageTypeC_plus_plus_03 }, 169 { "c++11", eLanguageTypeC_plus_plus_11 }, 170 { "ocaml", eLanguageTypeOCaml }, 171 { "rust", eLanguageTypeRust }, 172 { "c11", eLanguageTypeC11 }, 173 { "swift", eLanguageTypeSwift }, 174 { "julia", eLanguageTypeJulia }, 175 { "dylan", eLanguageTypeDylan }, 176 { "c++14", eLanguageTypeC_plus_plus_14 }, 177 { "fortran03", eLanguageTypeFortran03 }, 178 { "fortran08", eLanguageTypeFortran08 }, 179 // Vendor Extensions 180 { "mipsassem", eLanguageTypeMipsAssembler }, 181 { "renderscript", eLanguageTypeExtRenderScript}, 182 // Now synonyms, in arbitrary order 183 { "objc", eLanguageTypeObjC }, 184 { "objc++", eLanguageTypeObjC_plus_plus }, 185 { "pascal", eLanguageTypePascal83 } 186 }; 187 188 static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair); 189 190 LanguageType 191 Language::GetLanguageTypeFromString (const char *string) 192 { 193 for (uint32_t i = 0; i < num_languages; i++) 194 { 195 if (strcasecmp (language_names[i].name, string) == 0) 196 return (LanguageType) language_names[i].type; 197 } 198 return eLanguageTypeUnknown; 199 } 200 201 const char * 202 Language::GetNameForLanguageType (LanguageType language) 203 { 204 if (language < num_languages) 205 return language_names[language].name; 206 else 207 return language_names[eLanguageTypeUnknown].name; 208 } 209 210 void 211 Language::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix) 212 { 213 for (uint32_t i = 1; i < num_languages; i++) 214 { 215 s.Printf("%s%s%s", prefix, language_names[i].name, suffix); 216 } 217 } 218 219 void 220 Language::ForAllLanguages (std::function<bool(lldb::LanguageType)> callback) 221 { 222 for (uint32_t i = 1; i < num_languages; i++) 223 { 224 if (!callback(language_names[i].type)) 225 break; 226 } 227 } 228 229 bool 230 Language::LanguageIsCPlusPlus (LanguageType language) 231 { 232 switch (language) 233 { 234 case eLanguageTypeC_plus_plus: 235 case eLanguageTypeC_plus_plus_03: 236 case eLanguageTypeC_plus_plus_11: 237 case eLanguageTypeC_plus_plus_14: 238 return true; 239 default: 240 return false; 241 } 242 } 243 244 bool 245 Language::LanguageIsObjC (LanguageType language) 246 { 247 switch (language) 248 { 249 case eLanguageTypeObjC: 250 case eLanguageTypeObjC_plus_plus: 251 return true; 252 default: 253 return false; 254 } 255 } 256 257 bool 258 Language::LanguageIsC (LanguageType language) 259 { 260 switch (language) 261 { 262 case eLanguageTypeC: 263 case eLanguageTypeC89: 264 case eLanguageTypeC99: 265 case eLanguageTypeC11: 266 return true; 267 default: 268 return false; 269 } 270 } 271 272 bool 273 Language::LanguageIsPascal (LanguageType language) 274 { 275 switch (language) 276 { 277 case eLanguageTypePascal83: 278 return true; 279 default: 280 return false; 281 } 282 } 283 284 //---------------------------------------------------------------------- 285 // Constructor 286 //---------------------------------------------------------------------- 287 Language::Language() 288 { 289 } 290 291 //---------------------------------------------------------------------- 292 // Destructor 293 //---------------------------------------------------------------------- 294 Language::~Language() 295 { 296 } 297