| //===-- ValueObjectPrinter.h ---------------------------------------*- C++ |
| //-*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLDB_DATAFORMATTERS_VALUEOBJECTPRINTER_H |
| #define LLDB_DATAFORMATTERS_VALUEOBJECTPRINTER_H |
| |
| #include "lldb/lldb-private.h" |
| #include "lldb/lldb-public.h" |
| |
| #include "lldb/Utility/Flags.h" |
| |
| #include "lldb/DataFormatters/DumpValueObjectOptions.h" |
| #include "lldb/Symbol/CompilerType.h" |
| |
| namespace lldb_private { |
| |
| class ValueObjectPrinter { |
| /// The ValueObjectPrinter is a one-shot printer for ValueObjects. It |
| /// does not retain the ValueObject it is printing, that is the job of |
| /// its caller. It also doesn't attempt to track changes in the |
| /// ValueObject, e.g. changing synthetic child providers or changing |
| /// dynamic vrs. static vrs. synthetic settings. |
| public: |
| ValueObjectPrinter(ValueObject &valobj, Stream *s); |
| |
| ValueObjectPrinter(ValueObject &valobj, Stream *s, |
| const DumpValueObjectOptions &options); |
| |
| ~ValueObjectPrinter() = default; |
| |
| bool PrintValueObject(); |
| |
| protected: |
| typedef std::set<uint64_t> InstancePointersSet; |
| typedef std::shared_ptr<InstancePointersSet> InstancePointersSetSP; |
| |
| InstancePointersSetSP m_printed_instance_pointers; |
| |
| // only this class (and subclasses, if any) should ever be concerned with the |
| // depth mechanism |
| ValueObjectPrinter(ValueObject &valobj, Stream *s, |
| const DumpValueObjectOptions &options, |
| const DumpValueObjectOptions::PointerDepth &ptr_depth, |
| uint32_t curr_depth, |
| InstancePointersSetSP printed_instance_pointers); |
| |
| // we should actually be using delegating constructors here but some versions |
| // of GCC still have trouble with those |
| void Init(ValueObject &valobj, Stream *s, |
| const DumpValueObjectOptions &options, |
| const DumpValueObjectOptions::PointerDepth &ptr_depth, |
| uint32_t curr_depth, |
| InstancePointersSetSP printed_instance_pointers); |
| |
| /// Cache the ValueObject we are actually going to print. If this |
| /// ValueObject has a Dynamic type, we return that, if either the original |
| /// ValueObject or its Dynamic type has a Synthetic provider, return that. |
| /// This will never return an empty ValueObject, since we use the ValueObject |
| /// to carry errors. |
| /// Note, this gets called when making the printer object, and uses the |
| /// use dynamic and use synthetic settings of the ValueObject being printed, |
| /// so changes made to these settings won't affect already made |
| /// ValueObjectPrinters. SetupMostSpecializedValue(); |
| |
| /// Access the cached "most specialized value" - that is the one to use for |
| /// printing the value object's value. However, be sure to use |
| /// GetValueForChildGeneration when you are generating the children of this |
| /// value. |
| ValueObject &GetMostSpecializedValue(); |
| |
| void SetupMostSpecializedValue(); |
| |
| const char *GetDescriptionForDisplay(); |
| |
| const char *GetRootNameForDisplay(); |
| |
| bool ShouldPrintValueObject(); |
| |
| bool IsNil(); |
| |
| bool IsUninitialized(); |
| |
| bool IsPtr(); |
| |
| bool IsRef(); |
| |
| bool IsInstancePointer(); |
| |
| bool IsAggregate(); |
| |
| bool PrintLocationIfNeeded(); |
| |
| void PrintDecl(); |
| |
| bool CheckScopeIfNeeded(); |
| |
| bool ShouldPrintEmptyBrackets(bool value_printed, bool summary_printed); |
| |
| TypeSummaryImpl *GetSummaryFormatter(bool null_if_omitted = true); |
| |
| void GetValueSummaryError(std::string &value, std::string &summary, |
| std::string &error); |
| |
| bool PrintValueAndSummaryIfNeeded(bool &value_printed, bool &summary_printed); |
| |
| bool PrintObjectDescriptionIfNeeded(bool value_printed, bool summary_printed); |
| |
| bool |
| ShouldPrintChildren(DumpValueObjectOptions::PointerDepth &curr_ptr_depth); |
| |
| bool ShouldExpandEmptyAggregates(); |
| |
| ValueObject &GetValueObjectForChildrenGeneration(); |
| |
| void PrintChildrenPreamble(bool value_printed, bool summary_printed); |
| |
| void PrintChildrenPostamble(bool print_dotdotdot); |
| |
| lldb::ValueObjectSP GenerateChild(ValueObject &synth_valobj, size_t idx); |
| |
| void PrintChild(lldb::ValueObjectSP child_sp, |
| const DumpValueObjectOptions::PointerDepth &curr_ptr_depth); |
| |
| llvm::Expected<uint32_t> GetMaxNumChildrenToPrint(bool &print_dotdotdot); |
| |
| void |
| PrintChildren(bool value_printed, bool summary_printed, |
| const DumpValueObjectOptions::PointerDepth &curr_ptr_depth); |
| |
| void PrintChildrenIfNeeded(bool value_printed, bool summary_printed); |
| |
| bool PrintChildrenOneLiner(bool hide_names); |
| |
| bool HasReachedMaximumDepth(); |
| |
| private: |
| bool ShouldShowName() const; |
| |
| ValueObject &m_orig_valobj; |
| ValueObject *m_cached_valobj; /// Cache the current "most specialized" value. |
| /// Don't use this directly, use |
| /// GetMostSpecializedValue. |
| Stream *m_stream; |
| DumpValueObjectOptions m_options; |
| Flags m_type_flags; |
| CompilerType m_compiler_type; |
| DumpValueObjectOptions::PointerDepth m_ptr_depth; |
| uint32_t m_curr_depth; |
| LazyBool m_should_print; |
| LazyBool m_is_nil; |
| LazyBool m_is_uninit; |
| LazyBool m_is_ptr; |
| LazyBool m_is_ref; |
| LazyBool m_is_aggregate; |
| LazyBool m_is_instance_ptr; |
| std::pair<TypeSummaryImpl *, bool> m_summary_formatter; |
| std::string m_value; |
| std::string m_summary; |
| std::string m_error; |
| bool m_val_summary_ok; |
| |
| friend struct StringSummaryFormat; |
| |
| ValueObjectPrinter(const ValueObjectPrinter &) = delete; |
| const ValueObjectPrinter &operator=(const ValueObjectPrinter &) = delete; |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // LLDB_DATAFORMATTERS_VALUEOBJECTPRINTER_H |