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