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