1 //===-- SBTypeSummary.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/API/SBTypeSummary.h" 11 #include "lldb/API/SBStream.h" 12 #include "lldb/API/SBValue.h" 13 #include "lldb/DataFormatters/DataVisualization.h" 14 15 #include "llvm/Support/Casting.h" 16 17 using namespace lldb; 18 using namespace lldb_private; 19 20 SBTypeSummaryOptions::SBTypeSummaryOptions() 21 { 22 m_opaque_ap.reset(new TypeSummaryOptions()); 23 } 24 25 SBTypeSummaryOptions::SBTypeSummaryOptions (const lldb::SBTypeSummaryOptions &rhs) 26 { 27 if (rhs.m_opaque_ap) 28 m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap.get())); 29 else 30 m_opaque_ap.reset(new TypeSummaryOptions()); 31 } 32 33 SBTypeSummaryOptions::~SBTypeSummaryOptions () 34 { 35 } 36 37 bool 38 SBTypeSummaryOptions::IsValid() 39 { 40 return m_opaque_ap.get(); 41 } 42 43 lldb::LanguageType 44 SBTypeSummaryOptions::GetLanguage () 45 { 46 if (IsValid()) 47 return m_opaque_ap->GetLanguage(); 48 return lldb::eLanguageTypeUnknown; 49 } 50 51 lldb::TypeSummaryCapping 52 SBTypeSummaryOptions::GetCapping () 53 { 54 if (IsValid()) 55 return m_opaque_ap->GetCapping(); 56 return eTypeSummaryCapped; 57 } 58 59 void 60 SBTypeSummaryOptions::SetLanguage (lldb::LanguageType l) 61 { 62 if (IsValid()) 63 m_opaque_ap->SetLanguage(l); 64 } 65 66 void 67 SBTypeSummaryOptions::SetCapping (lldb::TypeSummaryCapping c) 68 { 69 if (IsValid()) 70 m_opaque_ap->SetCapping(c); 71 } 72 73 lldb_private::TypeSummaryOptions * 74 SBTypeSummaryOptions::operator->() 75 { 76 return m_opaque_ap.get(); 77 } 78 79 const lldb_private::TypeSummaryOptions * 80 SBTypeSummaryOptions::operator->() const 81 { 82 return m_opaque_ap.get(); 83 } 84 85 lldb_private::TypeSummaryOptions * 86 SBTypeSummaryOptions::get () 87 { 88 return m_opaque_ap.get(); 89 } 90 91 lldb_private::TypeSummaryOptions & 92 SBTypeSummaryOptions::ref() 93 { 94 return *m_opaque_ap.get(); 95 } 96 97 const lldb_private::TypeSummaryOptions & 98 SBTypeSummaryOptions::ref() const 99 { 100 return *m_opaque_ap.get(); 101 } 102 103 SBTypeSummaryOptions::SBTypeSummaryOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr) 104 { 105 SetOptions(lldb_object_ptr); 106 } 107 108 void 109 SBTypeSummaryOptions::SetOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr) 110 { 111 if (lldb_object_ptr) 112 m_opaque_ap.reset(new TypeSummaryOptions(*lldb_object_ptr)); 113 else 114 m_opaque_ap.reset(new TypeSummaryOptions()); 115 } 116 117 SBTypeSummary::SBTypeSummary() : 118 m_opaque_sp() 119 { 120 } 121 122 SBTypeSummary 123 SBTypeSummary::CreateWithSummaryString (const char* data, uint32_t options) 124 { 125 if (!data || data[0] == 0) 126 return SBTypeSummary(); 127 128 return SBTypeSummary(TypeSummaryImplSP(new StringSummaryFormat(options, data))); 129 } 130 131 SBTypeSummary 132 SBTypeSummary::CreateWithFunctionName (const char* data, uint32_t options) 133 { 134 if (!data || data[0] == 0) 135 return SBTypeSummary(); 136 137 return SBTypeSummary(TypeSummaryImplSP(new ScriptSummaryFormat(options, data))); 138 } 139 140 SBTypeSummary 141 SBTypeSummary::CreateWithScriptCode (const char* data, uint32_t options) 142 { 143 if (!data || data[0] == 0) 144 return SBTypeSummary(); 145 146 return SBTypeSummary(TypeSummaryImplSP(new ScriptSummaryFormat(options, "", data))); 147 } 148 149 SBTypeSummary 150 SBTypeSummary::CreateWithCallback (FormatCallback cb, uint32_t options) 151 { 152 return SBTypeSummary( 153 TypeSummaryImplSP( 154 cb ? new CXXFunctionSummaryFormat(options, 155 [cb] (ValueObject& valobj, Stream& stm, const TypeSummaryOptions& opt) -> bool { 156 BStream stream; 157 if (!cb(SBValue(valobj.GetSP()), SBTypeSummaryOptions(&opt), stream)) 158 return false; 159 stm.Write(stream.GetData(), stream.GetSize()); 160 return true; 161 }, 162 "SBTypeSummary formatter callback" 163 ) : nullptr 164 ) 165 ); 166 } 167 168 SBTypeSummary::SBTypeSummary (const lldb::SBTypeSummary &rhs) : 169 m_opaque_sp(rhs.m_opaque_sp) 170 { 171 } 172 173 SBTypeSummary::~SBTypeSummary () 174 { 175 } 176 177 bool 178 SBTypeSummary::IsValid() const 179 { 180 return m_opaque_sp.get() != NULL; 181 } 182 183 bool 184 SBTypeSummary::IsFunctionCode() 185 { 186 if (!IsValid()) 187 return false; 188 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 189 { 190 const char* ftext = script_summary_ptr->GetPythonScript(); 191 return (ftext && *ftext != 0); 192 } 193 return false; 194 } 195 196 bool 197 SBTypeSummary::IsFunctionName() 198 { 199 if (!IsValid()) 200 return false; 201 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 202 { 203 const char* ftext = script_summary_ptr->GetPythonScript(); 204 return (!ftext || *ftext == 0); 205 } 206 return false; 207 } 208 209 bool 210 SBTypeSummary::IsSummaryString() 211 { 212 if (!IsValid()) 213 return false; 214 215 return m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eSummaryString; 216 } 217 218 const char* 219 SBTypeSummary::GetData () 220 { 221 if (!IsValid()) 222 return NULL; 223 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 224 { 225 const char* fname = script_summary_ptr->GetFunctionName(); 226 const char* ftext = script_summary_ptr->GetPythonScript(); 227 if (ftext && *ftext) 228 return ftext; 229 return fname; 230 } 231 else if (StringSummaryFormat* string_summary_ptr = llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) 232 return string_summary_ptr->GetSummaryString(); 233 return nullptr; 234 } 235 236 uint32_t 237 SBTypeSummary::GetOptions () 238 { 239 if (!IsValid()) 240 return lldb::eTypeOptionNone; 241 return m_opaque_sp->GetOptions(); 242 } 243 244 void 245 SBTypeSummary::SetOptions (uint32_t value) 246 { 247 if (!CopyOnWrite_Impl()) 248 return; 249 m_opaque_sp->SetOptions(value); 250 } 251 252 void 253 SBTypeSummary::SetSummaryString (const char* data) 254 { 255 if (!IsValid()) 256 return; 257 if (!llvm::isa<StringSummaryFormat>(m_opaque_sp.get())) 258 ChangeSummaryType(false); 259 if (StringSummaryFormat* string_summary_ptr = llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) 260 string_summary_ptr->SetSummaryString(data); 261 } 262 263 void 264 SBTypeSummary::SetFunctionName (const char* data) 265 { 266 if (!IsValid()) 267 return; 268 if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get())) 269 ChangeSummaryType(true); 270 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 271 script_summary_ptr->SetFunctionName(data); 272 } 273 274 void 275 SBTypeSummary::SetFunctionCode (const char* data) 276 { 277 if (!IsValid()) 278 return; 279 if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get())) 280 ChangeSummaryType(true); 281 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 282 script_summary_ptr->SetPythonScript(data); 283 } 284 285 bool 286 SBTypeSummary::GetDescription (lldb::SBStream &description, 287 lldb::DescriptionLevel description_level) 288 { 289 if (!CopyOnWrite_Impl()) 290 return false; 291 else { 292 description.Printf("%s\n", 293 m_opaque_sp->GetDescription().c_str()); 294 return true; 295 } 296 } 297 298 bool 299 SBTypeSummary::DoesPrintValue (lldb::SBValue value) 300 { 301 if (!IsValid()) 302 return false; 303 lldb::ValueObjectSP value_sp = value.GetSP(); 304 return m_opaque_sp->DoesPrintValue(value_sp.get()); 305 } 306 307 lldb::SBTypeSummary & 308 SBTypeSummary::operator = (const lldb::SBTypeSummary &rhs) 309 { 310 if (this != &rhs) 311 { 312 m_opaque_sp = rhs.m_opaque_sp; 313 } 314 return *this; 315 } 316 317 bool 318 SBTypeSummary::operator == (lldb::SBTypeSummary &rhs) 319 { 320 if (IsValid() == false) 321 return !rhs.IsValid(); 322 return m_opaque_sp == rhs.m_opaque_sp; 323 } 324 325 bool 326 SBTypeSummary::IsEqualTo (lldb::SBTypeSummary &rhs) 327 { 328 if (IsValid() == false) 329 return !rhs.IsValid(); 330 331 if (m_opaque_sp->GetKind() != rhs.m_opaque_sp->GetKind()) 332 return false; 333 334 switch (m_opaque_sp->GetKind()) 335 { 336 case TypeSummaryImpl::Kind::eCallback: 337 return llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get()) == llvm::dyn_cast<CXXFunctionSummaryFormat>(rhs.m_opaque_sp.get()); 338 case TypeSummaryImpl::Kind::eScript: 339 if (IsFunctionCode() != rhs.IsFunctionCode()) 340 return false; 341 if (IsFunctionName() != rhs.IsFunctionName()) 342 return false; 343 return GetOptions() == rhs.GetOptions(); 344 case TypeSummaryImpl::Kind::eSummaryString: 345 if (IsSummaryString() != rhs.IsSummaryString()) 346 return false; 347 return GetOptions() == rhs.GetOptions(); 348 } 349 350 return false; 351 } 352 353 bool 354 SBTypeSummary::operator != (lldb::SBTypeSummary &rhs) 355 { 356 if (IsValid() == false) 357 return !rhs.IsValid(); 358 return m_opaque_sp != rhs.m_opaque_sp; 359 } 360 361 lldb::TypeSummaryImplSP 362 SBTypeSummary::GetSP () 363 { 364 return m_opaque_sp; 365 } 366 367 void 368 SBTypeSummary::SetSP (const lldb::TypeSummaryImplSP &typesummary_impl_sp) 369 { 370 m_opaque_sp = typesummary_impl_sp; 371 } 372 373 SBTypeSummary::SBTypeSummary (const lldb::TypeSummaryImplSP &typesummary_impl_sp) : 374 m_opaque_sp(typesummary_impl_sp) 375 { 376 } 377 378 bool 379 SBTypeSummary::CopyOnWrite_Impl() 380 { 381 if (!IsValid()) 382 return false; 383 384 if (m_opaque_sp.unique()) 385 return true; 386 387 TypeSummaryImplSP new_sp; 388 389 if (CXXFunctionSummaryFormat* current_summary_ptr = llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get())) 390 { 391 new_sp = TypeSummaryImplSP(new CXXFunctionSummaryFormat(GetOptions(), 392 current_summary_ptr->m_impl, 393 current_summary_ptr->m_description.c_str())); 394 } 395 else if (ScriptSummaryFormat* current_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 396 { 397 new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), 398 current_summary_ptr->GetFunctionName(), 399 current_summary_ptr->GetPythonScript())); 400 } 401 else if (StringSummaryFormat* current_summary_ptr = llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) 402 { 403 new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), 404 current_summary_ptr->GetSummaryString())); 405 } 406 407 SetSP(new_sp); 408 409 return nullptr != new_sp.get(); 410 } 411 412 bool 413 SBTypeSummary::ChangeSummaryType (bool want_script) 414 { 415 if (!IsValid()) 416 return false; 417 418 TypeSummaryImplSP new_sp; 419 420 if (want_script == (m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eScript)) 421 { 422 if (m_opaque_sp->GetKind() == lldb_private::TypeSummaryImpl::Kind::eCallback && !want_script) 423 new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), "")); 424 else 425 return CopyOnWrite_Impl(); 426 } 427 428 if (!new_sp) 429 { 430 if (want_script) 431 new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), "", "")); 432 else 433 new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), "")); 434 } 435 436 SetSP(new_sp); 437 438 return true; 439 } 440