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

#include "CPlusPlusLanguage.h"

// C Includes
// C++ Includes
#include <cstring>
#include <cctype>
#include <functional>
#include <mutex>

// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"

// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/DataFormatters/CXXFunctionPointer.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/VectorType.h"

#include "BlockPointer.h"
#include "CxxStringTypes.h"
#include "LibCxx.h"
#include "LibCxxAtomic.h"
#include "LibStdcpp.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

void
CPlusPlusLanguage::Initialize()
{
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   "C++ Language",
                                   CreateInstance);
}

void
CPlusPlusLanguage::Terminate()
{
    PluginManager::UnregisterPlugin (CreateInstance);
}

lldb_private::ConstString
CPlusPlusLanguage::GetPluginNameStatic()
{
    static ConstString g_name("cplusplus");
    return g_name;
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------

lldb_private::ConstString
CPlusPlusLanguage::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
CPlusPlusLanguage::GetPluginVersion()
{
    return 1;
}

//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------

Language *
CPlusPlusLanguage::CreateInstance (lldb::LanguageType language)
{
    if (Language::LanguageIsCPlusPlus(language))
        return new CPlusPlusLanguage();
    return nullptr;
}

void
CPlusPlusLanguage::MethodName::Clear()
{
    m_full.Clear();
    m_basename = llvm::StringRef();
    m_context = llvm::StringRef();
    m_arguments = llvm::StringRef();
    m_qualifiers = llvm::StringRef();
    m_type = eTypeInvalid;
    m_parsed = false;
    m_parse_error = false;
}

bool
ReverseFindMatchingChars (const llvm::StringRef &s,
                          const llvm::StringRef &left_right_chars,
                          size_t &left_pos,
                          size_t &right_pos,
                          size_t pos = llvm::StringRef::npos)
{
    assert (left_right_chars.size() == 2);
    left_pos = llvm::StringRef::npos;
    const char left_char = left_right_chars[0];
    const char right_char = left_right_chars[1];
    pos = s.find_last_of(left_right_chars, pos);
    if (pos == llvm::StringRef::npos || s[pos] == left_char)
        return false;
    right_pos = pos;
    uint32_t depth = 1;
    while (pos > 0 && depth > 0)
    {
        pos = s.find_last_of(left_right_chars, pos);
        if (pos == llvm::StringRef::npos)
            return false;
        if (s[pos] == left_char)
        {
            if (--depth == 0)
            {
                left_pos = pos;
                return left_pos < right_pos;
            }            
        }
        else if (s[pos] == right_char)
        {
            ++depth;
        }
    }
    return false;
}

static bool
IsValidBasename(const llvm::StringRef& basename)
{
    // Check that the basename matches with the following regular expression or is an operator name:
    // "^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$"
    // We are using a hand written implementation because it is significantly more efficient then
    // using the general purpose regular expression library.
    size_t idx = 0;
    if (basename.size() > 0 && basename[0] == '~')
        idx = 1;

    if (basename.size() <= idx)
        return false; // Empty string or "~"

    if (!std::isalpha(basename[idx]) && basename[idx] != '_')
        return false; // First charater (after removing the possible '~'') isn't in [A-Za-z_]

    // Read all characters matching [A-Za-z_0-9]
    ++idx;
    while (idx < basename.size())
    {
        if (!std::isalnum(basename[idx]) && basename[idx] != '_')
            break;
        ++idx;
    }

    // We processed all characters. It is a vaild basename.
    if (idx == basename.size())
        return true;

    // Check for basename with template arguments
    // TODO: Improve the quality of the validation with validating the template arguments
    if (basename[idx] == '<' && basename.back() == '>')
        return true;

    // Check if the basename is a vaild C++ operator name
    if (!basename.startswith("operator"))
        return false;

    static RegularExpression g_operator_regex("^(operator)( ?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|\\[\\]|[\\^<>=!\\/*+-]+)(<.*>)?(\\[\\])?$");
    std::string basename_str(basename.str());
    return g_operator_regex.Execute(basename_str.c_str(), nullptr);
}

void
CPlusPlusLanguage::MethodName::Parse()
{
    if (!m_parsed && m_full)
    {
//        ConstString mangled;
//        m_full.GetMangledCounterpart(mangled);
//        printf ("\n   parsing = '%s'\n", m_full.GetCString());
//        if (mangled)
//            printf ("   mangled = '%s'\n", mangled.GetCString());
        m_parse_error = false;
        m_parsed = true;
        llvm::StringRef full (m_full.GetCString());
        
        size_t arg_start, arg_end;
        llvm::StringRef parens("()", 2);
        if (ReverseFindMatchingChars (full, parens, arg_start, arg_end))
        {
            m_arguments = full.substr(arg_start, arg_end - arg_start + 1);
            if (arg_end + 1 < full.size())
                m_qualifiers = full.substr(arg_end + 1);
            if (arg_start > 0)
            {
                size_t basename_end = arg_start;
                size_t context_start = 0;
                size_t context_end = llvm::StringRef::npos;
                if (basename_end > 0 && full[basename_end-1] == '>')
                {
                    // TODO: handle template junk...
                    // Templated function
                    size_t template_start, template_end;
                    llvm::StringRef lt_gt("<>", 2);
                    if (ReverseFindMatchingChars (full, lt_gt, template_start, template_end, basename_end))
                    {
                        // Check for templated functions that include return type like: 'void foo<Int>()'
                        context_start = full.rfind(' ', template_start);
                        if (context_start == llvm::StringRef::npos)
                            context_start = 0;

                        context_end = full.rfind(':', template_start);
                        if (context_end == llvm::StringRef::npos || context_end < context_start)
                            context_end = context_start;
                    }
                    else
                    {
                        context_end = full.rfind(':', basename_end);
                    }
                }
                else if (context_end == llvm::StringRef::npos)
                {
                    context_end = full.rfind(':', basename_end);
                }

                if (context_end == llvm::StringRef::npos)
                    m_basename = full.substr(0, basename_end);
                else
                {
                    if (context_start < context_end)
                        m_context = full.substr(context_start, context_end - 1);
                    const size_t basename_begin = context_end + 1;
                    m_basename = full.substr(basename_begin, basename_end - basename_begin);
                }
                m_type = eTypeUnknownMethod;
            }
            else
            {
                m_parse_error = true;
                return;
            }

            if (!IsValidBasename(m_basename))
            {
                // The C++ basename doesn't match our regular expressions so this can't
                // be a valid C++ method, clear everything out and indicate an error
                m_context = llvm::StringRef();
                m_basename = llvm::StringRef();
                m_arguments = llvm::StringRef();
                m_qualifiers = llvm::StringRef();
                m_parse_error = true;
            }
        }
        else
        {
            m_parse_error = true;
        }
    }
}

llvm::StringRef
CPlusPlusLanguage::MethodName::GetBasename ()
{
    if (!m_parsed)
        Parse();
    return m_basename;
}

llvm::StringRef
CPlusPlusLanguage::MethodName::GetContext ()
{
    if (!m_parsed)
        Parse();
    return m_context;
}

llvm::StringRef
CPlusPlusLanguage::MethodName::GetArguments ()
{
    if (!m_parsed)
        Parse();
    return m_arguments;
}

llvm::StringRef
CPlusPlusLanguage::MethodName::GetQualifiers ()
{
    if (!m_parsed)
        Parse();
    return m_qualifiers;
}

std::string
CPlusPlusLanguage::MethodName::GetScopeQualifiedName ()
{
    if (!m_parsed)
        Parse();
    if (m_basename.empty() || m_context.empty())
        return std::string();

    std::string res;
    res += m_context;
    res += "::";
    res += m_basename;

    return res;
}

bool
CPlusPlusLanguage::IsCPPMangledName (const char *name)
{
    // FIXME, we should really run through all the known C++ Language plugins and ask each one if
    // this is a C++ mangled name, but we can put that off till there is actually more than one
    // we care about.
    
    return (name != nullptr && name[0] == '_' && name[1] == 'Z');
}

bool
CPlusPlusLanguage::ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier)
{
    static RegularExpression g_basename_regex("^(([A-Za-z_][A-Za-z_0-9]*::)*)(~?[A-Za-z_~][A-Za-z_0-9]*)$");
    RegularExpression::Match match(4);
    if (g_basename_regex.Execute (name, &match))
    {
        match.GetMatchAtIndex(name, 1, context);
        match.GetMatchAtIndex(name, 3, identifier);
        return true;
    }
    return false;
}

class CPPRuntimeEquivalents
{
public:
    CPPRuntimeEquivalents ()
    {
        m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("basic_string<char>"));

        // these two (with a prefixed std::) occur when c++stdlib string class occurs as a template argument in some STL container
        m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("std::basic_string<char>"));
        
        m_impl.Sort();
    }
    
    void
    Add (ConstString& type_name,
         ConstString& type_equivalent)
    {
        m_impl.Insert(type_name.AsCString(), type_equivalent);
    }
    
    uint32_t
    FindExactMatches (ConstString& type_name,
                      std::vector<ConstString>& equivalents)
    {
        uint32_t count = 0;

        for (ImplData match = m_impl.FindFirstValueForName(type_name.AsCString());
             match != nullptr;
             match = m_impl.FindNextValueForName(match))
        {
            equivalents.push_back(match->value);
            count++;
        }

        return count;        
    }
    
    // partial matches can occur when a name with equivalents is a template argument.
    // e.g. we may have "class Foo" be a match for "struct Bar". if we have a typename
    // such as "class Templatized<class Foo, Anything>" we want this to be replaced with
    // "class Templatized<struct Bar, Anything>". Since partial matching is time consuming
    // once we get a partial match, we add it to the exact matches list for faster retrieval
    uint32_t
    FindPartialMatches (ConstString& type_name,
                        std::vector<ConstString>& equivalents)
    {
        uint32_t count = 0;
        
        const char* type_name_cstr = type_name.AsCString();
        
        size_t items_count = m_impl.GetSize();
        
        for (size_t item = 0; item < items_count; item++)
        {
            const char* key_cstr = m_impl.GetCStringAtIndex(item);
            if ( strstr(type_name_cstr,key_cstr) )
            {
                count += AppendReplacements(type_name_cstr,
                                            key_cstr,
                                            equivalents);
            }
        }
        
        return count;
    }
    
private:
    std::string& replace (std::string& target,
                          std::string& pattern,
                          std::string& with)
    {
        size_t pos;
        size_t pattern_len = pattern.size();
        
        while ( (pos = target.find(pattern)) != std::string::npos )
            target.replace(pos, pattern_len, with);
        
        return target;
    }
    
    uint32_t
    AppendReplacements (const char* original,
                        const char *matching_key,
                        std::vector<ConstString>& equivalents)
    {
        std::string matching_key_str(matching_key);
        ConstString original_const(original);
        
        uint32_t count = 0;
        
        for (ImplData match = m_impl.FindFirstValueForName(matching_key);
             match != nullptr;
             match = m_impl.FindNextValueForName(match))
        {
            std::string target(original);
            std::string equiv_class(match->value.AsCString());
            
            replace (target, matching_key_str, equiv_class);
            
            ConstString target_const(target.c_str());

// you will most probably want to leave this off since it might make this map grow indefinitely
#ifdef ENABLE_CPP_EQUIVALENTS_MAP_TO_GROW
            Add(original_const, target_const);
#endif
            equivalents.push_back(target_const);
            
            count++;
        }
        
        return count;
    }
    
    typedef UniqueCStringMap<ConstString> Impl;
    typedef const Impl::Entry* ImplData;
    Impl m_impl;
};

static CPPRuntimeEquivalents&
GetEquivalentsMap ()
{
    static CPPRuntimeEquivalents g_equivalents_map;
    return g_equivalents_map;
}

uint32_t
CPlusPlusLanguage::FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents)
{
    uint32_t count = GetEquivalentsMap().FindExactMatches(type_name, equivalents);

    bool might_have_partials= 
        ( count == 0 )  // if we have a full name match just use it
        && (strchr(type_name.AsCString(), '<') != nullptr  // we should only have partial matches when templates are involved, check that we have
            && strchr(type_name.AsCString(), '>') != nullptr); // angle brackets in the type_name before trying to scan for partial matches
    
    if ( might_have_partials )
        count = GetEquivalentsMap().FindPartialMatches(type_name, equivalents);
    
    return count;
}

static void
LoadLibCxxFormatters (lldb::TypeCategoryImplSP cpp_category_sp)
{
    if (!cpp_category_sp)
        return;
    
    TypeSummaryImpl::Flags stl_summary_flags;
    stl_summary_flags.SetCascades(true)
    .SetSkipPointers(false)
    .SetSkipReferences(false)
    .SetDontShowChildren(true)
    .SetDontShowValue(true)
    .SetShowMembersOneLiner(false)
    .SetHideItemNames(false);
    
#ifndef LLDB_DISABLE_PYTHON
    lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider, "std::string summary provider"));
    lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider"));
    
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::string"),
                                                         std_string_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::string"),
                                                         std_string_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"),
                                                         std_string_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >"),
                                                         std_string_summary_sp);
    
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::wstring"),
                                                         std_wstring_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::wstring"),
                                                         std_wstring_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >"),
                                                         std_wstring_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__ndk1::basic_string<wchar_t, std::__ndk1::char_traits<wchar_t>, std::__ndk1::allocator<wchar_t> >"),
                                                         std_wstring_summary_sp);
    
    SyntheticChildren::Flags stl_synth_flags;
    stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
    
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("^std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, "libc++ std::vector synthetic children", ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", ConstString("^std::__(ndk)?1::map<.+> >(( )?&)?$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__(ndk)?1::vector<std::__(ndk)?1::allocator<bool> >"), stl_synth_flags);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator, "libc++ std::vector<bool> synthetic children", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_synth_flags);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::set synthetic children", ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", ConstString("^std::__(ndk)?1::multimap<.+> >(( )?&)?$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, "libc++ std::unordered containers synthetic children", ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator, "libc++ std::initializer_list synthetic children", ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, "libc++ std::atomic synthetic children", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_synth_flags, true);

    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^(std::__(ndk)?1::)deque<.+>(( )?&)?$")),
                                                               SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                                                 "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
    
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "shared_ptr synthetic children", ConstString("^(std::__(ndk)?1::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "weak_ptr synthetic children", ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true);
    
    stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(false);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector summary provider", ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::list summary provider", ConstString("^std::__(ndk)?1::list<.+>(( )?&)?$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::map summary provider", ConstString("^std::__(ndk)?1::map<.+>(( )?&)?$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::deque summary provider", ConstString("^std::__(ndk)?1::deque<.+>(( )?&)?$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::set summary provider", ConstString("^std::__(ndk)?1::set<.+>(( )?&)?$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multiset summary provider", ConstString("^std::__(ndk)?1::multiset<.+>(( )?&)?$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multimap summary provider", ConstString("^std::__(ndk)?1::multimap<.+>(( )?&)?$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::unordered containers summary provider", ConstString("^(std::__(ndk)?1::)unordered_(multi)?(map|set)<.+> >$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, "libc++ std::atomic summary provider", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true);
    
    stl_summary_flags.SetSkipPointers(true);
    
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::shared_ptr summary provider", ConstString("^std::__(ndk)?1::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::weak_ptr summary provider", ConstString("^std::__(ndk)?1::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, true);
    
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^std::__(ndk)?1::__wrap_iter<.+>$"), stl_synth_flags, true);
    
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::vector<bool> summary provider", ConstString("std::__(ndk)?1::vector<bool, std::__(ndk)?1::allocator<bool> >"), stl_summary_flags);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::__(ndk)?1::__map_iterator<.+>$"), stl_synth_flags, true);
#endif
}

static void
LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp)
{
    if (!cpp_category_sp)
        return;
    
    TypeSummaryImpl::Flags stl_summary_flags;
    stl_summary_flags.SetCascades(true)
    .SetSkipPointers(false)
    .SetSkipReferences(false)
    .SetDontShowChildren(true)
    .SetDontShowValue(true)
    .SetShowMembersOneLiner(false)
    .SetHideItemNames(false);
    
    lldb::TypeSummaryImplSP std_string_summary_sp(new StringSummaryFormat(stl_summary_flags,
                                                                          "${var._M_dataplus._M_p}"));

    lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags,
                                                                                 LibStdcppStringSummaryProvider,
                                                                                 "libstdc++ c++11 std::string summary provider"));
    lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags,
                                                                                 LibStdcppWStringSummaryProvider,
                                                                                 "libstdc++ c++11 std::wstring summary provider"));

    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
                                                      std_string_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char>"),
                                                      std_string_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"),
                                                      std_string_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
                                                      std_string_summary_sp);

    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::string"),
                                                      cxx11_string_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
                                                      cxx11_string_summary_sp);

    // making sure we force-pick the summary for printing wstring (_M_p is a wchar_t*)
    lldb::TypeSummaryImplSP std_wstring_summary_sp(new StringSummaryFormat(stl_summary_flags,
                                                                           "${var._M_dataplus._M_p%S}"));
    
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::wstring"),
                                                      std_wstring_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t>"),
                                                      std_wstring_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >"),
                                                      std_wstring_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
                                                      std_wstring_summary_sp);

    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::wstring"),
                                                      cxx11_wstring_summary_sp);
    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
                                                      cxx11_wstring_summary_sp);

#ifndef LLDB_DISABLE_PYTHON
    
    SyntheticChildren::Flags stl_synth_flags;
    stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
    
    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
                                                            SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                                              "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
                                                            SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                                              "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")),
                                                            SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                                              "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
    stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true);
    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
                                                           TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
                                                                                                     "size=${svar%#}")));
    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
                                                           TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
                                                                                                     "size=${svar%#}")));
    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")),
                                                           TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
                                                                                                     "size=${svar%#}")));

    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);

    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);

    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
                    "std::shared_ptr synthetic children", ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags,
                    true);
    AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator,
                    "std::weak_ptr synthetic children", ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags,
                    true);

    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
                  "libstdc++ std::shared_ptr summary provider", ConstString("^std::shared_ptr<.+>(( )?&)?$"),
                  stl_summary_flags, true);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider,
                  "libstdc++ std::weak_ptr summary provider", ConstString("^std::weak_ptr<.+>(( )?&)?$"),
                  stl_summary_flags, true);
#endif
}

static void
LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp)
{
    if (!cpp_category_sp)
        return;
    
    TypeSummaryImpl::Flags string_flags;
    string_flags.SetCascades(true)
    .SetSkipPointers(true)
    .SetSkipReferences(false)
    .SetDontShowChildren(true)
    .SetDontShowValue(false)
    .SetShowMembersOneLiner(false)
    .SetHideItemNames(false);
    
    TypeSummaryImpl::Flags string_array_flags;
    string_array_flags.SetCascades(true)
    .SetSkipPointers(true)
    .SetSkipReferences(false)
    .SetDontShowChildren(true)
    .SetDontShowValue(true)
    .SetShowMembersOneLiner(false)
    .SetHideItemNames(false);
    
#ifndef LLDB_DISABLE_PYTHON
    // FIXME because of a bug in the FormattersContainer we need to add a summary for both X* and const X* (<rdar://problem/12717717>)
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("char16_t *"), string_flags);
    AddCXXSummary(cpp_category_sp,
                  lldb_private::formatters::Char16StringSummaryProvider,
                  "char16_t [] summary provider",
                  ConstString("char16_t \\[[0-9]+\\]"),
                  string_array_flags,
                  true);
    
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t * summary provider", ConstString("char32_t *"), string_flags);
    AddCXXSummary(cpp_category_sp,
                  lldb_private::formatters::Char32StringSummaryProvider,
                  "char32_t [] summary provider",
                  ConstString("char32_t \\[[0-9]+\\]"),
                  string_array_flags,
                  true);
    
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true);
    
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "unichar * summary provider", ConstString("unichar *"), string_flags);
    
    TypeSummaryImpl::Flags widechar_flags;
    widechar_flags.SetDontShowValue(true)
    .SetSkipPointers(true)
    .SetSkipReferences(false)
    .SetCascades(true)
    .SetDontShowChildren(true)
    .SetHideItemNames(true)
    .SetShowMembersOneLiner(false);
    
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, "char16_t summary provider", ConstString("char16_t"), widechar_flags);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32SummaryProvider, "char32_t summary provider", ConstString("char32_t"), widechar_flags);
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider, "wchar_t summary provider", ConstString("wchar_t"), widechar_flags);
    
    AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, "unichar summary provider", ConstString("unichar"), widechar_flags);
#endif
}

lldb::TypeCategoryImplSP
CPlusPlusLanguage::GetFormatters ()
{
    static std::once_flag g_initialize;
    static TypeCategoryImplSP g_category;
    
    std::call_once(g_initialize, [this] () -> void {
        DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
        if (g_category)
        {
            LoadLibCxxFormatters(g_category);
            LoadLibStdcppFormatters(g_category);
            LoadSystemFormatters(g_category);
        }
    });
    return g_category;
}

HardcodedFormatters::HardcodedSummaryFinder
CPlusPlusLanguage::GetHardcodedSummaries ()
{
    static std::once_flag g_initialize;
    static ConstString g_vectortypes("VectorTypes");
    static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
    
    std::call_once(g_initialize, [] () -> void {
        g_formatters.push_back(
                                        [](lldb_private::ValueObject& valobj,
                                           lldb::DynamicValueType,
                                           FormatManager&) -> TypeSummaryImpl::SharedPointer {
                                            static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags(), lldb_private::formatters::CXXFunctionPointerSummaryProvider, "Function pointer summary provider"));
                                            if (valobj.GetCompilerType().IsFunctionPointerType())
                                            {
                                                return formatter_sp;
                                            }
                                            return nullptr;
                                        });
        g_formatters.push_back(
                                        [](lldb_private::ValueObject& valobj,
                                           lldb::DynamicValueType,
                                           FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer {
                                            static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags()
                                                                                                                                     .SetCascades(true)
                                                                                                                                     .SetDontShowChildren(true)
                                                                                                                                     .SetHideItemNames(true)
                                                                                                                                     .SetShowMembersOneLiner(true)
                                                                                                                                     .SetSkipPointers(true)
                                                                                                                                     .SetSkipReferences(false),
                                                                                                                                     lldb_private::formatters::VectorTypeSummaryProvider,
                                                                                                                                     "vector_type pointer summary provider"));
                                            if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr))
                                            {
                                                if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
                                                    return formatter_sp;
                                            }
                                            return nullptr;
                                        });
        g_formatters.push_back(
                               [](lldb_private::ValueObject& valobj,
                                  lldb::DynamicValueType,
                                  FormatManager& fmt_mgr) -> TypeSummaryImpl::SharedPointer {
                                   static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat(TypeSummaryImpl::Flags()
                                                                                                                            .SetCascades(true)
                                                                                                                            .SetDontShowChildren(true)
                                                                                                                            .SetHideItemNames(true)
                                                                                                                            .SetShowMembersOneLiner(true)
                                                                                                                            .SetSkipPointers(true)
                                                                                                                            .SetSkipReferences(false),
                                                                                                                            lldb_private::formatters::BlockPointerSummaryProvider,
                                                                                                                            "block pointer summary provider"));
                                   if (valobj.GetCompilerType().IsBlockPointerType(nullptr))
                                   {
                                       return formatter_sp;
                                   }
                                   return nullptr;
                               });
    });
    
    return g_formatters;
}

HardcodedFormatters::HardcodedSyntheticFinder
CPlusPlusLanguage::GetHardcodedSynthetics ()
{
    static std::once_flag g_initialize;
    static ConstString g_vectortypes("VectorTypes");
    static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
    
    std::call_once(g_initialize, [] () -> void {
        g_formatters.push_back(
                                         [](lldb_private::ValueObject& valobj,
                                            lldb::DynamicValueType,
                                            FormatManager& fmt_mgr) -> SyntheticChildren::SharedPointer {
                                             static CXXSyntheticChildren::SharedPointer formatter_sp(new CXXSyntheticChildren(SyntheticChildren::Flags().SetCascades(true).SetSkipPointers(true).SetSkipReferences(true).SetNonCacheable(true),
                                                                                                                              "vector_type synthetic children",
                                                                                                                              lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
                                             if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr))
                                             {
                                                 if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
                                                     return formatter_sp;
                                             }
                                             return nullptr;
                                         });
        g_formatters.push_back(
                                         [](lldb_private::ValueObject& valobj,
                                            lldb::DynamicValueType,
                                            FormatManager& fmt_mgr) -> SyntheticChildren::SharedPointer {
                                             static CXXSyntheticChildren::SharedPointer formatter_sp(new CXXSyntheticChildren(SyntheticChildren::Flags().SetCascades(true).SetSkipPointers(true).SetSkipReferences(true).SetNonCacheable(true),
                                                                                                                              "block pointer synthetic children",
                                                                                                                              lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
                                             if (valobj.GetCompilerType().IsBlockPointerType(nullptr))
                                             {
                                                 return formatter_sp;
                                             }
                                             return nullptr;
                                         });

    });
    
    return g_formatters;
}
