SBTypeCategory.cpp revision 263363
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 (!IsValid()) 88 return 0; 89 90 return m_opaque_sp->GetValueNavigator()->GetCount() + m_opaque_sp->GetRegexValueNavigator()->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 (!IsValid()) 131 return SBTypeNameSpecifier(); 132 return SBTypeNameSpecifier(m_opaque_sp->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 (!IsValid()) 181 return SBTypeFormat(); 182 183 if (!spec.IsValid()) 184 return SBTypeFormat(); 185 186 lldb::TypeFormatImplSP format_sp; 187 188 if (spec.IsRegex()) 189 m_opaque_sp->GetRegexValueNavigator()->GetExact(ConstString(spec.GetName()), format_sp); 190 else 191 m_opaque_sp->GetValueNavigator()->GetExact(ConstString(spec.GetName()), format_sp); 192 193 if (!format_sp) 194 return lldb::SBTypeFormat(); 195 196 return lldb::SBTypeFormat(format_sp); 197} 198 199#ifndef LLDB_DISABLE_PYTHON 200SBTypeSummary 201SBTypeCategory::GetSummaryForType (SBTypeNameSpecifier spec) 202{ 203 if (!IsValid()) 204 return SBTypeSummary(); 205 206 if (!spec.IsValid()) 207 return SBTypeSummary(); 208 209 lldb::TypeSummaryImplSP summary_sp; 210 211 if (spec.IsRegex()) 212 m_opaque_sp->GetRegexSummaryNavigator()->GetExact(ConstString(spec.GetName()), summary_sp); 213 else 214 m_opaque_sp->GetSummaryNavigator()->GetExact(ConstString(spec.GetName()), summary_sp); 215 216 if (!summary_sp) 217 return lldb::SBTypeSummary(); 218 219 return lldb::SBTypeSummary(summary_sp); 220} 221#endif // LLDB_DISABLE_PYTHON 222 223#ifndef LLDB_DISABLE_PYTHON 224SBTypeSynthetic 225SBTypeCategory::GetSyntheticForType (SBTypeNameSpecifier spec) 226{ 227 if (!IsValid()) 228 return SBTypeSynthetic(); 229 230 if (!spec.IsValid()) 231 return SBTypeSynthetic(); 232 233 lldb::SyntheticChildrenSP children_sp; 234 235 if (spec.IsRegex()) 236 m_opaque_sp->GetRegexSyntheticNavigator()->GetExact(ConstString(spec.GetName()), children_sp); 237 else 238 m_opaque_sp->GetSyntheticNavigator()->GetExact(ConstString(spec.GetName()), children_sp); 239 240 if (!children_sp) 241 return lldb::SBTypeSynthetic(); 242 243 ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); 244 245 return lldb::SBTypeSynthetic(synth_sp); 246} 247#endif 248 249#ifndef LLDB_DISABLE_PYTHON 250SBTypeFilter 251SBTypeCategory::GetFilterAtIndex (uint32_t index) 252{ 253 if (!IsValid()) 254 return SBTypeFilter(); 255 lldb::SyntheticChildrenSP children_sp = m_opaque_sp->GetSyntheticAtIndex((index)); 256 257 if (!children_sp.get()) 258 return lldb::SBTypeFilter(); 259 260 TypeFilterImplSP filter_sp = std::static_pointer_cast<TypeFilterImpl>(children_sp); 261 262 return lldb::SBTypeFilter(filter_sp); 263} 264#endif 265 266SBTypeFormat 267SBTypeCategory::GetFormatAtIndex (uint32_t index) 268{ 269 if (!IsValid()) 270 return SBTypeFormat(); 271 return SBTypeFormat(m_opaque_sp->GetFormatAtIndex((index))); 272} 273 274#ifndef LLDB_DISABLE_PYTHON 275SBTypeSummary 276SBTypeCategory::GetSummaryAtIndex (uint32_t index) 277{ 278 if (!IsValid()) 279 return SBTypeSummary(); 280 return SBTypeSummary(m_opaque_sp->GetSummaryAtIndex((index))); 281} 282#endif 283 284#ifndef LLDB_DISABLE_PYTHON 285SBTypeSynthetic 286SBTypeCategory::GetSyntheticAtIndex (uint32_t index) 287{ 288 if (!IsValid()) 289 return SBTypeSynthetic(); 290 lldb::SyntheticChildrenSP children_sp = m_opaque_sp->GetSyntheticAtIndex((index)); 291 292 if (!children_sp.get()) 293 return lldb::SBTypeSynthetic(); 294 295 ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); 296 297 return lldb::SBTypeSynthetic(synth_sp); 298} 299#endif 300 301bool 302SBTypeCategory::AddTypeFormat (SBTypeNameSpecifier type_name, 303 SBTypeFormat format) 304{ 305 if (!IsValid()) 306 return false; 307 308 if (!type_name.IsValid()) 309 return false; 310 311 if (!format.IsValid()) 312 return false; 313 314 if (type_name.IsRegex()) 315 m_opaque_sp->GetRegexValueNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), format.GetSP()); 316 else 317 m_opaque_sp->GetValueNavigator()->Add(ConstString(type_name.GetName()), format.GetSP()); 318 319 return true; 320} 321 322bool 323SBTypeCategory::DeleteTypeFormat (SBTypeNameSpecifier type_name) 324{ 325 if (!IsValid()) 326 return false; 327 328 if (!type_name.IsValid()) 329 return false; 330 331 if (type_name.IsRegex()) 332 return m_opaque_sp->GetRegexValueNavigator()->Delete(ConstString(type_name.GetName())); 333 else 334 return m_opaque_sp->GetValueNavigator()->Delete(ConstString(type_name.GetName())); 335} 336 337#ifndef LLDB_DISABLE_PYTHON 338bool 339SBTypeCategory::AddTypeSummary (SBTypeNameSpecifier type_name, 340 SBTypeSummary summary) 341{ 342 if (!IsValid()) 343 return false; 344 345 if (!type_name.IsValid()) 346 return false; 347 348 if (!summary.IsValid()) 349 return false; 350 351 // FIXME: we need to iterate over all the Debugger objects and have each of them contain a copy of the function 352 // since we currently have formatters live in a global space, while Python code lives in a specific Debugger-related environment 353 // this should eventually be fixed by deciding a final location in the LLDB object space for formatters 354 if (summary.IsFunctionCode()) 355 { 356 void *name_token = (void*)ConstString(type_name.GetName()).GetCString(); 357 const char* script = summary.GetData(); 358 StringList input; input.SplitIntoLines(script, strlen(script)); 359 uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers(); 360 bool need_set = true; 361 for (uint32_t j = 0; 362 j < num_debuggers; 363 j++) 364 { 365 DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j); 366 if (debugger_sp) 367 { 368 ScriptInterpreter* interpreter_ptr = debugger_sp->GetCommandInterpreter().GetScriptInterpreter(); 369 if (interpreter_ptr) 370 { 371 std::string output; 372 if (interpreter_ptr->GenerateTypeScriptFunction(input, output, name_token) && !output.empty()) 373 { 374 if (need_set) 375 { 376 need_set = false; 377 summary.SetFunctionName(output.c_str()); 378 } 379 } 380 } 381 } 382 } 383 } 384 385 if (type_name.IsRegex()) 386 m_opaque_sp->GetRegexSummaryNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), summary.GetSP()); 387 else 388 m_opaque_sp->GetSummaryNavigator()->Add(ConstString(type_name.GetName()), summary.GetSP()); 389 390 return true; 391} 392#endif 393 394bool 395SBTypeCategory::DeleteTypeSummary (SBTypeNameSpecifier type_name) 396{ 397 if (!IsValid()) 398 return false; 399 400 if (!type_name.IsValid()) 401 return false; 402 403 if (type_name.IsRegex()) 404 return m_opaque_sp->GetRegexSummaryNavigator()->Delete(ConstString(type_name.GetName())); 405 else 406 return m_opaque_sp->GetSummaryNavigator()->Delete(ConstString(type_name.GetName())); 407} 408 409bool 410SBTypeCategory::AddTypeFilter (SBTypeNameSpecifier type_name, 411 SBTypeFilter filter) 412{ 413 if (!IsValid()) 414 return false; 415 416 if (!type_name.IsValid()) 417 return false; 418 419 if (!filter.IsValid()) 420 return false; 421 422 if (type_name.IsRegex()) 423 m_opaque_sp->GetRegexFilterNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), filter.GetSP()); 424 else 425 m_opaque_sp->GetFilterNavigator()->Add(ConstString(type_name.GetName()), filter.GetSP()); 426 427 return true; 428} 429 430bool 431SBTypeCategory::DeleteTypeFilter (SBTypeNameSpecifier type_name) 432{ 433 if (!IsValid()) 434 return false; 435 436 if (!type_name.IsValid()) 437 return false; 438 439 if (type_name.IsRegex()) 440 return m_opaque_sp->GetRegexFilterNavigator()->Delete(ConstString(type_name.GetName())); 441 else 442 return m_opaque_sp->GetFilterNavigator()->Delete(ConstString(type_name.GetName())); 443} 444 445#ifndef LLDB_DISABLE_PYTHON 446bool 447SBTypeCategory::AddTypeSynthetic (SBTypeNameSpecifier type_name, 448 SBTypeSynthetic synth) 449{ 450 if (!IsValid()) 451 return false; 452 453 if (!type_name.IsValid()) 454 return false; 455 456 if (!synth.IsValid()) 457 return false; 458 459 // FIXME: we need to iterate over all the Debugger objects and have each of them contain a copy of the function 460 // since we currently have formatters live in a global space, while Python code lives in a specific Debugger-related environment 461 // this should eventually be fixed by deciding a final location in the LLDB object space for formatters 462 if (synth.IsClassCode()) 463 { 464 void *name_token = (void*)ConstString(type_name.GetName()).GetCString(); 465 const char* script = synth.GetData(); 466 StringList input; input.SplitIntoLines(script, strlen(script)); 467 uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers(); 468 bool need_set = true; 469 for (uint32_t j = 0; 470 j < num_debuggers; 471 j++) 472 { 473 DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j); 474 if (debugger_sp) 475 { 476 ScriptInterpreter* interpreter_ptr = debugger_sp->GetCommandInterpreter().GetScriptInterpreter(); 477 if (interpreter_ptr) 478 { 479 std::string output; 480 if (interpreter_ptr->GenerateTypeSynthClass(input, output, name_token) && !output.empty()) 481 { 482 if (need_set) 483 { 484 need_set = false; 485 synth.SetClassName(output.c_str()); 486 } 487 } 488 } 489 } 490 } 491 } 492 493 if (type_name.IsRegex()) 494 m_opaque_sp->GetRegexSyntheticNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), synth.GetSP()); 495 else 496 m_opaque_sp->GetSyntheticNavigator()->Add(ConstString(type_name.GetName()), synth.GetSP()); 497 498 return true; 499} 500 501bool 502SBTypeCategory::DeleteTypeSynthetic (SBTypeNameSpecifier type_name) 503{ 504 if (!IsValid()) 505 return false; 506 507 if (!type_name.IsValid()) 508 return false; 509 510 if (type_name.IsRegex()) 511 return m_opaque_sp->GetRegexSyntheticNavigator()->Delete(ConstString(type_name.GetName())); 512 else 513 return m_opaque_sp->GetSyntheticNavigator()->Delete(ConstString(type_name.GetName())); 514} 515#endif // LLDB_DISABLE_PYTHON 516 517bool 518SBTypeCategory::GetDescription (lldb::SBStream &description, 519 lldb::DescriptionLevel description_level) 520{ 521 if (!IsValid()) 522 return false; 523 description.Printf("Category name: %s\n",GetName()); 524 return true; 525} 526 527lldb::SBTypeCategory & 528SBTypeCategory::operator = (const lldb::SBTypeCategory &rhs) 529{ 530 if (this != &rhs) 531 { 532 m_opaque_sp = rhs.m_opaque_sp; 533 } 534 return *this; 535} 536 537bool 538SBTypeCategory::operator == (lldb::SBTypeCategory &rhs) 539{ 540 if (IsValid() == false) 541 return !rhs.IsValid(); 542 543 return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 544 545} 546 547bool 548SBTypeCategory::operator != (lldb::SBTypeCategory &rhs) 549{ 550 if (IsValid() == false) 551 return rhs.IsValid(); 552 553 return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 554} 555 556lldb::TypeCategoryImplSP 557SBTypeCategory::GetSP () 558{ 559 if (!IsValid()) 560 return lldb::TypeCategoryImplSP(); 561 return m_opaque_sp; 562} 563 564void 565SBTypeCategory::SetSP (const lldb::TypeCategoryImplSP &typecategory_impl_sp) 566{ 567 m_opaque_sp = typecategory_impl_sp; 568} 569 570SBTypeCategory::SBTypeCategory (const lldb::TypeCategoryImplSP &typecategory_impl_sp) : 571m_opaque_sp(typecategory_impl_sp) 572{ 573} 574 575bool 576SBTypeCategory::IsDefaultCategory() 577{ 578 if (!IsValid()) 579 return false; 580 581 return (strcmp(m_opaque_sp->GetName(),"default") == 0); 582} 583 584