File indexing completed on 2026-05-10 08:42:47
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_DATAFORMATTERS_TYPESUMMARY_H
0010 #define LLDB_DATAFORMATTERS_TYPESUMMARY_H
0011
0012 #include <cstdint>
0013
0014 #include <functional>
0015 #include <memory>
0016 #include <string>
0017
0018 #include "lldb/lldb-enumerations.h"
0019 #include "lldb/lldb-public.h"
0020
0021 #include "lldb/Core/FormatEntity.h"
0022 #include "lldb/Utility/Status.h"
0023 #include "lldb/Utility/StructuredData.h"
0024
0025 namespace llvm {
0026 class MemoryBuffer;
0027 }
0028
0029 namespace lldb_private {
0030 class TypeSummaryOptions {
0031 public:
0032 TypeSummaryOptions();
0033
0034 ~TypeSummaryOptions() = default;
0035
0036 lldb::LanguageType GetLanguage() const;
0037
0038 lldb::TypeSummaryCapping GetCapping() const;
0039
0040 TypeSummaryOptions &SetLanguage(lldb::LanguageType);
0041
0042 TypeSummaryOptions &SetCapping(lldb::TypeSummaryCapping);
0043
0044 private:
0045 lldb::LanguageType m_lang = lldb::eLanguageTypeUnknown;
0046 lldb::TypeSummaryCapping m_capping = lldb::eTypeSummaryCapped;
0047 };
0048
0049 class TypeSummaryImpl {
0050 public:
0051 enum class Kind { eSummaryString, eScript, eBytecode, eCallback, eInternal };
0052
0053 virtual ~TypeSummaryImpl() = default;
0054
0055 Kind GetKind() const { return m_kind; }
0056
0057 class Flags {
0058 public:
0059 Flags() = default;
0060
0061 Flags(const Flags &other) : m_flags(other.m_flags) {}
0062
0063 Flags(uint32_t value) : m_flags(value) {}
0064
0065 Flags &operator=(const Flags &rhs) {
0066 if (&rhs != this)
0067 m_flags = rhs.m_flags;
0068
0069 return *this;
0070 }
0071
0072 Flags &operator=(const uint32_t &rhs) {
0073 m_flags = rhs;
0074 return *this;
0075 }
0076
0077 Flags &Clear() {
0078 m_flags = 0;
0079 return *this;
0080 }
0081
0082 bool GetCascades() const {
0083 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
0084 }
0085
0086 Flags &SetCascades(bool value = true) {
0087 if (value)
0088 m_flags |= lldb::eTypeOptionCascade;
0089 else
0090 m_flags &= ~lldb::eTypeOptionCascade;
0091 return *this;
0092 }
0093
0094 bool GetSkipPointers() const {
0095 return (m_flags & lldb::eTypeOptionSkipPointers) ==
0096 lldb::eTypeOptionSkipPointers;
0097 }
0098
0099 Flags &SetSkipPointers(bool value = true) {
0100 if (value)
0101 m_flags |= lldb::eTypeOptionSkipPointers;
0102 else
0103 m_flags &= ~lldb::eTypeOptionSkipPointers;
0104 return *this;
0105 }
0106
0107 bool GetSkipReferences() const {
0108 return (m_flags & lldb::eTypeOptionSkipReferences) ==
0109 lldb::eTypeOptionSkipReferences;
0110 }
0111
0112 Flags &SetSkipReferences(bool value = true) {
0113 if (value)
0114 m_flags |= lldb::eTypeOptionSkipReferences;
0115 else
0116 m_flags &= ~lldb::eTypeOptionSkipReferences;
0117 return *this;
0118 }
0119
0120 bool GetDontShowChildren() const {
0121 return (m_flags & lldb::eTypeOptionHideChildren) ==
0122 lldb::eTypeOptionHideChildren;
0123 }
0124
0125 Flags &SetDontShowChildren(bool value = true) {
0126 if (value)
0127 m_flags |= lldb::eTypeOptionHideChildren;
0128 else
0129 m_flags &= ~lldb::eTypeOptionHideChildren;
0130 return *this;
0131 }
0132
0133 bool GetHideEmptyAggregates() const {
0134 return (m_flags & lldb::eTypeOptionHideEmptyAggregates) ==
0135 lldb::eTypeOptionHideEmptyAggregates;
0136 }
0137
0138 Flags &SetHideEmptyAggregates(bool value = true) {
0139 if (value)
0140 m_flags |= lldb::eTypeOptionHideEmptyAggregates;
0141 else
0142 m_flags &= ~lldb::eTypeOptionHideEmptyAggregates;
0143 return *this;
0144 }
0145
0146 bool GetDontShowValue() const {
0147 return (m_flags & lldb::eTypeOptionHideValue) ==
0148 lldb::eTypeOptionHideValue;
0149 }
0150
0151 Flags &SetDontShowValue(bool value = true) {
0152 if (value)
0153 m_flags |= lldb::eTypeOptionHideValue;
0154 else
0155 m_flags &= ~lldb::eTypeOptionHideValue;
0156 return *this;
0157 }
0158
0159 bool GetShowMembersOneLiner() const {
0160 return (m_flags & lldb::eTypeOptionShowOneLiner) ==
0161 lldb::eTypeOptionShowOneLiner;
0162 }
0163
0164 Flags &SetShowMembersOneLiner(bool value = true) {
0165 if (value)
0166 m_flags |= lldb::eTypeOptionShowOneLiner;
0167 else
0168 m_flags &= ~lldb::eTypeOptionShowOneLiner;
0169 return *this;
0170 }
0171
0172 bool GetHideItemNames() const {
0173 return (m_flags & lldb::eTypeOptionHideNames) ==
0174 lldb::eTypeOptionHideNames;
0175 }
0176
0177 Flags &SetHideItemNames(bool value = true) {
0178 if (value)
0179 m_flags |= lldb::eTypeOptionHideNames;
0180 else
0181 m_flags &= ~lldb::eTypeOptionHideNames;
0182 return *this;
0183 }
0184
0185 bool GetNonCacheable() const {
0186 return (m_flags & lldb::eTypeOptionNonCacheable) ==
0187 lldb::eTypeOptionNonCacheable;
0188 }
0189
0190 Flags &SetNonCacheable(bool value = true) {
0191 if (value)
0192 m_flags |= lldb::eTypeOptionNonCacheable;
0193 else
0194 m_flags &= ~lldb::eTypeOptionNonCacheable;
0195 return *this;
0196 }
0197
0198 uint32_t GetValue() { return m_flags; }
0199
0200 void SetValue(uint32_t value) { m_flags = value; }
0201
0202 private:
0203 uint32_t m_flags = lldb::eTypeOptionCascade;
0204 };
0205
0206 bool Cascades() const { return m_flags.GetCascades(); }
0207
0208 bool SkipsPointers() const { return m_flags.GetSkipPointers(); }
0209
0210 bool SkipsReferences() const { return m_flags.GetSkipReferences(); }
0211
0212 bool NonCacheable() const { return m_flags.GetNonCacheable(); }
0213
0214 virtual bool DoesPrintChildren(ValueObject *valobj) const {
0215 return !m_flags.GetDontShowChildren();
0216 }
0217
0218 virtual bool DoesPrintEmptyAggregates() const {
0219 return !m_flags.GetHideEmptyAggregates();
0220 }
0221
0222 virtual bool DoesPrintValue(ValueObject *valobj) const {
0223 return !m_flags.GetDontShowValue();
0224 }
0225
0226 bool IsOneLiner() const { return m_flags.GetShowMembersOneLiner(); }
0227
0228 virtual bool HideNames(ValueObject *valobj) const {
0229 return m_flags.GetHideItemNames();
0230 }
0231
0232 void SetCascades(bool value) { m_flags.SetCascades(value); }
0233
0234 void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }
0235
0236 void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }
0237
0238 virtual void SetDoesPrintChildren(bool value) {
0239 m_flags.SetDontShowChildren(!value);
0240 }
0241
0242 virtual void SetDoesPrintValue(bool value) {
0243 m_flags.SetDontShowValue(!value);
0244 }
0245
0246 void SetIsOneLiner(bool value) { m_flags.SetShowMembersOneLiner(value); }
0247
0248 virtual void SetHideNames(bool value) { m_flags.SetHideItemNames(value); }
0249
0250 virtual void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }
0251
0252 uint32_t GetOptions() { return m_flags.GetValue(); }
0253
0254 void SetOptions(uint32_t value) { m_flags.SetValue(value); }
0255
0256
0257
0258
0259
0260 virtual bool FormatObject(ValueObject *valobj, std::string &dest,
0261 const TypeSummaryOptions &options) = 0;
0262
0263 virtual std::string GetDescription() = 0;
0264
0265
0266
0267 virtual std::string GetName() = 0;
0268
0269
0270
0271 virtual std::string GetSummaryKindName();
0272
0273 uint32_t &GetRevision() { return m_my_revision; }
0274
0275 typedef std::shared_ptr<TypeSummaryImpl> SharedPointer;
0276
0277 protected:
0278 uint32_t m_my_revision = 0;
0279 Flags m_flags;
0280
0281 TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags);
0282
0283 private:
0284 Kind m_kind;
0285 TypeSummaryImpl(const TypeSummaryImpl &) = delete;
0286 const TypeSummaryImpl &operator=(const TypeSummaryImpl &) = delete;
0287 };
0288
0289
0290 struct StringSummaryFormat : public TypeSummaryImpl {
0291 std::string m_format_str;
0292 FormatEntity::Entry m_format;
0293 Status m_error;
0294
0295 StringSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *f);
0296
0297 ~StringSummaryFormat() override = default;
0298
0299 const char *GetSummaryString() const { return m_format_str.c_str(); }
0300
0301 void SetSummaryString(const char *f);
0302
0303 bool FormatObject(ValueObject *valobj, std::string &dest,
0304 const TypeSummaryOptions &options) override;
0305
0306 std::string GetDescription() override;
0307
0308 std::string GetName() override;
0309
0310 static bool classof(const TypeSummaryImpl *S) {
0311 return S->GetKind() == Kind::eSummaryString;
0312 }
0313
0314 private:
0315 StringSummaryFormat(const StringSummaryFormat &) = delete;
0316 const StringSummaryFormat &operator=(const StringSummaryFormat &) = delete;
0317 };
0318
0319
0320 struct CXXFunctionSummaryFormat : public TypeSummaryImpl {
0321
0322
0323 typedef std::function<bool(ValueObject &, Stream &,
0324 const TypeSummaryOptions &)>
0325 Callback;
0326
0327 Callback m_impl;
0328 std::string m_description;
0329
0330 CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags &flags, Callback impl,
0331 const char *description);
0332
0333 ~CXXFunctionSummaryFormat() override = default;
0334
0335 Callback GetBackendFunction() const { return m_impl; }
0336
0337 const char *GetTextualInfo() const { return m_description.c_str(); }
0338
0339 void SetBackendFunction(Callback cb_func) { m_impl = std::move(cb_func); }
0340
0341 void SetTextualInfo(const char *descr) {
0342 if (descr)
0343 m_description.assign(descr);
0344 else
0345 m_description.clear();
0346 }
0347
0348 bool FormatObject(ValueObject *valobj, std::string &dest,
0349 const TypeSummaryOptions &options) override;
0350
0351 std::string GetDescription() override;
0352
0353 static bool classof(const TypeSummaryImpl *S) {
0354 return S->GetKind() == Kind::eCallback;
0355 }
0356
0357 std::string GetName() override;
0358
0359 typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer;
0360
0361 private:
0362 CXXFunctionSummaryFormat(const CXXFunctionSummaryFormat &) = delete;
0363 const CXXFunctionSummaryFormat &
0364 operator=(const CXXFunctionSummaryFormat &) = delete;
0365 };
0366
0367
0368 struct ScriptSummaryFormat : public TypeSummaryImpl {
0369 std::string m_function_name;
0370 std::string m_python_script;
0371 std::string m_script_formatter_name;
0372 StructuredData::ObjectSP m_script_function_sp;
0373
0374 ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags,
0375 const char *function_name,
0376 const char *python_script = nullptr);
0377
0378 ~ScriptSummaryFormat() override = default;
0379
0380 const char *GetFunctionName() const { return m_function_name.c_str(); }
0381
0382 const char *GetPythonScript() const { return m_python_script.c_str(); }
0383
0384 void SetFunctionName(const char *function_name) {
0385 if (function_name)
0386 m_function_name.assign(function_name);
0387 else
0388 m_function_name.clear();
0389 m_python_script.clear();
0390 }
0391
0392 void SetPythonScript(const char *script) {
0393 if (script)
0394 m_python_script.assign(script);
0395 else
0396 m_python_script.clear();
0397 }
0398
0399 bool FormatObject(ValueObject *valobj, std::string &dest,
0400 const TypeSummaryOptions &options) override;
0401
0402 std::string GetDescription() override;
0403
0404 std::string GetName() override;
0405
0406 static bool classof(const TypeSummaryImpl *S) {
0407 return S->GetKind() == Kind::eScript;
0408 }
0409
0410 typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer;
0411
0412 private:
0413 ScriptSummaryFormat(const ScriptSummaryFormat &) = delete;
0414 const ScriptSummaryFormat &operator=(const ScriptSummaryFormat &) = delete;
0415 };
0416
0417
0418 class BytecodeSummaryFormat : public TypeSummaryImpl {
0419 std::unique_ptr<llvm::MemoryBuffer> m_bytecode;
0420
0421 public:
0422 BytecodeSummaryFormat(const TypeSummaryImpl::Flags &flags,
0423 std::unique_ptr<llvm::MemoryBuffer> bytecode);
0424 bool FormatObject(ValueObject *valobj, std::string &dest,
0425 const TypeSummaryOptions &options) override;
0426 std::string GetDescription() override;
0427 std::string GetName() override;
0428 static bool classof(const TypeSummaryImpl *S) {
0429 return S->GetKind() == Kind::eBytecode;
0430 }
0431 };
0432
0433 }
0434
0435 #endif