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/Core/PluginManager.h" 17 #include "lldb/Core/Stream.h" 18 19 using namespace lldb; 20 using namespace lldb_private; 21 using namespace lldb_private::formatters; 22 23 typedef std::unique_ptr<Language> LanguageUP; 24 typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap; 25 26 static LanguagesMap& 27 GetLanguagesMap () 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 } 38 static std::mutex & 39 GetLanguagesMutex() 40 { 41 static std::mutex *g_mutex = nullptr; 42 static std::once_flag g_initialize; 43 44 std::call_once(g_initialize, [] { 45 g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global destructor chain 46 }); 47 48 return *g_mutex; 49 } 50 51 Language* 52 Language::FindPlugin (lldb::LanguageType language) 53 { 54 std::lock_guard<std::mutex> guard(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 79 void 80 Language::ForEach (std::function<bool(Language*)> callback) 81 { 82 std::lock_guard<std::mutex> guard(GetLanguagesMutex()); 83 LanguagesMap& map(GetLanguagesMap()); 84 for (const auto& entry : map) 85 { 86 if (!callback(entry.second.get())) 87 break; 88 } 89 } 90 91 bool 92 Language::IsTopLevelFunction (Function& function) 93 { 94 return false; 95 } 96 97 lldb::TypeCategoryImplSP 98 Language::GetFormatters () 99 { 100 return nullptr; 101 } 102 103 HardcodedFormatters::HardcodedFormatFinder 104 Language::GetHardcodedFormats () 105 { 106 return {}; 107 } 108 109 HardcodedFormatters::HardcodedSummaryFinder 110 Language::GetHardcodedSummaries () 111 { 112 return {}; 113 } 114 115 HardcodedFormatters::HardcodedSyntheticFinder 116 Language::GetHardcodedSynthetics () 117 { 118 return {}; 119 } 120 121 HardcodedFormatters::HardcodedValidatorFinder 122 Language::GetHardcodedValidators () 123 { 124 return {}; 125 } 126 127 std::vector<ConstString> 128 Language::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic) 129 { 130 return {}; 131 } 132 133 lldb_private::formatters::StringPrinter::EscapingHelper 134 Language::GetStringPrinterEscapingHelper (lldb_private::formatters::StringPrinter::GetPrintableElementType elem_type) 135 { 136 return StringPrinter::GetDefaultEscapingHelper(elem_type); 137 } 138 139 struct language_name_pair { 140 const char *name; 141 LanguageType type; 142 }; 143 144 struct language_name_pair language_names[] = 145 { 146 // To allow GetNameForLanguageType to be a simple array lookup, the first 147 // part of this array must follow enum LanguageType exactly. 148 { "unknown", eLanguageTypeUnknown }, 149 { "c89", eLanguageTypeC89 }, 150 { "c", eLanguageTypeC }, 151 { "ada83", eLanguageTypeAda83 }, 152 { "c++", eLanguageTypeC_plus_plus }, 153 { "cobol74", eLanguageTypeCobol74 }, 154 { "cobol85", eLanguageTypeCobol85 }, 155 { "fortran77", eLanguageTypeFortran77 }, 156 { "fortran90", eLanguageTypeFortran90 }, 157 { "pascal83", eLanguageTypePascal83 }, 158 { "modula2", eLanguageTypeModula2 }, 159 { "java", eLanguageTypeJava }, 160 { "c99", eLanguageTypeC99 }, 161 { "ada95", eLanguageTypeAda95 }, 162 { "fortran95", eLanguageTypeFortran95 }, 163 { "pli", eLanguageTypePLI }, 164 { "objective-c", eLanguageTypeObjC }, 165 { "objective-c++", eLanguageTypeObjC_plus_plus }, 166 { "upc", eLanguageTypeUPC }, 167 { "d", eLanguageTypeD }, 168 { "python", eLanguageTypePython }, 169 { "opencl", eLanguageTypeOpenCL }, 170 { "go", eLanguageTypeGo }, 171 { "modula3", eLanguageTypeModula3 }, 172 { "haskell", eLanguageTypeHaskell }, 173 { "c++03", eLanguageTypeC_plus_plus_03 }, 174 { "c++11", eLanguageTypeC_plus_plus_11 }, 175 { "ocaml", eLanguageTypeOCaml }, 176 { "rust", eLanguageTypeRust }, 177 { "c11", eLanguageTypeC11 }, 178 { "swift", eLanguageTypeSwift }, 179 { "julia", eLanguageTypeJulia }, 180 { "dylan", eLanguageTypeDylan }, 181 { "c++14", eLanguageTypeC_plus_plus_14 }, 182 { "fortran03", eLanguageTypeFortran03 }, 183 { "fortran08", eLanguageTypeFortran08 }, 184 // Vendor Extensions 185 { "mipsassem", eLanguageTypeMipsAssembler }, 186 { "renderscript", eLanguageTypeExtRenderScript}, 187 // Now synonyms, in arbitrary order 188 { "objc", eLanguageTypeObjC }, 189 { "objc++", eLanguageTypeObjC_plus_plus }, 190 { "pascal", eLanguageTypePascal83 } 191 }; 192 193 static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair); 194 195 LanguageType 196 Language::GetLanguageTypeFromString (const char *string) 197 { 198 for (uint32_t i = 0; i < num_languages; i++) 199 { 200 if (strcasecmp (language_names[i].name, string) == 0) 201 return (LanguageType) language_names[i].type; 202 } 203 return eLanguageTypeUnknown; 204 } 205 206 const char * 207 Language::GetNameForLanguageType (LanguageType language) 208 { 209 if (language < num_languages) 210 return language_names[language].name; 211 else 212 return language_names[eLanguageTypeUnknown].name; 213 } 214 215 void 216 Language::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix) 217 { 218 for (uint32_t i = 1; i < num_languages; i++) 219 { 220 s.Printf("%s%s%s", prefix, language_names[i].name, suffix); 221 } 222 } 223 224 void 225 Language::ForAllLanguages (std::function<bool(lldb::LanguageType)> callback) 226 { 227 for (uint32_t i = 1; i < num_languages; i++) 228 { 229 if (!callback(language_names[i].type)) 230 break; 231 } 232 } 233 234 bool 235 Language::LanguageIsCPlusPlus (LanguageType language) 236 { 237 switch (language) 238 { 239 case eLanguageTypeC_plus_plus: 240 case eLanguageTypeC_plus_plus_03: 241 case eLanguageTypeC_plus_plus_11: 242 case eLanguageTypeC_plus_plus_14: 243 case eLanguageTypeObjC_plus_plus: 244 return true; 245 default: 246 return false; 247 } 248 } 249 250 bool 251 Language::LanguageIsObjC (LanguageType language) 252 { 253 switch (language) 254 { 255 case eLanguageTypeObjC: 256 case eLanguageTypeObjC_plus_plus: 257 return true; 258 default: 259 return false; 260 } 261 } 262 263 bool 264 Language::LanguageIsC (LanguageType language) 265 { 266 switch (language) 267 { 268 case eLanguageTypeC: 269 case eLanguageTypeC89: 270 case eLanguageTypeC99: 271 case eLanguageTypeC11: 272 return true; 273 default: 274 return false; 275 } 276 } 277 278 bool 279 Language::LanguageIsPascal (LanguageType language) 280 { 281 switch (language) 282 { 283 case eLanguageTypePascal83: 284 return true; 285 default: 286 return false; 287 } 288 } 289 290 LanguageType 291 Language::GetPrimaryLanguage (LanguageType language) 292 { 293 switch (language) 294 { 295 case eLanguageTypeC_plus_plus: 296 case eLanguageTypeC_plus_plus_03: 297 case eLanguageTypeC_plus_plus_11: 298 case eLanguageTypeC_plus_plus_14: 299 return eLanguageTypeC_plus_plus; 300 case eLanguageTypeC: 301 case eLanguageTypeC89: 302 case eLanguageTypeC99: 303 case eLanguageTypeC11: 304 return eLanguageTypeC; 305 case eLanguageTypeObjC: 306 case eLanguageTypeObjC_plus_plus: 307 return eLanguageTypeObjC; 308 case eLanguageTypePascal83: 309 case eLanguageTypeCobol74: 310 case eLanguageTypeCobol85: 311 case eLanguageTypeFortran77: 312 case eLanguageTypeFortran90: 313 case eLanguageTypeFortran95: 314 case eLanguageTypeFortran03: 315 case eLanguageTypeFortran08: 316 case eLanguageTypeAda83: 317 case eLanguageTypeAda95: 318 case eLanguageTypeModula2: 319 case eLanguageTypeJava: 320 case eLanguageTypePLI: 321 case eLanguageTypeUPC: 322 case eLanguageTypeD: 323 case eLanguageTypePython: 324 case eLanguageTypeOpenCL: 325 case eLanguageTypeGo: 326 case eLanguageTypeModula3: 327 case eLanguageTypeHaskell: 328 case eLanguageTypeOCaml: 329 case eLanguageTypeRust: 330 case eLanguageTypeSwift: 331 case eLanguageTypeJulia: 332 case eLanguageTypeDylan: 333 case eLanguageTypeMipsAssembler: 334 case eLanguageTypeExtRenderScript: 335 case eLanguageTypeUnknown: 336 default: 337 return language; 338 } 339 } 340 341 void 342 Language::GetLanguagesSupportingTypeSystems (std::set<lldb::LanguageType> &languages, 343 std::set<lldb::LanguageType> &languages_for_expressions) 344 { 345 uint32_t idx = 0; 346 347 while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++)) 348 { 349 (*enumerate)(languages, languages_for_expressions); 350 } 351 } 352 353 void 354 Language::GetLanguagesSupportingREPLs (std::set<lldb::LanguageType> &languages) 355 { 356 uint32_t idx = 0; 357 358 while (REPLEnumerateSupportedLanguages enumerate = PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(idx++)) 359 { 360 (*enumerate)(languages); 361 } 362 } 363 364 std::unique_ptr<Language::TypeScavenger> 365 Language::GetTypeScavenger () 366 { 367 return nullptr; 368 } 369 370 const char* 371 Language::GetLanguageSpecificTypeLookupHelp () 372 { 373 return nullptr; 374 } 375 376 size_t 377 Language::TypeScavenger::Find (ExecutionContextScope *exe_scope, 378 const char *key, 379 ResultSet &results, 380 bool append) 381 { 382 if (!exe_scope || !exe_scope->CalculateTarget().get()) 383 return false; 384 385 if (!key || !key[0]) 386 return false; 387 388 if (!append) 389 results.clear(); 390 391 size_t old_size = results.size(); 392 393 if (this->Find_Impl(exe_scope, key, results)) 394 return results.size() - old_size; 395 return 0; 396 } 397 398 bool 399 Language::GetFormatterPrefixSuffix (ValueObject& valobj, ConstString type_hint, 400 std::string& prefix, std::string& suffix) 401 { 402 return false; 403 } 404 405 DumpValueObjectOptions::DeclPrintingHelper 406 Language::GetDeclPrintingHelper () 407 { 408 return nullptr; 409 } 410 411 LazyBool 412 Language::IsLogicalTrue (ValueObject& valobj, 413 Error& error) 414 { 415 return eLazyBoolCalculate; 416 } 417 418 bool 419 Language::IsNilReference (ValueObject& valobj) 420 { 421 return false; 422 } 423 424 bool 425 Language::IsUninitializedReference (ValueObject& valobj) 426 { 427 return false; 428 } 429 430 bool 431 Language::GetFunctionDisplayName (const SymbolContext *sc, 432 const ExecutionContext *exe_ctx, 433 FunctionNameRepresentation representation, 434 Stream& s) 435 { 436 return false; 437 } 438 439 void 440 Language::GetExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s) 441 { 442 GetDefaultExceptionResolverDescription(catch_on, throw_on, s); 443 } 444 445 void 446 Language::GetDefaultExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s) 447 { 448 s.Printf ("Exception breakpoint (catch: %s throw: %s)", 449 catch_on ? "on" : "off", 450 throw_on ? "on" : "off"); 451 } 452 //---------------------------------------------------------------------- 453 // Constructor 454 //---------------------------------------------------------------------- 455 Language::Language() 456 { 457 } 458 459 //---------------------------------------------------------------------- 460 // Destructor 461 //---------------------------------------------------------------------- 462 Language::~Language() 463 { 464 } 465