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 24using namespace lldb; 25using namespace lldb_private; 26 27typedef std::pair<lldb::TypeCategoryImplSP, user_id_t> ImplType; 28 29SBTypeCategory::SBTypeCategory() { LLDB_INSTRUMENT_VA(this); } 30 31SBTypeCategory::SBTypeCategory(const char *name) { 32 DataVisualization::Categories::GetCategory(ConstString(name), m_opaque_sp); 33} 34 35SBTypeCategory::SBTypeCategory(const lldb::SBTypeCategory &rhs) 36 : m_opaque_sp(rhs.m_opaque_sp) { 37 LLDB_INSTRUMENT_VA(this, rhs); 38} 39 40SBTypeCategory::~SBTypeCategory() = default; 41 42bool SBTypeCategory::IsValid() const { 43 LLDB_INSTRUMENT_VA(this); 44 return this->operator bool(); 45} 46SBTypeCategory::operator bool() const { 47 LLDB_INSTRUMENT_VA(this); 48 49 return (m_opaque_sp.get() != nullptr); 50} 51 52bool SBTypeCategory::GetEnabled() { 53 LLDB_INSTRUMENT_VA(this); 54 55 if (!IsValid()) 56 return false; 57 return m_opaque_sp->IsEnabled(); 58} 59 60void 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 71const char *SBTypeCategory::GetName() { 72 LLDB_INSTRUMENT_VA(this); 73 74 if (!IsValid()) 75 return nullptr; 76 return ConstString(m_opaque_sp->GetName()).GetCString(); 77} 78 79lldb::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 87uint32_t SBTypeCategory::GetNumLanguages() { 88 LLDB_INSTRUMENT_VA(this); 89 90 if (IsValid()) 91 return m_opaque_sp->GetNumLanguages(); 92 return 0; 93} 94 95void SBTypeCategory::AddLanguage(lldb::LanguageType language) { 96 LLDB_INSTRUMENT_VA(this, language); 97 98 if (IsValid()) 99 m_opaque_sp->AddLanguage(language); 100} 101 102uint32_t SBTypeCategory::GetNumFormats() { 103 LLDB_INSTRUMENT_VA(this); 104 105 if (!IsValid()) 106 return 0; 107 108 return m_opaque_sp->GetNumFormats(); 109} 110 111uint32_t SBTypeCategory::GetNumSummaries() { 112 LLDB_INSTRUMENT_VA(this); 113 114 if (!IsValid()) 115 return 0; 116 return m_opaque_sp->GetNumSummaries(); 117} 118 119uint32_t SBTypeCategory::GetNumFilters() { 120 LLDB_INSTRUMENT_VA(this); 121 122 if (!IsValid()) 123 return 0; 124 return m_opaque_sp->GetNumFilters(); 125} 126 127uint32_t SBTypeCategory::GetNumSynthetics() { 128 LLDB_INSTRUMENT_VA(this); 129 130 if (!IsValid()) 131 return 0; 132 return m_opaque_sp->GetNumSynthetics(); 133} 134 135lldb::SBTypeNameSpecifier 136SBTypeCategory::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 145lldb::SBTypeNameSpecifier 146SBTypeCategory::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 155lldb::SBTypeNameSpecifier 156SBTypeCategory::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 165lldb::SBTypeNameSpecifier 166SBTypeCategory::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 175SBTypeFilter 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} 195SBTypeFormat 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 213SBTypeSummary 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 231SBTypeSynthetic 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 252SBTypeFilter 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 269SBTypeFormat 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 277SBTypeSummary 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 285SBTypeSynthetic 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 302bool 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 319bool 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 331bool 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 382bool 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 394bool 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 411bool 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 423bool 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 474bool 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 486bool 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 496lldb::SBTypeCategory &SBTypeCategory:: 497operator=(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 506bool 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 515bool 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 524lldb::TypeCategoryImplSP SBTypeCategory::GetSP() { 525 if (!IsValid()) 526 return lldb::TypeCategoryImplSP(); 527 return m_opaque_sp; 528} 529 530void SBTypeCategory::SetSP( 531 const lldb::TypeCategoryImplSP &typecategory_impl_sp) { 532 m_opaque_sp = typecategory_impl_sp; 533} 534 535SBTypeCategory::SBTypeCategory( 536 const lldb::TypeCategoryImplSP &typecategory_impl_sp) 537 : m_opaque_sp(typecategory_impl_sp) {} 538 539bool SBTypeCategory::IsDefaultCategory() { 540 if (!IsValid()) 541 return false; 542 543 return (strcmp(m_opaque_sp->GetName(), "default") == 0); 544} 545