1 //===-- SBTypeCategory.cpp ------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBTypeCategory.h" 10 #include "lldb/Utility/Instrumentation.h" 11 12 #include "lldb/API/SBStream.h" 13 #include "lldb/API/SBTypeFilter.h" 14 #include "lldb/API/SBTypeFormat.h" 15 #include "lldb/API/SBTypeNameSpecifier.h" 16 #include "lldb/API/SBTypeSummary.h" 17 #include "lldb/API/SBTypeSynthetic.h" 18 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/DataFormatters/DataVisualization.h" 21 #include "lldb/Interpreter/CommandInterpreter.h" 22 #include "lldb/Interpreter/ScriptInterpreter.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 typedef std::pair<lldb::TypeCategoryImplSP, user_id_t> ImplType; 28 29 SBTypeCategory::SBTypeCategory() { LLDB_INSTRUMENT_VA(this); } 30 31 SBTypeCategory::SBTypeCategory(const char *name) { 32 DataVisualization::Categories::GetCategory(ConstString(name), m_opaque_sp); 33 } 34 35 SBTypeCategory::SBTypeCategory(const lldb::SBTypeCategory &rhs) 36 : m_opaque_sp(rhs.m_opaque_sp) { 37 LLDB_INSTRUMENT_VA(this, rhs); 38 } 39 40 SBTypeCategory::~SBTypeCategory() = default; 41 42 bool SBTypeCategory::IsValid() const { 43 LLDB_INSTRUMENT_VA(this); 44 return this->operator bool(); 45 } 46 SBTypeCategory::operator bool() const { 47 LLDB_INSTRUMENT_VA(this); 48 49 return (m_opaque_sp.get() != nullptr); 50 } 51 52 bool SBTypeCategory::GetEnabled() { 53 LLDB_INSTRUMENT_VA(this); 54 55 if (!IsValid()) 56 return false; 57 return m_opaque_sp->IsEnabled(); 58 } 59 60 void SBTypeCategory::SetEnabled(bool enabled) { 61 LLDB_INSTRUMENT_VA(this, enabled); 62 63 if (!IsValid()) 64 return; 65 if (enabled) 66 DataVisualization::Categories::Enable(m_opaque_sp); 67 else 68 DataVisualization::Categories::Disable(m_opaque_sp); 69 } 70 71 const char *SBTypeCategory::GetName() { 72 LLDB_INSTRUMENT_VA(this); 73 74 if (!IsValid()) 75 return nullptr; 76 return m_opaque_sp->GetName(); 77 } 78 79 lldb::LanguageType SBTypeCategory::GetLanguageAtIndex(uint32_t idx) { 80 LLDB_INSTRUMENT_VA(this, idx); 81 82 if (IsValid()) 83 return m_opaque_sp->GetLanguageAtIndex(idx); 84 return lldb::eLanguageTypeUnknown; 85 } 86 87 uint32_t SBTypeCategory::GetNumLanguages() { 88 LLDB_INSTRUMENT_VA(this); 89 90 if (IsValid()) 91 return m_opaque_sp->GetNumLanguages(); 92 return 0; 93 } 94 95 void SBTypeCategory::AddLanguage(lldb::LanguageType language) { 96 LLDB_INSTRUMENT_VA(this, language); 97 98 if (IsValid()) 99 m_opaque_sp->AddLanguage(language); 100 } 101 102 uint32_t SBTypeCategory::GetNumFormats() { 103 LLDB_INSTRUMENT_VA(this); 104 105 if (!IsValid()) 106 return 0; 107 108 return m_opaque_sp->GetNumFormats(); 109 } 110 111 uint32_t SBTypeCategory::GetNumSummaries() { 112 LLDB_INSTRUMENT_VA(this); 113 114 if (!IsValid()) 115 return 0; 116 return m_opaque_sp->GetNumSummaries(); 117 } 118 119 uint32_t SBTypeCategory::GetNumFilters() { 120 LLDB_INSTRUMENT_VA(this); 121 122 if (!IsValid()) 123 return 0; 124 return m_opaque_sp->GetNumFilters(); 125 } 126 127 uint32_t SBTypeCategory::GetNumSynthetics() { 128 LLDB_INSTRUMENT_VA(this); 129 130 if (!IsValid()) 131 return 0; 132 return m_opaque_sp->GetNumSynthetics(); 133 } 134 135 lldb::SBTypeNameSpecifier 136 SBTypeCategory::GetTypeNameSpecifierForFilterAtIndex(uint32_t index) { 137 LLDB_INSTRUMENT_VA(this, index); 138 139 if (!IsValid()) 140 return SBTypeNameSpecifier(); 141 return SBTypeNameSpecifier( 142 m_opaque_sp->GetTypeNameSpecifierForFilterAtIndex(index)); 143 } 144 145 lldb::SBTypeNameSpecifier 146 SBTypeCategory::GetTypeNameSpecifierForFormatAtIndex(uint32_t index) { 147 LLDB_INSTRUMENT_VA(this, index); 148 149 if (!IsValid()) 150 return SBTypeNameSpecifier(); 151 return SBTypeNameSpecifier( 152 m_opaque_sp->GetTypeNameSpecifierForFormatAtIndex(index)); 153 } 154 155 lldb::SBTypeNameSpecifier 156 SBTypeCategory::GetTypeNameSpecifierForSummaryAtIndex(uint32_t index) { 157 LLDB_INSTRUMENT_VA(this, index); 158 159 if (!IsValid()) 160 return SBTypeNameSpecifier(); 161 return SBTypeNameSpecifier( 162 m_opaque_sp->GetTypeNameSpecifierForSummaryAtIndex(index)); 163 } 164 165 lldb::SBTypeNameSpecifier 166 SBTypeCategory::GetTypeNameSpecifierForSyntheticAtIndex(uint32_t index) { 167 LLDB_INSTRUMENT_VA(this, index); 168 169 if (!IsValid()) 170 return SBTypeNameSpecifier(); 171 return SBTypeNameSpecifier( 172 m_opaque_sp->GetTypeNameSpecifierForSyntheticAtIndex(index)); 173 } 174 175 SBTypeFilter SBTypeCategory::GetFilterForType(SBTypeNameSpecifier spec) { 176 LLDB_INSTRUMENT_VA(this, spec); 177 178 if (!IsValid()) 179 return SBTypeFilter(); 180 181 if (!spec.IsValid()) 182 return SBTypeFilter(); 183 184 lldb::TypeFilterImplSP children_sp = 185 m_opaque_sp->GetFilterForType(spec.GetSP()); 186 187 if (!children_sp) 188 return lldb::SBTypeFilter(); 189 190 TypeFilterImplSP filter_sp = 191 std::static_pointer_cast<TypeFilterImpl>(children_sp); 192 193 return lldb::SBTypeFilter(filter_sp); 194 } 195 SBTypeFormat SBTypeCategory::GetFormatForType(SBTypeNameSpecifier spec) { 196 LLDB_INSTRUMENT_VA(this, spec); 197 198 if (!IsValid()) 199 return SBTypeFormat(); 200 201 if (!spec.IsValid()) 202 return SBTypeFormat(); 203 204 lldb::TypeFormatImplSP format_sp = 205 m_opaque_sp->GetFormatForType(spec.GetSP()); 206 207 if (!format_sp) 208 return lldb::SBTypeFormat(); 209 210 return lldb::SBTypeFormat(format_sp); 211 } 212 213 SBTypeSummary SBTypeCategory::GetSummaryForType(SBTypeNameSpecifier spec) { 214 LLDB_INSTRUMENT_VA(this, spec); 215 216 if (!IsValid()) 217 return SBTypeSummary(); 218 219 if (!spec.IsValid()) 220 return SBTypeSummary(); 221 222 lldb::TypeSummaryImplSP summary_sp = 223 m_opaque_sp->GetSummaryForType(spec.GetSP()); 224 225 if (!summary_sp) 226 return lldb::SBTypeSummary(); 227 228 return lldb::SBTypeSummary(summary_sp); 229 } 230 231 SBTypeSynthetic SBTypeCategory::GetSyntheticForType(SBTypeNameSpecifier spec) { 232 LLDB_INSTRUMENT_VA(this, spec); 233 234 if (!IsValid()) 235 return SBTypeSynthetic(); 236 237 if (!spec.IsValid()) 238 return SBTypeSynthetic(); 239 240 lldb::SyntheticChildrenSP children_sp = 241 m_opaque_sp->GetSyntheticForType(spec.GetSP()); 242 243 if (!children_sp) 244 return lldb::SBTypeSynthetic(); 245 246 ScriptedSyntheticChildrenSP synth_sp = 247 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); 248 249 return lldb::SBTypeSynthetic(synth_sp); 250 } 251 252 SBTypeFilter SBTypeCategory::GetFilterAtIndex(uint32_t index) { 253 LLDB_INSTRUMENT_VA(this, index); 254 255 if (!IsValid()) 256 return SBTypeFilter(); 257 lldb::SyntheticChildrenSP children_sp = 258 m_opaque_sp->GetSyntheticAtIndex((index)); 259 260 if (!children_sp.get()) 261 return lldb::SBTypeFilter(); 262 263 TypeFilterImplSP filter_sp = 264 std::static_pointer_cast<TypeFilterImpl>(children_sp); 265 266 return lldb::SBTypeFilter(filter_sp); 267 } 268 269 SBTypeFormat SBTypeCategory::GetFormatAtIndex(uint32_t index) { 270 LLDB_INSTRUMENT_VA(this, index); 271 272 if (!IsValid()) 273 return SBTypeFormat(); 274 return SBTypeFormat(m_opaque_sp->GetFormatAtIndex((index))); 275 } 276 277 SBTypeSummary SBTypeCategory::GetSummaryAtIndex(uint32_t index) { 278 LLDB_INSTRUMENT_VA(this, index); 279 280 if (!IsValid()) 281 return SBTypeSummary(); 282 return SBTypeSummary(m_opaque_sp->GetSummaryAtIndex((index))); 283 } 284 285 SBTypeSynthetic SBTypeCategory::GetSyntheticAtIndex(uint32_t index) { 286 LLDB_INSTRUMENT_VA(this, index); 287 288 if (!IsValid()) 289 return SBTypeSynthetic(); 290 lldb::SyntheticChildrenSP children_sp = 291 m_opaque_sp->GetSyntheticAtIndex((index)); 292 293 if (!children_sp.get()) 294 return lldb::SBTypeSynthetic(); 295 296 ScriptedSyntheticChildrenSP synth_sp = 297 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); 298 299 return lldb::SBTypeSynthetic(synth_sp); 300 } 301 302 bool SBTypeCategory::AddTypeFormat(SBTypeNameSpecifier type_name, 303 SBTypeFormat format) { 304 LLDB_INSTRUMENT_VA(this, type_name, format); 305 306 if (!IsValid()) 307 return false; 308 309 if (!type_name.IsValid()) 310 return false; 311 312 if (!format.IsValid()) 313 return false; 314 315 m_opaque_sp->AddTypeFormat(type_name.GetSP(), format.GetSP()); 316 return true; 317 } 318 319 bool SBTypeCategory::DeleteTypeFormat(SBTypeNameSpecifier type_name) { 320 LLDB_INSTRUMENT_VA(this, type_name); 321 322 if (!IsValid()) 323 return false; 324 325 if (!type_name.IsValid()) 326 return false; 327 328 return m_opaque_sp->DeleteTypeFormat(type_name.GetSP()); 329 } 330 331 bool SBTypeCategory::AddTypeSummary(SBTypeNameSpecifier type_name, 332 SBTypeSummary summary) { 333 LLDB_INSTRUMENT_VA(this, type_name, summary); 334 335 if (!IsValid()) 336 return false; 337 338 if (!type_name.IsValid()) 339 return false; 340 341 if (!summary.IsValid()) 342 return false; 343 344 // FIXME: we need to iterate over all the Debugger objects and have each of 345 // them contain a copy of the function 346 // since we currently have formatters live in a global space, while Python 347 // code lives in a specific Debugger-related environment this should 348 // eventually be fixed by deciding a final location in the LLDB object space 349 // for formatters 350 if (summary.IsFunctionCode()) { 351 const void *name_token = 352 (const void *)ConstString(type_name.GetName()).GetCString(); 353 const char *script = summary.GetData(); 354 StringList input; 355 input.SplitIntoLines(script, strlen(script)); 356 uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers(); 357 bool need_set = true; 358 for (uint32_t j = 0; j < num_debuggers; j++) { 359 DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j); 360 if (debugger_sp) { 361 ScriptInterpreter *interpreter_ptr = 362 debugger_sp->GetScriptInterpreter(); 363 if (interpreter_ptr) { 364 std::string output; 365 if (interpreter_ptr->GenerateTypeScriptFunction(input, output, 366 name_token) && 367 !output.empty()) { 368 if (need_set) { 369 need_set = false; 370 summary.SetFunctionName(output.c_str()); 371 } 372 } 373 } 374 } 375 } 376 } 377 378 m_opaque_sp->AddTypeSummary(type_name.GetSP(), summary.GetSP()); 379 return true; 380 } 381 382 bool SBTypeCategory::DeleteTypeSummary(SBTypeNameSpecifier type_name) { 383 LLDB_INSTRUMENT_VA(this, type_name); 384 385 if (!IsValid()) 386 return false; 387 388 if (!type_name.IsValid()) 389 return false; 390 391 return m_opaque_sp->DeleteTypeSummary(type_name.GetSP()); 392 } 393 394 bool SBTypeCategory::AddTypeFilter(SBTypeNameSpecifier type_name, 395 SBTypeFilter filter) { 396 LLDB_INSTRUMENT_VA(this, type_name, filter); 397 398 if (!IsValid()) 399 return false; 400 401 if (!type_name.IsValid()) 402 return false; 403 404 if (!filter.IsValid()) 405 return false; 406 407 m_opaque_sp->AddTypeFilter(type_name.GetSP(), filter.GetSP()); 408 return true; 409 } 410 411 bool SBTypeCategory::DeleteTypeFilter(SBTypeNameSpecifier type_name) { 412 LLDB_INSTRUMENT_VA(this, type_name); 413 414 if (!IsValid()) 415 return false; 416 417 if (!type_name.IsValid()) 418 return false; 419 420 return m_opaque_sp->DeleteTypeFilter(type_name.GetSP()); 421 } 422 423 bool SBTypeCategory::AddTypeSynthetic(SBTypeNameSpecifier type_name, 424 SBTypeSynthetic synth) { 425 LLDB_INSTRUMENT_VA(this, type_name, synth); 426 427 if (!IsValid()) 428 return false; 429 430 if (!type_name.IsValid()) 431 return false; 432 433 if (!synth.IsValid()) 434 return false; 435 436 // FIXME: we need to iterate over all the Debugger objects and have each of 437 // them contain a copy of the function 438 // since we currently have formatters live in a global space, while Python 439 // code lives in a specific Debugger-related environment this should 440 // eventually be fixed by deciding a final location in the LLDB object space 441 // for formatters 442 if (synth.IsClassCode()) { 443 const void *name_token = 444 (const void *)ConstString(type_name.GetName()).GetCString(); 445 const char *script = synth.GetData(); 446 StringList input; 447 input.SplitIntoLines(script, strlen(script)); 448 uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers(); 449 bool need_set = true; 450 for (uint32_t j = 0; j < num_debuggers; j++) { 451 DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j); 452 if (debugger_sp) { 453 ScriptInterpreter *interpreter_ptr = 454 debugger_sp->GetScriptInterpreter(); 455 if (interpreter_ptr) { 456 std::string output; 457 if (interpreter_ptr->GenerateTypeSynthClass(input, output, 458 name_token) && 459 !output.empty()) { 460 if (need_set) { 461 need_set = false; 462 synth.SetClassName(output.c_str()); 463 } 464 } 465 } 466 } 467 } 468 } 469 470 m_opaque_sp->AddTypeSynthetic(type_name.GetSP(), synth.GetSP()); 471 return true; 472 } 473 474 bool SBTypeCategory::DeleteTypeSynthetic(SBTypeNameSpecifier type_name) { 475 LLDB_INSTRUMENT_VA(this, type_name); 476 477 if (!IsValid()) 478 return false; 479 480 if (!type_name.IsValid()) 481 return false; 482 483 return m_opaque_sp->DeleteTypeSynthetic(type_name.GetSP()); 484 } 485 486 bool SBTypeCategory::GetDescription(lldb::SBStream &description, 487 lldb::DescriptionLevel description_level) { 488 LLDB_INSTRUMENT_VA(this, description, description_level); 489 490 if (!IsValid()) 491 return false; 492 description.Printf("Category name: %s\n", GetName()); 493 return true; 494 } 495 496 lldb::SBTypeCategory &SBTypeCategory:: 497 operator=(const lldb::SBTypeCategory &rhs) { 498 LLDB_INSTRUMENT_VA(this, rhs); 499 500 if (this != &rhs) { 501 m_opaque_sp = rhs.m_opaque_sp; 502 } 503 return *this; 504 } 505 506 bool SBTypeCategory::operator==(lldb::SBTypeCategory &rhs) { 507 LLDB_INSTRUMENT_VA(this, rhs); 508 509 if (!IsValid()) 510 return !rhs.IsValid(); 511 512 return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 513 } 514 515 bool SBTypeCategory::operator!=(lldb::SBTypeCategory &rhs) { 516 LLDB_INSTRUMENT_VA(this, rhs); 517 518 if (!IsValid()) 519 return rhs.IsValid(); 520 521 return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 522 } 523 524 lldb::TypeCategoryImplSP SBTypeCategory::GetSP() { 525 if (!IsValid()) 526 return lldb::TypeCategoryImplSP(); 527 return m_opaque_sp; 528 } 529 530 void SBTypeCategory::SetSP( 531 const lldb::TypeCategoryImplSP &typecategory_impl_sp) { 532 m_opaque_sp = typecategory_impl_sp; 533 } 534 535 SBTypeCategory::SBTypeCategory( 536 const lldb::TypeCategoryImplSP &typecategory_impl_sp) 537 : m_opaque_sp(typecategory_impl_sp) {} 538 539 bool SBTypeCategory::IsDefaultCategory() { 540 if (!IsValid()) 541 return false; 542 543 return (strcmp(m_opaque_sp->GetName(), "default") == 0); 544 } 545