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, const char* description) 151 { 152 SBTypeSummary retval; 153 if (cb) 154 { 155 retval.SetSP(TypeSummaryImplSP(new CXXFunctionSummaryFormat(options, 156 [cb] (ValueObject& valobj, Stream& stm, const TypeSummaryOptions& opt) -> bool { 157 SBStream stream; 158 SBValue sb_value(valobj.GetSP()); 159 SBTypeSummaryOptions options(&opt); 160 if (!cb(sb_value, options, stream)) 161 return false; 162 stm.Write(stream.GetData(), stream.GetSize()); 163 return true; 164 }, 165 description ? description : "callback summary formatter"))); 166 } 167 168 return retval; 169 } 170 171 SBTypeSummary::SBTypeSummary (const lldb::SBTypeSummary &rhs) : 172 m_opaque_sp(rhs.m_opaque_sp) 173 { 174 } 175 176 SBTypeSummary::~SBTypeSummary () 177 { 178 } 179 180 bool 181 SBTypeSummary::IsValid() const 182 { 183 return m_opaque_sp.get() != NULL; 184 } 185 186 bool 187 SBTypeSummary::IsFunctionCode() 188 { 189 if (!IsValid()) 190 return false; 191 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 192 { 193 const char* ftext = script_summary_ptr->GetPythonScript(); 194 return (ftext && *ftext != 0); 195 } 196 return false; 197 } 198 199 bool 200 SBTypeSummary::IsFunctionName() 201 { 202 if (!IsValid()) 203 return false; 204 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 205 { 206 const char* ftext = script_summary_ptr->GetPythonScript(); 207 return (!ftext || *ftext == 0); 208 } 209 return false; 210 } 211 212 bool 213 SBTypeSummary::IsSummaryString() 214 { 215 if (!IsValid()) 216 return false; 217 218 return m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eSummaryString; 219 } 220 221 const char* 222 SBTypeSummary::GetData () 223 { 224 if (!IsValid()) 225 return NULL; 226 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 227 { 228 const char* fname = script_summary_ptr->GetFunctionName(); 229 const char* ftext = script_summary_ptr->GetPythonScript(); 230 if (ftext && *ftext) 231 return ftext; 232 return fname; 233 } 234 else if (StringSummaryFormat* string_summary_ptr = llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) 235 return string_summary_ptr->GetSummaryString(); 236 return nullptr; 237 } 238 239 uint32_t 240 SBTypeSummary::GetOptions () 241 { 242 if (!IsValid()) 243 return lldb::eTypeOptionNone; 244 return m_opaque_sp->GetOptions(); 245 } 246 247 void 248 SBTypeSummary::SetOptions (uint32_t value) 249 { 250 if (!CopyOnWrite_Impl()) 251 return; 252 m_opaque_sp->SetOptions(value); 253 } 254 255 void 256 SBTypeSummary::SetSummaryString (const char* data) 257 { 258 if (!IsValid()) 259 return; 260 if (!llvm::isa<StringSummaryFormat>(m_opaque_sp.get())) 261 ChangeSummaryType(false); 262 if (StringSummaryFormat* string_summary_ptr = llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) 263 string_summary_ptr->SetSummaryString(data); 264 } 265 266 void 267 SBTypeSummary::SetFunctionName (const char* data) 268 { 269 if (!IsValid()) 270 return; 271 if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get())) 272 ChangeSummaryType(true); 273 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 274 script_summary_ptr->SetFunctionName(data); 275 } 276 277 void 278 SBTypeSummary::SetFunctionCode (const char* data) 279 { 280 if (!IsValid()) 281 return; 282 if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get())) 283 ChangeSummaryType(true); 284 if (ScriptSummaryFormat* script_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 285 script_summary_ptr->SetPythonScript(data); 286 } 287 288 bool 289 SBTypeSummary::GetDescription (lldb::SBStream &description, 290 lldb::DescriptionLevel description_level) 291 { 292 if (!CopyOnWrite_Impl()) 293 return false; 294 else { 295 description.Printf("%s\n", 296 m_opaque_sp->GetDescription().c_str()); 297 return true; 298 } 299 } 300 301 bool 302 SBTypeSummary::DoesPrintValue (lldb::SBValue value) 303 { 304 if (!IsValid()) 305 return false; 306 lldb::ValueObjectSP value_sp = value.GetSP(); 307 return m_opaque_sp->DoesPrintValue(value_sp.get()); 308 } 309 310 lldb::SBTypeSummary & 311 SBTypeSummary::operator = (const lldb::SBTypeSummary &rhs) 312 { 313 if (this != &rhs) 314 { 315 m_opaque_sp = rhs.m_opaque_sp; 316 } 317 return *this; 318 } 319 320 bool 321 SBTypeSummary::operator == (lldb::SBTypeSummary &rhs) 322 { 323 if (IsValid() == false) 324 return !rhs.IsValid(); 325 return m_opaque_sp == rhs.m_opaque_sp; 326 } 327 328 bool 329 SBTypeSummary::IsEqualTo (lldb::SBTypeSummary &rhs) 330 { 331 if (IsValid() == false) 332 return !rhs.IsValid(); 333 334 if (m_opaque_sp->GetKind() != rhs.m_opaque_sp->GetKind()) 335 return false; 336 337 switch (m_opaque_sp->GetKind()) 338 { 339 case TypeSummaryImpl::Kind::eCallback: 340 return llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get()) == llvm::dyn_cast<CXXFunctionSummaryFormat>(rhs.m_opaque_sp.get()); 341 case TypeSummaryImpl::Kind::eScript: 342 if (IsFunctionCode() != rhs.IsFunctionCode()) 343 return false; 344 if (IsFunctionName() != rhs.IsFunctionName()) 345 return false; 346 return GetOptions() == rhs.GetOptions(); 347 case TypeSummaryImpl::Kind::eSummaryString: 348 if (IsSummaryString() != rhs.IsSummaryString()) 349 return false; 350 return GetOptions() == rhs.GetOptions(); 351 } 352 353 return false; 354 } 355 356 bool 357 SBTypeSummary::operator != (lldb::SBTypeSummary &rhs) 358 { 359 if (IsValid() == false) 360 return !rhs.IsValid(); 361 return m_opaque_sp != rhs.m_opaque_sp; 362 } 363 364 lldb::TypeSummaryImplSP 365 SBTypeSummary::GetSP () 366 { 367 return m_opaque_sp; 368 } 369 370 void 371 SBTypeSummary::SetSP (const lldb::TypeSummaryImplSP &typesummary_impl_sp) 372 { 373 m_opaque_sp = typesummary_impl_sp; 374 } 375 376 SBTypeSummary::SBTypeSummary (const lldb::TypeSummaryImplSP &typesummary_impl_sp) : 377 m_opaque_sp(typesummary_impl_sp) 378 { 379 } 380 381 bool 382 SBTypeSummary::CopyOnWrite_Impl() 383 { 384 if (!IsValid()) 385 return false; 386 387 if (m_opaque_sp.unique()) 388 return true; 389 390 TypeSummaryImplSP new_sp; 391 392 if (CXXFunctionSummaryFormat* current_summary_ptr = llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get())) 393 { 394 new_sp = TypeSummaryImplSP(new CXXFunctionSummaryFormat(GetOptions(), 395 current_summary_ptr->m_impl, 396 current_summary_ptr->m_description.c_str())); 397 } 398 else if (ScriptSummaryFormat* current_summary_ptr = llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) 399 { 400 new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), 401 current_summary_ptr->GetFunctionName(), 402 current_summary_ptr->GetPythonScript())); 403 } 404 else if (StringSummaryFormat* current_summary_ptr = llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) 405 { 406 new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), 407 current_summary_ptr->GetSummaryString())); 408 } 409 410 SetSP(new_sp); 411 412 return nullptr != new_sp.get(); 413 } 414 415 bool 416 SBTypeSummary::ChangeSummaryType (bool want_script) 417 { 418 if (!IsValid()) 419 return false; 420 421 TypeSummaryImplSP new_sp; 422 423 if (want_script == (m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eScript)) 424 { 425 if (m_opaque_sp->GetKind() == lldb_private::TypeSummaryImpl::Kind::eCallback && !want_script) 426 new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), "")); 427 else 428 return CopyOnWrite_Impl(); 429 } 430 431 if (!new_sp) 432 { 433 if (want_script) 434 new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), "", "")); 435 else 436 new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), "")); 437 } 438 439 SetSP(new_sp); 440 441 return true; 442 } 443