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