Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:47

0001 //===-- TypeSummary.h -------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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   // we are using a ValueObject* instead of a ValueObjectSP because we do not
0257   // need to hold on to this for extended periods of time and we trust the
0258   // ValueObject to stay around for as long as it is required for us to
0259   // generate its summary
0260   virtual bool FormatObject(ValueObject *valobj, std::string &dest,
0261                             const TypeSummaryOptions &options) = 0;
0262 
0263   virtual std::string GetDescription() = 0;
0264 
0265   /// Get the name of the Type Summary Provider, either a C++ class, a summary
0266   /// string, or a script function name.
0267   virtual std::string GetName() = 0;
0268 
0269   /// Get the name of the kind of Summary Provider, either c++, summary string,
0270   /// script or python.
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 // simple string-based summaries, using ${var to show data
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 // summaries implemented via a C++ function
0320 struct CXXFunctionSummaryFormat : public TypeSummaryImpl {
0321   // we should convert these to SBValue and SBStream if we ever cross the
0322   // boundary towards the external world
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 // Python-based summaries, running script code to show data
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 /// A summary formatter that is defined in LLDB formmater bytecode.
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 } // namespace lldb_private
0434 
0435 #endif // LLDB_DATAFORMATTERS_TYPESUMMARY_H