//===-- LibCxx.h ---------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_LibCxx_h_
#define liblldb_LibCxx_h_

#include "lldb/Core/Stream.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/DataFormatters/TypeSynthetic.h"

namespace lldb_private {
    namespace formatters
    {
        
        bool
        LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::string
        
        bool
        LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::wstring
        
        bool
        LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libc++ std::shared_ptr<> and std::weak_ptr<>
        
        class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd
        {
        public:
            LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
            
            size_t
            CalculateNumChildren() override;
            
            lldb::ValueObjectSP
            GetChildAtIndex(size_t idx) override;
            
            bool
            Update() override;
            
            bool
            MightHaveChildren() override;
            
            size_t
            GetIndexOfChildWithName(const ConstString &name) override;
            
            ~LibcxxVectorBoolSyntheticFrontEnd() override;
            
        private:
            CompilerType m_bool_type;
            ExecutionContextRef m_exe_ctx_ref;
            uint64_t m_count;
            lldb::addr_t m_base_data_address;
            std::map<size_t,lldb::ValueObjectSP> m_children;
        };
        
        SyntheticChildrenFrontEnd* LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
        
        bool
        LibcxxContainerSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
        
        class LibCxxMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
        {
        public:
            LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
            
            size_t
            CalculateNumChildren() override;
            
            lldb::ValueObjectSP
            GetChildAtIndex(size_t idx) override;
            
            bool
            Update() override;
            
            bool
            MightHaveChildren() override;
            
            size_t
            GetIndexOfChildWithName(const ConstString &name) override;
            
            ~LibCxxMapIteratorSyntheticFrontEnd() override;
            
        private:
            ValueObject *m_pair_ptr;
        };
        
        SyntheticChildrenFrontEnd* LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
        
        SyntheticChildrenFrontEnd* LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
        
        class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd
        {
        public:
            LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
            
            size_t
            CalculateNumChildren() override;
            
            lldb::ValueObjectSP
            GetChildAtIndex(size_t idx) override;
            
            bool
            Update() override;
            
            bool
            MightHaveChildren() override;
            
            size_t
            GetIndexOfChildWithName(const ConstString &name) override;
            
            ~LibcxxSharedPtrSyntheticFrontEnd() override;
            
        private:
            ValueObject* m_cntrl;
            lldb::ValueObjectSP m_count_sp;
            lldb::ValueObjectSP m_weak_count_sp;
            uint8_t m_ptr_size;
            lldb::ByteOrder m_byte_order;
        };
        
        SyntheticChildrenFrontEnd* LibcxxSharedPtrSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
        
        SyntheticChildrenFrontEnd* LibcxxStdVectorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
        
        SyntheticChildrenFrontEnd* LibcxxStdListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
        
        SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
        
        SyntheticChildrenFrontEnd* LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
        
        SyntheticChildrenFrontEnd* LibcxxInitializerListSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);

    } // namespace formatters
} // namespace lldb_private

#endif // liblldb_LibCxx_h_
