blob: 30414bd728cbab869713432547303f3f4b84ce2e [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/API/SBTypeCategory.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTypeFilter.h"
#include "lldb/API/SBTypeFormat.h"
#include "lldb/API/SBTypeNameSpecifier.h"
#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBTypeSynthetic.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();
}
lldb::LanguageType SBTypeCategory::GetLanguageAtIndex(uint32_t idx) {
if (IsValid())
return m_opaque_sp->GetLanguageAtIndex(idx);
return lldb::eLanguageTypeUnknown;
}
uint32_t SBTypeCategory::GetNumLanguages() {
if (IsValid())
return m_opaque_sp->GetNumLanguages();
return 0;
}
void SBTypeCategory::AddLanguage(lldb::LanguageType language) {
if (IsValid())
m_opaque_sp->AddLanguage(language);
}
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::TypeFilterImplSP 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(
llvm::StringRef::withNullAsEmpty(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()) {
const void *name_token =
(const 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(
llvm::StringRef::withNullAsEmpty(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(
llvm::StringRef::withNullAsEmpty(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()) {
const void *name_token =
(const 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(
llvm::StringRef::withNullAsEmpty(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);
}