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 26using namespace lldb; 27using namespace lldb_private; 28 29typedef std::pair<lldb::TypeCategoryImplSP,user_id_t> ImplType; 30 31SBTypeCategory::SBTypeCategory() : 32m_opaque_sp() 33{ 34} 35 36SBTypeCategory::SBTypeCategory (const char* name) : 37m_opaque_sp() 38{ 39 DataVisualization::Categories::GetCategory(ConstString(name), m_opaque_sp); 40} 41 42SBTypeCategory::SBTypeCategory (const lldb::SBTypeCategory &rhs) : 43m_opaque_sp(rhs.m_opaque_sp) 44{ 45} 46 47SBTypeCategory::~SBTypeCategory () 48{ 49} 50 51bool 52SBTypeCategory::IsValid() const 53{ 54 return (m_opaque_sp.get() != NULL); 55} 56 57bool 58SBTypeCategory::GetEnabled () 59{ 60 if (!IsValid()) 61 return false; 62 return m_opaque_sp->IsEnabled(); 63} 64 65void 66SBTypeCategory::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 76const char* 77SBTypeCategory::GetName() 78{ 79 if (!IsValid()) 80 return NULL; 81 return m_opaque_sp->GetName(); 82} 83 84uint32_t 85SBTypeCategory::GetNumFormats () 86{ 87 if (!IsDefaultCategory()) 88 return 0; 89 90 return DataVisualization::ValueFormats::GetCount(); 91} 92 93uint32_t 94SBTypeCategory::GetNumSummaries () 95{ 96 if (!IsValid()) 97 return 0; 98 return m_opaque_sp->GetSummaryNavigator()->GetCount() + m_opaque_sp->GetRegexSummaryNavigator()->GetCount(); 99} 100 101uint32_t 102SBTypeCategory::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 110uint32_t 111SBTypeCategory::GetNumSynthetics () 112{ 113 if (!IsValid()) 114 return 0; 115 return m_opaque_sp->GetSyntheticNavigator()->GetCount() + m_opaque_sp->GetRegexSyntheticNavigator()->GetCount(); 116} 117#endif 118 119lldb::SBTypeNameSpecifier 120SBTypeCategory::GetTypeNameSpecifierForFilterAtIndex (uint32_t index) 121{ 122 if (!IsValid()) 123 return SBTypeNameSpecifier(); 124 return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForFilterAtIndex(index)); 125} 126 127lldb::SBTypeNameSpecifier 128SBTypeCategory::GetTypeNameSpecifierForFormatAtIndex (uint32_t index) 129{ 130 if (!IsDefaultCategory()) 131 return SBTypeNameSpecifier(); 132 return SBTypeNameSpecifier(DataVisualization::ValueFormats::GetTypeNameSpecifierForFormatAtIndex(index)); 133} 134 135lldb::SBTypeNameSpecifier 136SBTypeCategory::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 144lldb::SBTypeNameSpecifier 145SBTypeCategory::GetTypeNameSpecifierForSyntheticAtIndex (uint32_t index) 146{ 147 if (!IsValid()) 148 return SBTypeNameSpecifier(); 149 return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForSyntheticAtIndex(index)); 150} 151#endif 152 153SBTypeFilter 154SBTypeCategory::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} 177SBTypeFormat 178SBTypeCategory::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 193SBTypeSummary 194SBTypeCategory::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 217SBTypeSynthetic 218SBTypeCategory::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 243SBTypeFilter 244SBTypeCategory::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 259SBTypeFormat 260SBTypeCategory::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 268SBTypeSummary 269SBTypeCategory::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 278SBTypeSynthetic 279SBTypeCategory::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 294bool 295SBTypeCategory::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 315bool 316SBTypeCategory::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 331bool 332SBTypeCategory::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 387bool 388SBTypeCategory::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 402bool 403SBTypeCategory::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 423bool 424SBTypeCategory::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 439bool 440SBTypeCategory::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 494bool 495SBTypeCategory::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 510bool 511SBTypeCategory::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 520lldb::SBTypeCategory & 521SBTypeCategory::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 530bool 531SBTypeCategory::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 540bool 541SBTypeCategory::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 549lldb::TypeCategoryImplSP 550SBTypeCategory::GetSP () 551{ 552 if (!IsValid()) 553 return lldb::TypeCategoryImplSP(); 554 return m_opaque_sp; 555} 556 557void 558SBTypeCategory::SetSP (const lldb::TypeCategoryImplSP &typecategory_impl_sp) 559{ 560 m_opaque_sp = typecategory_impl_sp; 561} 562 563SBTypeCategory::SBTypeCategory (const lldb::TypeCategoryImplSP &typecategory_impl_sp) : 564m_opaque_sp(typecategory_impl_sp) 565{ 566} 567 568bool 569SBTypeCategory::IsDefaultCategory() 570{ 571 if (!IsValid()) 572 return false; 573 574 return (strcmp(m_opaque_sp->GetName(),"default") == 0); 575} 576 577