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