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