blob: 9fe4dad01a9fdac5c17d5003498410f50488419c [file] [log] [blame]
//===-- SBTypeCategory.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/lldb-python.h"
#include "lldb/API/SBTypeCategory.h"
#include "lldb/API/SBTypeFilter.h"
#include "lldb/API/SBTypeFormat.h"
#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBTypeSynthetic.h"
#include "lldb/API/SBTypeNameSpecifier.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Debugger.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
using namespace lldb;
using namespace lldb_private;
typedef std::pair<lldb::TypeCategoryImplSP,user_id_t> ImplType;
SBTypeCategory::SBTypeCategory() :
m_opaque_sp()
{
}
SBTypeCategory::SBTypeCategory (const char* name) :
m_opaque_sp()
{
DataVisualization::Categories::GetCategory(ConstString(name), m_opaque_sp);
}
SBTypeCategory::SBTypeCategory (const lldb::SBTypeCategory &rhs) :
m_opaque_sp(rhs.m_opaque_sp)
{
}
SBTypeCategory::~SBTypeCategory ()
{
}
bool
SBTypeCategory::IsValid() const
{
return (m_opaque_sp.get() != NULL);
}
bool
SBTypeCategory::GetEnabled ()
{
if (!IsValid())
return false;
return m_opaque_sp->IsEnabled();
}
void
SBTypeCategory::SetEnabled (bool enabled)
{
if (!IsValid())
return;
if (enabled)
DataVisualization::Categories::Enable(m_opaque_sp);
else
DataVisualization::Categories::Disable(m_opaque_sp);
}
const char*
SBTypeCategory::GetName()
{
if (!IsValid())
return NULL;
return m_opaque_sp->GetName();
}
uint32_t
SBTypeCategory::GetNumFormats ()
{
if (!IsValid())
return 0;
return m_opaque_sp->GetTypeFormatsContainer()->GetCount() + m_opaque_sp->GetRegexTypeFormatsContainer()->GetCount();
}
uint32_t
SBTypeCategory::GetNumSummaries ()
{
if (!IsValid())
return 0;
return m_opaque_sp->GetTypeSummariesContainer()->GetCount() + m_opaque_sp->GetRegexTypeSummariesContainer()->GetCount();
}
uint32_t
SBTypeCategory::GetNumFilters ()
{
if (!IsValid())
return 0;
return m_opaque_sp->GetTypeFiltersContainer()->GetCount() + m_opaque_sp->GetRegexTypeFiltersContainer()->GetCount();
}
#ifndef LLDB_DISABLE_PYTHON
uint32_t
SBTypeCategory::GetNumSynthetics ()
{
if (!IsValid())
return 0;
return m_opaque_sp->GetTypeSyntheticsContainer()->GetCount() + m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetCount();
}
#endif
lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForFilterAtIndex (uint32_t index)
{
if (!IsValid())
return SBTypeNameSpecifier();
return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForFilterAtIndex(index));
}
lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForFormatAtIndex (uint32_t index)
{
if (!IsValid())
return SBTypeNameSpecifier();
return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForFormatAtIndex(index));
}
lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForSummaryAtIndex (uint32_t index)
{
if (!IsValid())
return SBTypeNameSpecifier();
return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForSummaryAtIndex(index));
}
#ifndef LLDB_DISABLE_PYTHON
lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForSyntheticAtIndex (uint32_t index)
{
if (!IsValid())
return SBTypeNameSpecifier();
return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForSyntheticAtIndex(index));
}
#endif
SBTypeFilter
SBTypeCategory::GetFilterForType (SBTypeNameSpecifier spec)
{
if (!IsValid())
return SBTypeFilter();
if (!spec.IsValid())
return SBTypeFilter();
lldb::SyntheticChildrenSP children_sp;
if (spec.IsRegex())
m_opaque_sp->GetRegexTypeFiltersContainer()->GetExact(ConstString(spec.GetName()), children_sp);
else
m_opaque_sp->GetTypeFiltersContainer()->GetExact(ConstString(spec.GetName()), children_sp);
if (!children_sp)
return lldb::SBTypeFilter();
TypeFilterImplSP filter_sp = std::static_pointer_cast<TypeFilterImpl>(children_sp);
return lldb::SBTypeFilter(filter_sp);
}
SBTypeFormat
SBTypeCategory::GetFormatForType (SBTypeNameSpecifier spec)
{
if (!IsValid())
return SBTypeFormat();
if (!spec.IsValid())
return SBTypeFormat();
lldb::TypeFormatImplSP format_sp;
if (spec.IsRegex())
m_opaque_sp->GetRegexTypeFormatsContainer()->GetExact(ConstString(spec.GetName()), format_sp);
else
m_opaque_sp->GetTypeFormatsContainer()->GetExact(ConstString(spec.GetName()), format_sp);
if (!format_sp)
return lldb::SBTypeFormat();
return lldb::SBTypeFormat(format_sp);
}
#ifndef LLDB_DISABLE_PYTHON
SBTypeSummary
SBTypeCategory::GetSummaryForType (SBTypeNameSpecifier spec)
{
if (!IsValid())
return SBTypeSummary();
if (!spec.IsValid())
return SBTypeSummary();
lldb::TypeSummaryImplSP summary_sp;
if (spec.IsRegex())
m_opaque_sp->GetRegexTypeSummariesContainer()->GetExact(ConstString(spec.GetName()), summary_sp);
else
m_opaque_sp->GetTypeSummariesContainer()->GetExact(ConstString(spec.GetName()), summary_sp);
if (!summary_sp)
return lldb::SBTypeSummary();
return lldb::SBTypeSummary(summary_sp);
}
#endif // LLDB_DISABLE_PYTHON
#ifndef LLDB_DISABLE_PYTHON
SBTypeSynthetic
SBTypeCategory::GetSyntheticForType (SBTypeNameSpecifier spec)
{
if (!IsValid())
return SBTypeSynthetic();
if (!spec.IsValid())
return SBTypeSynthetic();
lldb::SyntheticChildrenSP children_sp;
if (spec.IsRegex())
m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetExact(ConstString(spec.GetName()), children_sp);
else
m_opaque_sp->GetTypeSyntheticsContainer()->GetExact(ConstString(spec.GetName()), children_sp);
if (!children_sp)
return lldb::SBTypeSynthetic();
ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
return lldb::SBTypeSynthetic(synth_sp);
}
#endif
#ifndef LLDB_DISABLE_PYTHON
SBTypeFilter
SBTypeCategory::GetFilterAtIndex (uint32_t index)
{
if (!IsValid())
return SBTypeFilter();
lldb::SyntheticChildrenSP children_sp = m_opaque_sp->GetSyntheticAtIndex((index));
if (!children_sp.get())
return lldb::SBTypeFilter();
TypeFilterImplSP filter_sp = std::static_pointer_cast<TypeFilterImpl>(children_sp);
return lldb::SBTypeFilter(filter_sp);
}
#endif
SBTypeFormat
SBTypeCategory::GetFormatAtIndex (uint32_t index)
{
if (!IsValid())
return SBTypeFormat();
return SBTypeFormat(m_opaque_sp->GetFormatAtIndex((index)));
}
#ifndef LLDB_DISABLE_PYTHON
SBTypeSummary
SBTypeCategory::GetSummaryAtIndex (uint32_t index)
{
if (!IsValid())
return SBTypeSummary();
return SBTypeSummary(m_opaque_sp->GetSummaryAtIndex((index)));
}
#endif
#ifndef LLDB_DISABLE_PYTHON
SBTypeSynthetic
SBTypeCategory::GetSyntheticAtIndex (uint32_t index)
{
if (!IsValid())
return SBTypeSynthetic();
lldb::SyntheticChildrenSP children_sp = m_opaque_sp->GetSyntheticAtIndex((index));
if (!children_sp.get())
return lldb::SBTypeSynthetic();
ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
return lldb::SBTypeSynthetic(synth_sp);
}
#endif
bool
SBTypeCategory::AddTypeFormat (SBTypeNameSpecifier type_name,
SBTypeFormat format)
{
if (!IsValid())
return false;
if (!type_name.IsValid())
return false;
if (!format.IsValid())
return false;
if (type_name.IsRegex())
m_opaque_sp->GetRegexTypeFormatsContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), format.GetSP());
else
m_opaque_sp->GetTypeFormatsContainer()->Add(ConstString(type_name.GetName()), format.GetSP());
return true;
}
bool
SBTypeCategory::DeleteTypeFormat (SBTypeNameSpecifier type_name)
{
if (!IsValid())
return false;
if (!type_name.IsValid())
return false;
if (type_name.IsRegex())
return m_opaque_sp->GetRegexTypeFormatsContainer()->Delete(ConstString(type_name.GetName()));
else
return m_opaque_sp->GetTypeFormatsContainer()->Delete(ConstString(type_name.GetName()));
}
#ifndef LLDB_DISABLE_PYTHON
bool
SBTypeCategory::AddTypeSummary (SBTypeNameSpecifier type_name,
SBTypeSummary summary)
{
if (!IsValid())
return false;
if (!type_name.IsValid())
return false;
if (!summary.IsValid())
return false;
// FIXME: we need to iterate over all the Debugger objects and have each of them contain a copy of the function
// since we currently have formatters live in a global space, while Python code lives in a specific Debugger-related environment
// this should eventually be fixed by deciding a final location in the LLDB object space for formatters
if (summary.IsFunctionCode())
{
void *name_token = (void*)ConstString(type_name.GetName()).GetCString();
const char* script = summary.GetData();
StringList input; input.SplitIntoLines(script, strlen(script));
uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers();
bool need_set = true;
for (uint32_t j = 0;
j < num_debuggers;
j++)
{
DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j);
if (debugger_sp)
{
ScriptInterpreter* interpreter_ptr = debugger_sp->GetCommandInterpreter().GetScriptInterpreter();
if (interpreter_ptr)
{
std::string output;
if (interpreter_ptr->GenerateTypeScriptFunction(input, output, name_token) && !output.empty())
{
if (need_set)
{
need_set = false;
summary.SetFunctionName(output.c_str());
}
}
}
}
}
}
if (type_name.IsRegex())
m_opaque_sp->GetRegexTypeSummariesContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), summary.GetSP());
else
m_opaque_sp->GetTypeSummariesContainer()->Add(ConstString(type_name.GetName()), summary.GetSP());
return true;
}
#endif
bool
SBTypeCategory::DeleteTypeSummary (SBTypeNameSpecifier type_name)
{
if (!IsValid())
return false;
if (!type_name.IsValid())
return false;
if (type_name.IsRegex())
return m_opaque_sp->GetRegexTypeSummariesContainer()->Delete(ConstString(type_name.GetName()));
else
return m_opaque_sp->GetTypeSummariesContainer()->Delete(ConstString(type_name.GetName()));
}
bool
SBTypeCategory::AddTypeFilter (SBTypeNameSpecifier type_name,
SBTypeFilter filter)
{
if (!IsValid())
return false;
if (!type_name.IsValid())
return false;
if (!filter.IsValid())
return false;
if (type_name.IsRegex())
m_opaque_sp->GetRegexTypeFiltersContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), filter.GetSP());
else
m_opaque_sp->GetTypeFiltersContainer()->Add(ConstString(type_name.GetName()), filter.GetSP());
return true;
}
bool
SBTypeCategory::DeleteTypeFilter (SBTypeNameSpecifier type_name)
{
if (!IsValid())
return false;
if (!type_name.IsValid())
return false;
if (type_name.IsRegex())
return m_opaque_sp->GetRegexTypeFiltersContainer()->Delete(ConstString(type_name.GetName()));
else
return m_opaque_sp->GetTypeFiltersContainer()->Delete(ConstString(type_name.GetName()));
}
#ifndef LLDB_DISABLE_PYTHON
bool
SBTypeCategory::AddTypeSynthetic (SBTypeNameSpecifier type_name,
SBTypeSynthetic synth)
{
if (!IsValid())
return false;
if (!type_name.IsValid())
return false;
if (!synth.IsValid())
return false;
// FIXME: we need to iterate over all the Debugger objects and have each of them contain a copy of the function
// since we currently have formatters live in a global space, while Python code lives in a specific Debugger-related environment
// this should eventually be fixed by deciding a final location in the LLDB object space for formatters
if (synth.IsClassCode())
{
void *name_token = (void*)ConstString(type_name.GetName()).GetCString();
const char* script = synth.GetData();
StringList input; input.SplitIntoLines(script, strlen(script));
uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers();
bool need_set = true;
for (uint32_t j = 0;
j < num_debuggers;
j++)
{
DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j);
if (debugger_sp)
{
ScriptInterpreter* interpreter_ptr = debugger_sp->GetCommandInterpreter().GetScriptInterpreter();
if (interpreter_ptr)
{
std::string output;
if (interpreter_ptr->GenerateTypeSynthClass(input, output, name_token) && !output.empty())
{
if (need_set)
{
need_set = false;
synth.SetClassName(output.c_str());
}
}
}
}
}
}
if (type_name.IsRegex())
m_opaque_sp->GetRegexTypeSyntheticsContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), synth.GetSP());
else
m_opaque_sp->GetTypeSyntheticsContainer()->Add(ConstString(type_name.GetName()), synth.GetSP());
return true;
}
bool
SBTypeCategory::DeleteTypeSynthetic (SBTypeNameSpecifier type_name)
{
if (!IsValid())
return false;
if (!type_name.IsValid())
return false;
if (type_name.IsRegex())
return m_opaque_sp->GetRegexTypeSyntheticsContainer()->Delete(ConstString(type_name.GetName()));
else
return m_opaque_sp->GetTypeSyntheticsContainer()->Delete(ConstString(type_name.GetName()));
}
#endif // LLDB_DISABLE_PYTHON
bool
SBTypeCategory::GetDescription (lldb::SBStream &description,
lldb::DescriptionLevel description_level)
{
if (!IsValid())
return false;
description.Printf("Category name: %s\n",GetName());
return true;
}
lldb::SBTypeCategory &
SBTypeCategory::operator = (const lldb::SBTypeCategory &rhs)
{
if (this != &rhs)
{
m_opaque_sp = rhs.m_opaque_sp;
}
return *this;
}
bool
SBTypeCategory::operator == (lldb::SBTypeCategory &rhs)
{
if (IsValid() == false)
return !rhs.IsValid();
return m_opaque_sp.get() == rhs.m_opaque_sp.get();
}
bool
SBTypeCategory::operator != (lldb::SBTypeCategory &rhs)
{
if (IsValid() == false)
return rhs.IsValid();
return m_opaque_sp.get() != rhs.m_opaque_sp.get();
}
lldb::TypeCategoryImplSP
SBTypeCategory::GetSP ()
{
if (!IsValid())
return lldb::TypeCategoryImplSP();
return m_opaque_sp;
}
void
SBTypeCategory::SetSP (const lldb::TypeCategoryImplSP &typecategory_impl_sp)
{
m_opaque_sp = typecategory_impl_sp;
}
SBTypeCategory::SBTypeCategory (const lldb::TypeCategoryImplSP &typecategory_impl_sp) :
m_opaque_sp(typecategory_impl_sp)
{
}
bool
SBTypeCategory::IsDefaultCategory()
{
if (!IsValid())
return false;
return (strcmp(m_opaque_sp->GetName(),"default") == 0);
}