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