1 //===-- TypeSummary.h --------------------------------------------*- 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 #ifndef lldb_TypeSummary_h_ 11 #define lldb_TypeSummary_h_ 12 13 // C Includes 14 #include <stdint.h> 15 #include <unistd.h> 16 17 // C++ Includes 18 #include <string> 19 #include <vector> 20 21 // Other libraries and framework includes 22 23 // Project includes 24 #include "lldb/lldb-public.h" 25 #include "lldb/lldb-enumerations.h" 26 27 #include "lldb/Core/ValueObject.h" 28 #include "lldb/Interpreter/ScriptInterpreterPython.h" 29 #include "lldb/Symbol/Type.h" 30 31 namespace lldb_private { 32 33 class TypeSummaryImpl 34 { 35 public: 36 class Flags 37 { 38 public: 39 Flags()40 Flags () : 41 m_flags (lldb::eTypeOptionCascade) 42 {} 43 Flags(const Flags & other)44 Flags (const Flags& other) : 45 m_flags (other.m_flags) 46 {} 47 Flags(uint32_t value)48 Flags (uint32_t value) : 49 m_flags (value) 50 {} 51 52 Flags& 53 operator = (const Flags& rhs) 54 { 55 if (&rhs != this) 56 m_flags = rhs.m_flags; 57 58 return *this; 59 } 60 61 Flags& 62 operator = (const uint32_t& rhs) 63 { 64 m_flags = rhs; 65 return *this; 66 } 67 68 Flags& Clear()69 Clear() 70 { 71 m_flags = 0; 72 return *this; 73 } 74 75 bool GetCascades()76 GetCascades () const 77 { 78 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade; 79 } 80 81 Flags& 82 SetCascades (bool value = true) 83 { 84 if (value) 85 m_flags |= lldb::eTypeOptionCascade; 86 else 87 m_flags &= ~lldb::eTypeOptionCascade; 88 return *this; 89 } 90 91 bool GetSkipPointers()92 GetSkipPointers () const 93 { 94 return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers; 95 } 96 97 Flags& 98 SetSkipPointers (bool value = true) 99 { 100 if (value) 101 m_flags |= lldb::eTypeOptionSkipPointers; 102 else 103 m_flags &= ~lldb::eTypeOptionSkipPointers; 104 return *this; 105 } 106 107 bool GetSkipReferences()108 GetSkipReferences () const 109 { 110 return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences; 111 } 112 113 Flags& 114 SetSkipReferences (bool value = true) 115 { 116 if (value) 117 m_flags |= lldb::eTypeOptionSkipReferences; 118 else 119 m_flags &= ~lldb::eTypeOptionSkipReferences; 120 return *this; 121 } 122 123 bool GetDontShowChildren()124 GetDontShowChildren () const 125 { 126 return (m_flags & lldb::eTypeOptionHideChildren) == lldb::eTypeOptionHideChildren; 127 } 128 129 Flags& 130 SetDontShowChildren (bool value = true) 131 { 132 if (value) 133 m_flags |= lldb::eTypeOptionHideChildren; 134 else 135 m_flags &= ~lldb::eTypeOptionHideChildren; 136 return *this; 137 } 138 139 bool GetDontShowValue()140 GetDontShowValue () const 141 { 142 return (m_flags & lldb::eTypeOptionHideValue) == lldb::eTypeOptionHideValue; 143 } 144 145 Flags& 146 SetDontShowValue (bool value = true) 147 { 148 if (value) 149 m_flags |= lldb::eTypeOptionHideValue; 150 else 151 m_flags &= ~lldb::eTypeOptionHideValue; 152 return *this; 153 } 154 155 bool GetShowMembersOneLiner()156 GetShowMembersOneLiner () const 157 { 158 return (m_flags & lldb::eTypeOptionShowOneLiner) == lldb::eTypeOptionShowOneLiner; 159 } 160 161 Flags& 162 SetShowMembersOneLiner (bool value = true) 163 { 164 if (value) 165 m_flags |= lldb::eTypeOptionShowOneLiner; 166 else 167 m_flags &= ~lldb::eTypeOptionShowOneLiner; 168 return *this; 169 } 170 171 bool GetHideItemNames()172 GetHideItemNames () const 173 { 174 return (m_flags & lldb::eTypeOptionHideNames) == lldb::eTypeOptionHideNames; 175 } 176 177 Flags& 178 SetHideItemNames (bool value = true) 179 { 180 if (value) 181 m_flags |= lldb::eTypeOptionHideNames; 182 else 183 m_flags &= ~lldb::eTypeOptionHideNames; 184 return *this; 185 } 186 187 uint32_t GetValue()188 GetValue () 189 { 190 return m_flags; 191 } 192 193 void SetValue(uint32_t value)194 SetValue (uint32_t value) 195 { 196 m_flags = value; 197 } 198 199 private: 200 uint32_t m_flags; 201 }; 202 203 typedef enum Type 204 { 205 eTypeUnknown, 206 eTypeString, 207 eTypeScript, 208 eTypeCallback 209 } Type; 210 211 TypeSummaryImpl (const TypeSummaryImpl::Flags& flags); 212 213 bool Cascades()214 Cascades () const 215 { 216 return m_flags.GetCascades(); 217 } 218 bool SkipsPointers()219 SkipsPointers () const 220 { 221 return m_flags.GetSkipPointers(); 222 } 223 bool SkipsReferences()224 SkipsReferences () const 225 { 226 return m_flags.GetSkipReferences(); 227 } 228 229 bool DoesPrintChildren()230 DoesPrintChildren () const 231 { 232 return !m_flags.GetDontShowChildren(); 233 } 234 235 bool DoesPrintValue()236 DoesPrintValue () const 237 { 238 return !m_flags.GetDontShowValue(); 239 } 240 241 bool IsOneliner()242 IsOneliner () const 243 { 244 return m_flags.GetShowMembersOneLiner(); 245 } 246 247 bool HideNames()248 HideNames () const 249 { 250 return m_flags.GetHideItemNames(); 251 } 252 253 void SetCascades(bool value)254 SetCascades (bool value) 255 { 256 m_flags.SetCascades(value); 257 } 258 259 void SetSkipsPointers(bool value)260 SetSkipsPointers (bool value) 261 { 262 m_flags.SetSkipPointers(value); 263 } 264 265 void SetSkipsReferences(bool value)266 SetSkipsReferences (bool value) 267 { 268 m_flags.SetSkipReferences(value); 269 } 270 271 void SetDoesPrintChildren(bool value)272 SetDoesPrintChildren (bool value) 273 { 274 m_flags.SetDontShowChildren(!value); 275 } 276 277 void SetDoesPrintValue(bool value)278 SetDoesPrintValue (bool value) 279 { 280 m_flags.SetDontShowValue(!value); 281 } 282 283 void SetIsOneliner(bool value)284 SetIsOneliner (bool value) 285 { 286 m_flags.SetShowMembersOneLiner(value); 287 } 288 289 void SetHideNames(bool value)290 SetHideNames (bool value) 291 { 292 m_flags.SetHideItemNames(value); 293 } 294 295 uint32_t GetOptions()296 GetOptions () 297 { 298 return m_flags.GetValue(); 299 } 300 301 void SetOptions(uint32_t value)302 SetOptions (uint32_t value) 303 { 304 m_flags.SetValue(value); 305 } 306 307 virtual ~TypeSummaryImpl()308 ~TypeSummaryImpl () 309 { 310 } 311 312 // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for 313 // extended periods of time and we trust the ValueObject to stay around for as long as it is required 314 // for us to generate its summary 315 virtual bool 316 FormatObject (ValueObject *valobj, 317 std::string& dest) = 0; 318 319 virtual std::string 320 GetDescription () = 0; 321 322 virtual bool 323 IsScripted () = 0; 324 325 virtual Type 326 GetType () = 0; 327 328 uint32_t& GetRevision()329 GetRevision () 330 { 331 return m_my_revision; 332 } 333 334 typedef std::shared_ptr<TypeSummaryImpl> SharedPointer; 335 typedef bool(*SummaryCallback)(void*, ConstString, const lldb::TypeSummaryImplSP&); 336 typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const lldb::TypeSummaryImplSP&); 337 338 protected: 339 uint32_t m_my_revision; 340 Flags m_flags; 341 342 private: 343 DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl); 344 }; 345 346 // simple string-based summaries, using ${var to show data 347 struct StringSummaryFormat : public TypeSummaryImpl 348 { 349 std::string m_format; 350 351 StringSummaryFormat(const TypeSummaryImpl::Flags& flags, 352 const char* f); 353 354 const char* GetSummaryStringStringSummaryFormat355 GetSummaryString () const 356 { 357 return m_format.c_str(); 358 } 359 360 void SetSummaryStringStringSummaryFormat361 SetSummaryString (const char* data) 362 { 363 if (data) 364 m_format.assign(data); 365 else 366 m_format.clear(); 367 } 368 369 virtual ~StringSummaryFormatStringSummaryFormat370 ~StringSummaryFormat() 371 { 372 } 373 374 virtual bool 375 FormatObject(ValueObject *valobj, 376 std::string& dest); 377 378 virtual std::string 379 GetDescription(); 380 381 virtual bool IsScriptedStringSummaryFormat382 IsScripted () 383 { 384 return false; 385 } 386 387 388 virtual Type GetTypeStringSummaryFormat389 GetType () 390 { 391 return TypeSummaryImpl::eTypeString; 392 } 393 394 private: 395 DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat); 396 }; 397 398 // summaries implemented via a C++ function 399 struct CXXFunctionSummaryFormat : public TypeSummaryImpl 400 { 401 402 // we should convert these to SBValue and SBStream if we ever cross 403 // the boundary towards the external world 404 typedef bool (*Callback)(ValueObject& valobj, Stream& dest); 405 406 Callback m_impl; 407 std::string m_description; 408 409 CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags, 410 Callback impl, 411 const char* description); 412 413 Callback GetBackendFunctionCXXFunctionSummaryFormat414 GetBackendFunction () const 415 { 416 return m_impl; 417 } 418 419 const char* GetTextualInfoCXXFunctionSummaryFormat420 GetTextualInfo () const 421 { 422 return m_description.c_str(); 423 } 424 425 void SetBackendFunctionCXXFunctionSummaryFormat426 SetBackendFunction (Callback cb_func) 427 { 428 m_impl = cb_func; 429 } 430 431 void SetTextualInfoCXXFunctionSummaryFormat432 SetTextualInfo (const char* descr) 433 { 434 if (descr) 435 m_description.assign(descr); 436 else 437 m_description.clear(); 438 } 439 440 virtual ~CXXFunctionSummaryFormatCXXFunctionSummaryFormat441 ~CXXFunctionSummaryFormat () 442 { 443 } 444 445 virtual bool 446 FormatObject (ValueObject *valobj, 447 std::string& dest); 448 449 virtual std::string 450 GetDescription (); 451 452 virtual bool IsScriptedCXXFunctionSummaryFormat453 IsScripted () 454 { 455 return false; 456 } 457 458 virtual Type GetTypeCXXFunctionSummaryFormat459 GetType () 460 { 461 return TypeSummaryImpl::eTypeCallback; 462 } 463 464 typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer; 465 466 private: 467 DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat); 468 }; 469 470 #ifndef LLDB_DISABLE_PYTHON 471 472 // Python-based summaries, running script code to show data 473 struct ScriptSummaryFormat : public TypeSummaryImpl 474 { 475 std::string m_function_name; 476 std::string m_python_script; 477 lldb::ScriptInterpreterObjectSP m_script_function_sp; 478 479 ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags, 480 const char *function_name, 481 const char* python_script = NULL); 482 483 const char* GetFunctionNameScriptSummaryFormat484 GetFunctionName () const 485 { 486 return m_function_name.c_str(); 487 } 488 489 const char* GetPythonScriptScriptSummaryFormat490 GetPythonScript () const 491 { 492 return m_python_script.c_str(); 493 } 494 495 void SetFunctionNameScriptSummaryFormat496 SetFunctionName (const char* function_name) 497 { 498 if (function_name) 499 m_function_name.assign(function_name); 500 else 501 m_function_name.clear(); 502 m_python_script.clear(); 503 } 504 505 void SetPythonScriptScriptSummaryFormat506 SetPythonScript (const char* script) 507 { 508 if (script) 509 m_python_script.assign(script); 510 else 511 m_python_script.clear(); 512 } 513 514 virtual ~ScriptSummaryFormatScriptSummaryFormat515 ~ScriptSummaryFormat () 516 { 517 } 518 519 virtual bool 520 FormatObject (ValueObject *valobj, 521 std::string& dest); 522 523 virtual std::string 524 GetDescription (); 525 526 virtual bool IsScriptedScriptSummaryFormat527 IsScripted () 528 { 529 return true; 530 } 531 532 virtual Type GetTypeScriptSummaryFormat533 GetType () 534 { 535 return TypeSummaryImpl::eTypeScript; 536 } 537 538 typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer; 539 540 541 private: 542 DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat); 543 }; 544 #endif 545 } // namespace lldb_private 546 547 #endif // lldb_TypeSummary_h_ 548