Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,29 @@
add_lldb_library(lldbDataFormatters
CXXFunctionPointer.cpp
DataVisualization.cpp
DumpValueObjectOptions.cpp
FormatCache.cpp
FormatClasses.cpp
FormatManager.cpp
FormattersHelpers.cpp
LanguageCategory.cpp
StringPrinter.cpp
TypeCategory.cpp
TypeCategoryMap.cpp
TypeFormat.cpp
TypeSummary.cpp
TypeSynthetic.cpp
TypeValidator.cpp
ValueObjectPrinter.cpp
VectorType.cpp
LINK_LIBS
lldbCore
lldbInterpreter
lldbSymbol
lldbTarget
lldbUtility
LINK_COMPONENTS
Support
)

View File

@@ -0,0 +1,57 @@
//===-- CXXFunctionPointer.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/DataFormatters/CXXFunctionPointer.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Stream.h"
#include <string>
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
bool lldb_private::formatters::CXXFunctionPointerSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
std::string destination;
StreamString sstr;
AddressType func_ptr_address_type = eAddressTypeInvalid;
addr_t func_ptr_address = valobj.GetPointerValue(&func_ptr_address_type);
if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) {
switch (func_ptr_address_type) {
case eAddressTypeInvalid:
case eAddressTypeFile:
case eAddressTypeHost:
break;
case eAddressTypeLoad: {
ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
Address so_addr;
Target *target = exe_ctx.GetTargetPtr();
if (target && target->GetSectionLoadList().IsEmpty() == false) {
if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address,
so_addr)) {
so_addr.Dump(&sstr, exe_ctx.GetBestExecutionContextScope(),
Address::DumpStyleResolvedDescription,
Address::DumpStyleSectionNameOffset);
}
}
} break;
}
}
if (sstr.GetSize() > 0) {
stream.Printf("(%s)", sstr.GetData());
return true;
} else
return false;
}

View File

@@ -0,0 +1,226 @@
//===-- DataVisualization.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/DataFormatters/DataVisualization.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
using namespace lldb;
using namespace lldb_private;
static FormatManager &GetFormatManager() {
static FormatManager g_format_manager;
return g_format_manager;
}
void DataVisualization::ForceUpdate() { GetFormatManager().Changed(); }
uint32_t DataVisualization::GetCurrentRevision() {
return GetFormatManager().GetCurrentRevision();
}
bool DataVisualization::ShouldPrintAsOneLiner(ValueObject &valobj) {
return GetFormatManager().ShouldPrintAsOneLiner(valobj);
}
lldb::TypeFormatImplSP
DataVisualization::GetFormat(ValueObject &valobj,
lldb::DynamicValueType use_dynamic) {
return GetFormatManager().GetFormat(valobj, use_dynamic);
}
lldb::TypeFormatImplSP
DataVisualization::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) {
return GetFormatManager().GetFormatForType(type_sp);
}
lldb::TypeSummaryImplSP
DataVisualization::GetSummaryFormat(ValueObject &valobj,
lldb::DynamicValueType use_dynamic) {
return GetFormatManager().GetSummaryFormat(valobj, use_dynamic);
}
lldb::TypeSummaryImplSP
DataVisualization::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) {
return GetFormatManager().GetSummaryForType(type_sp);
}
#ifndef LLDB_DISABLE_PYTHON
lldb::SyntheticChildrenSP
DataVisualization::GetSyntheticChildren(ValueObject &valobj,
lldb::DynamicValueType use_dynamic) {
return GetFormatManager().GetSyntheticChildren(valobj, use_dynamic);
}
#endif
#ifndef LLDB_DISABLE_PYTHON
lldb::SyntheticChildrenSP DataVisualization::GetSyntheticChildrenForType(
lldb::TypeNameSpecifierImplSP type_sp) {
return GetFormatManager().GetSyntheticChildrenForType(type_sp);
}
#endif
lldb::TypeFilterImplSP
DataVisualization::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) {
return GetFormatManager().GetFilterForType(type_sp);
}
#ifndef LLDB_DISABLE_PYTHON
lldb::ScriptedSyntheticChildrenSP
DataVisualization::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) {
return GetFormatManager().GetSyntheticForType(type_sp);
}
#endif
lldb::TypeValidatorImplSP
DataVisualization::GetValidator(ValueObject &valobj,
lldb::DynamicValueType use_dynamic) {
return GetFormatManager().GetValidator(valobj, use_dynamic);
}
lldb::TypeValidatorImplSP
DataVisualization::GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp) {
return GetFormatManager().GetValidatorForType(type_sp);
}
bool DataVisualization::AnyMatches(
ConstString type_name, TypeCategoryImpl::FormatCategoryItems items,
bool only_enabled, const char **matching_category,
TypeCategoryImpl::FormatCategoryItems *matching_type) {
return GetFormatManager().AnyMatches(type_name, items, only_enabled,
matching_category, matching_type);
}
bool DataVisualization::Categories::GetCategory(const ConstString &category,
lldb::TypeCategoryImplSP &entry,
bool allow_create) {
entry = GetFormatManager().GetCategory(category, allow_create);
return (entry.get() != NULL);
}
bool DataVisualization::Categories::GetCategory(
lldb::LanguageType language, lldb::TypeCategoryImplSP &entry) {
if (LanguageCategory *lang_category =
GetFormatManager().GetCategoryForLanguage(language))
entry = lang_category->GetCategory();
return (entry.get() != nullptr);
}
void DataVisualization::Categories::Add(const ConstString &category) {
GetFormatManager().GetCategory(category);
}
bool DataVisualization::Categories::Delete(const ConstString &category) {
GetFormatManager().DisableCategory(category);
return GetFormatManager().DeleteCategory(category);
}
void DataVisualization::Categories::Clear() {
GetFormatManager().ClearCategories();
}
void DataVisualization::Categories::Clear(const ConstString &category) {
GetFormatManager().GetCategory(category)->Clear(
eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
}
void DataVisualization::Categories::Enable(const ConstString &category,
TypeCategoryMap::Position pos) {
if (GetFormatManager().GetCategory(category)->IsEnabled())
GetFormatManager().DisableCategory(category);
GetFormatManager().EnableCategory(
category, pos, std::initializer_list<lldb::LanguageType>());
}
void DataVisualization::Categories::Enable(lldb::LanguageType lang_type) {
if (LanguageCategory *lang_category =
GetFormatManager().GetCategoryForLanguage(lang_type))
lang_category->Enable();
}
void DataVisualization::Categories::Disable(const ConstString &category) {
if (GetFormatManager().GetCategory(category)->IsEnabled() == true)
GetFormatManager().DisableCategory(category);
}
void DataVisualization::Categories::Disable(lldb::LanguageType lang_type) {
if (LanguageCategory *lang_category =
GetFormatManager().GetCategoryForLanguage(lang_type))
lang_category->Disable();
}
void DataVisualization::Categories::Enable(
const lldb::TypeCategoryImplSP &category, TypeCategoryMap::Position pos) {
if (category.get()) {
if (category->IsEnabled())
GetFormatManager().DisableCategory(category);
GetFormatManager().EnableCategory(category, pos);
}
}
void DataVisualization::Categories::Disable(
const lldb::TypeCategoryImplSP &category) {
if (category.get() && category->IsEnabled() == true)
GetFormatManager().DisableCategory(category);
}
void DataVisualization::Categories::EnableStar() {
GetFormatManager().EnableAllCategories();
}
void DataVisualization::Categories::DisableStar() {
GetFormatManager().DisableAllCategories();
}
void DataVisualization::Categories::ForEach(
TypeCategoryMap::ForEachCallback callback) {
GetFormatManager().ForEachCategory(callback);
}
uint32_t DataVisualization::Categories::GetCount() {
return GetFormatManager().GetCategoriesCount();
}
lldb::TypeCategoryImplSP
DataVisualization::Categories::GetCategoryAtIndex(size_t index) {
return GetFormatManager().GetCategoryAtIndex(index);
}
bool DataVisualization::NamedSummaryFormats::GetSummaryFormat(
const ConstString &type, lldb::TypeSummaryImplSP &entry) {
return GetFormatManager().GetNamedSummaryContainer().Get(type, entry);
}
void DataVisualization::NamedSummaryFormats::Add(
const ConstString &type, const lldb::TypeSummaryImplSP &entry) {
GetFormatManager().GetNamedSummaryContainer().Add(
FormatManager::GetValidTypeName(type), entry);
}
bool DataVisualization::NamedSummaryFormats::Delete(const ConstString &type) {
return GetFormatManager().GetNamedSummaryContainer().Delete(type);
}
void DataVisualization::NamedSummaryFormats::Clear() {
GetFormatManager().GetNamedSummaryContainer().Clear();
}
void DataVisualization::NamedSummaryFormats::ForEach(
std::function<bool(ConstString, const lldb::TypeSummaryImplSP &)>
callback) {
GetFormatManager().GetNamedSummaryContainer().ForEach(callback);
}
uint32_t DataVisualization::NamedSummaryFormats::GetCount() {
return GetFormatManager().GetNamedSummaryContainer().GetCount();
}

View File

@@ -0,0 +1,206 @@
//===-- DumpValueObjectOptions.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/DataFormatters/DumpValueObjectOptions.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ValueObject.h"
using namespace lldb;
using namespace lldb_private;
DumpValueObjectOptions::DumpValueObjectOptions()
: m_summary_sp(), m_root_valobj_name(),
m_max_ptr_depth(PointerDepth{PointerDepth::Mode::Default, 0}),
m_decl_printing_helper(), m_pointer_as_array(), m_use_synthetic(true),
m_scope_already_checked(false), m_flat_output(false), m_ignore_cap(false),
m_show_types(false), m_show_location(false), m_use_objc(false),
m_hide_root_type(false), m_hide_name(false), m_hide_value(false),
m_run_validator(false), m_use_type_display_name(true),
m_allow_oneliner_mode(true), m_hide_pointer_value(false),
m_reveal_empty_aggregates(true) {}
DumpValueObjectOptions::DumpValueObjectOptions(ValueObject &valobj)
: DumpValueObjectOptions() {
m_use_dynamic = valobj.GetDynamicValueType();
m_use_synthetic = valobj.IsSynthetic();
m_varformat_language = valobj.GetPreferredDisplayLanguage();
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetMaximumPointerDepth(PointerDepth depth) {
m_max_ptr_depth = depth;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetMaximumDepth(uint32_t depth) {
m_max_depth = depth;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetDeclPrintingHelper(DeclPrintingHelper helper) {
m_decl_printing_helper = helper;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetShowTypes(bool show) {
m_show_types = show;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetShowLocation(bool show) {
m_show_location = show;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetUseObjectiveC(bool use) {
m_use_objc = use;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetShowSummary(bool show) {
if (show == false)
SetOmitSummaryDepth(UINT32_MAX);
else
SetOmitSummaryDepth(0);
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetUseDynamicType(lldb::DynamicValueType dyn) {
m_use_dynamic = dyn;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetUseSyntheticValue(bool use_synthetic) {
m_use_synthetic = use_synthetic;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetScopeChecked(bool check) {
m_scope_already_checked = check;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetFlatOutput(bool flat) {
m_flat_output = flat;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetOmitSummaryDepth(uint32_t depth) {
m_omit_summary_depth = depth;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetIgnoreCap(bool ignore) {
m_ignore_cap = ignore;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetRawDisplay() {
SetUseSyntheticValue(false);
SetOmitSummaryDepth(UINT32_MAX);
SetIgnoreCap(true);
SetHideName(false);
SetHideValue(false);
SetUseTypeDisplayName(false);
SetAllowOnelinerMode(false);
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetFormat(lldb::Format format) {
m_format = format;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetSummary(lldb::TypeSummaryImplSP summary) {
m_summary_sp = summary;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetRootValueObjectName(const char *name) {
if (name)
m_root_valobj_name.assign(name);
else
m_root_valobj_name.clear();
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetHideRootType(bool hide_root_type) {
m_hide_root_type = hide_root_type;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetHideName(bool hide_name) {
m_hide_name = hide_name;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetHideValue(bool hide_value) {
m_hide_value = hide_value;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetHidePointerValue(bool hide) {
m_hide_pointer_value = hide;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetVariableFormatDisplayLanguage(
lldb::LanguageType lang) {
m_varformat_language = lang;
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetRunValidator(bool run) {
m_run_validator = run;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetUseTypeDisplayName(bool dis) {
m_use_type_display_name = dis;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetAllowOnelinerMode(bool oneliner) {
m_allow_oneliner_mode = oneliner;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetRevealEmptyAggregates(bool reveal) {
m_reveal_empty_aggregates = reveal;
return *this;
}
DumpValueObjectOptions &
DumpValueObjectOptions::SetElementCount(uint32_t element_count) {
m_pointer_as_array = PointerAsArraySettings(element_count);
return *this;
}
DumpValueObjectOptions &DumpValueObjectOptions::SetPointerAsArray(
const PointerAsArraySettings &ptr_array) {
m_pointer_as_array = ptr_array;
return *this;
}

View File

@@ -0,0 +1,224 @@
//===-- FormatCache.cpp ------------------------------------------*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/FormatCache.h"
using namespace lldb;
using namespace lldb_private;
FormatCache::Entry::Entry()
: m_format_cached(false), m_summary_cached(false),
m_synthetic_cached(false), m_validator_cached(false), m_format_sp(),
m_summary_sp(), m_synthetic_sp(), m_validator_sp() {}
FormatCache::Entry::Entry(lldb::TypeFormatImplSP format_sp)
: m_summary_cached(false), m_synthetic_cached(false),
m_validator_cached(false), m_summary_sp(), m_synthetic_sp(),
m_validator_sp() {
SetFormat(format_sp);
}
FormatCache::Entry::Entry(lldb::TypeSummaryImplSP summary_sp)
: m_format_cached(false), m_synthetic_cached(false),
m_validator_cached(false), m_format_sp(), m_synthetic_sp(),
m_validator_sp() {
SetSummary(summary_sp);
}
FormatCache::Entry::Entry(lldb::SyntheticChildrenSP synthetic_sp)
: m_format_cached(false), m_summary_cached(false),
m_validator_cached(false), m_format_sp(), m_summary_sp(),
m_validator_sp() {
SetSynthetic(synthetic_sp);
}
FormatCache::Entry::Entry(lldb::TypeValidatorImplSP validator_sp)
: m_format_cached(false), m_summary_cached(false),
m_synthetic_cached(false), m_format_sp(), m_summary_sp(),
m_synthetic_sp() {
SetValidator(validator_sp);
}
FormatCache::Entry::Entry(lldb::TypeFormatImplSP format_sp,
lldb::TypeSummaryImplSP summary_sp,
lldb::SyntheticChildrenSP synthetic_sp,
lldb::TypeValidatorImplSP validator_sp) {
SetFormat(format_sp);
SetSummary(summary_sp);
SetSynthetic(synthetic_sp);
SetValidator(validator_sp);
}
bool FormatCache::Entry::IsFormatCached() { return m_format_cached; }
bool FormatCache::Entry::IsSummaryCached() { return m_summary_cached; }
bool FormatCache::Entry::IsSyntheticCached() { return m_synthetic_cached; }
bool FormatCache::Entry::IsValidatorCached() { return m_validator_cached; }
lldb::TypeFormatImplSP FormatCache::Entry::GetFormat() { return m_format_sp; }
lldb::TypeSummaryImplSP FormatCache::Entry::GetSummary() {
return m_summary_sp;
}
lldb::SyntheticChildrenSP FormatCache::Entry::GetSynthetic() {
return m_synthetic_sp;
}
lldb::TypeValidatorImplSP FormatCache::Entry::GetValidator() {
return m_validator_sp;
}
void FormatCache::Entry::SetFormat(lldb::TypeFormatImplSP format_sp) {
m_format_cached = true;
m_format_sp = format_sp;
}
void FormatCache::Entry::SetSummary(lldb::TypeSummaryImplSP summary_sp) {
m_summary_cached = true;
m_summary_sp = summary_sp;
}
void FormatCache::Entry::SetSynthetic(lldb::SyntheticChildrenSP synthetic_sp) {
m_synthetic_cached = true;
m_synthetic_sp = synthetic_sp;
}
void FormatCache::Entry::SetValidator(lldb::TypeValidatorImplSP validator_sp) {
m_validator_cached = true;
m_validator_sp = validator_sp;
}
FormatCache::FormatCache()
: m_map(), m_mutex()
#ifdef LLDB_CONFIGURATION_DEBUG
,
m_cache_hits(0), m_cache_misses(0)
#endif
{
}
FormatCache::Entry &FormatCache::GetEntry(const ConstString &type) {
auto i = m_map.find(type), e = m_map.end();
if (i != e)
return i->second;
m_map[type] = FormatCache::Entry();
return m_map[type];
}
bool FormatCache::GetFormat(const ConstString &type,
lldb::TypeFormatImplSP &format_sp) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
auto entry = GetEntry(type);
if (entry.IsFormatCached()) {
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_hits++;
#endif
format_sp = entry.GetFormat();
return true;
}
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_misses++;
#endif
format_sp.reset();
return false;
}
bool FormatCache::GetSummary(const ConstString &type,
lldb::TypeSummaryImplSP &summary_sp) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
auto entry = GetEntry(type);
if (entry.IsSummaryCached()) {
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_hits++;
#endif
summary_sp = entry.GetSummary();
return true;
}
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_misses++;
#endif
summary_sp.reset();
return false;
}
bool FormatCache::GetSynthetic(const ConstString &type,
lldb::SyntheticChildrenSP &synthetic_sp) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
auto entry = GetEntry(type);
if (entry.IsSyntheticCached()) {
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_hits++;
#endif
synthetic_sp = entry.GetSynthetic();
return true;
}
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_misses++;
#endif
synthetic_sp.reset();
return false;
}
bool FormatCache::GetValidator(const ConstString &type,
lldb::TypeValidatorImplSP &validator_sp) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
auto entry = GetEntry(type);
if (entry.IsValidatorCached()) {
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_hits++;
#endif
validator_sp = entry.GetValidator();
return true;
}
#ifdef LLDB_CONFIGURATION_DEBUG
m_cache_misses++;
#endif
validator_sp.reset();
return false;
}
void FormatCache::SetFormat(const ConstString &type,
lldb::TypeFormatImplSP &format_sp) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
GetEntry(type).SetFormat(format_sp);
}
void FormatCache::SetSummary(const ConstString &type,
lldb::TypeSummaryImplSP &summary_sp) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
GetEntry(type).SetSummary(summary_sp);
}
void FormatCache::SetSynthetic(const ConstString &type,
lldb::SyntheticChildrenSP &synthetic_sp) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
GetEntry(type).SetSynthetic(synthetic_sp);
}
void FormatCache::SetValidator(const ConstString &type,
lldb::TypeValidatorImplSP &validator_sp) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
GetEntry(type).SetValidator(validator_sp);
}
void FormatCache::Clear() {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
m_map.clear();
}

View File

@@ -0,0 +1,54 @@
//===-- FormatClasses.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/DataFormatters/FormatClasses.h"
#include "lldb/DataFormatters/FormatManager.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
using namespace lldb;
using namespace lldb_private;
FormattersMatchData::FormattersMatchData(ValueObject &valobj,
lldb::DynamicValueType use_dynamic)
: m_valobj(valobj), m_dynamic_value_type(use_dynamic),
m_formatters_match_vector({}, false), m_type_for_cache(),
m_candidate_languages() {
m_type_for_cache = FormatManager::GetTypeForCache(valobj, use_dynamic);
m_candidate_languages = FormatManager::GetCandidateLanguages(valobj);
}
FormattersMatchVector FormattersMatchData::GetMatchesVector() {
if (!m_formatters_match_vector.second) {
m_formatters_match_vector.second = true;
m_formatters_match_vector.first =
FormatManager::GetPossibleMatches(m_valobj, m_dynamic_value_type);
}
return m_formatters_match_vector.first;
}
ConstString FormattersMatchData::GetTypeForCache() { return m_type_for_cache; }
CandidateLanguagesVector FormattersMatchData::GetCandidateLanguages() {
return m_candidate_languages;
}
ValueObject &FormattersMatchData::GetValueObject() { return m_valobj; }
lldb::DynamicValueType FormattersMatchData::GetDynamicValueType() {
return m_dynamic_value_type;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
//===-- FormattersHelpers.cpp -------------------------------------*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/RegularExpression.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
void lldb_private::formatters::AddFormat(
TypeCategoryImpl::SharedPointer category_sp, lldb::Format format,
ConstString type_name, TypeFormatImpl::Flags flags, bool regex) {
lldb::TypeFormatImplSP format_sp(new TypeFormatImpl_Format(format, flags));
if (regex)
category_sp->GetRegexTypeFormatsContainer()->Add(
RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
format_sp);
else
category_sp->GetTypeFormatsContainer()->Add(type_name, format_sp);
}
void lldb_private::formatters::AddSummary(
TypeCategoryImpl::SharedPointer category_sp, TypeSummaryImplSP summary_sp,
ConstString type_name, bool regex) {
if (regex)
category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
summary_sp);
else
category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
}
void lldb_private::formatters::AddStringSummary(
TypeCategoryImpl::SharedPointer category_sp, const char *string,
ConstString type_name, TypeSummaryImpl::Flags flags, bool regex) {
lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags, string));
if (regex)
category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
summary_sp);
else
category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
}
void lldb_private::formatters::AddOneLineSummary(
TypeCategoryImpl::SharedPointer category_sp, ConstString type_name,
TypeSummaryImpl::Flags flags, bool regex) {
flags.SetShowMembersOneLiner(true);
lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags, ""));
if (regex)
category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
summary_sp);
else
category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
}
#ifndef LLDB_DISABLE_PYTHON
void lldb_private::formatters::AddCXXSummary(
TypeCategoryImpl::SharedPointer category_sp,
CXXFunctionSummaryFormat::Callback funct, const char *description,
ConstString type_name, TypeSummaryImpl::Flags flags, bool regex) {
lldb::TypeSummaryImplSP summary_sp(
new CXXFunctionSummaryFormat(flags, funct, description));
if (regex)
category_sp->GetRegexTypeSummariesContainer()->Add(
RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
summary_sp);
else
category_sp->GetTypeSummariesContainer()->Add(type_name, summary_sp);
}
void lldb_private::formatters::AddCXXSynthetic(
TypeCategoryImpl::SharedPointer category_sp,
CXXSyntheticChildren::CreateFrontEndCallback generator,
const char *description, ConstString type_name,
ScriptedSyntheticChildren::Flags flags, bool regex) {
lldb::SyntheticChildrenSP synth_sp(
new CXXSyntheticChildren(flags, description, generator));
if (regex)
category_sp->GetRegexTypeSyntheticsContainer()->Add(
RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
synth_sp);
else
category_sp->GetTypeSyntheticsContainer()->Add(type_name, synth_sp);
}
void lldb_private::formatters::AddFilter(
TypeCategoryImpl::SharedPointer category_sp,
std::vector<std::string> children, const char *description,
ConstString type_name, ScriptedSyntheticChildren::Flags flags, bool regex) {
TypeFilterImplSP filter_sp(new TypeFilterImpl(flags));
for (auto child : children)
filter_sp->AddExpressionPath(child);
if (regex)
category_sp->GetRegexTypeFiltersContainer()->Add(
RegularExpressionSP(new RegularExpression(type_name.GetStringRef())),
filter_sp);
else
category_sp->GetTypeFiltersContainer()->Add(type_name, filter_sp);
}
#endif
size_t lldb_private::formatters::ExtractIndexFromString(const char *item_name) {
if (!item_name || !*item_name)
return UINT32_MAX;
if (*item_name != '[')
return UINT32_MAX;
item_name++;
char *endptr = NULL;
unsigned long int idx = ::strtoul(item_name, &endptr, 0);
if (idx == 0 && endptr == item_name)
return UINT32_MAX;
if (idx == ULONG_MAX)
return UINT32_MAX;
return idx;
}
lldb::addr_t
lldb_private::formatters::GetArrayAddressOrPointerValue(ValueObject &valobj) {
lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
if (valobj.IsPointerType())
data_addr = valobj.GetValueAsUnsigned(0);
else if (valobj.IsArrayType())
data_addr = valobj.GetAddressOf();
return data_addr;
}

View File

@@ -0,0 +1,232 @@
//===-- LanguageCategory.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/DataFormatters/LanguageCategory.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/DataFormatters/TypeCategory.h"
#include "lldb/DataFormatters/TypeFormat.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/DataFormatters/TypeSynthetic.h"
#include "lldb/DataFormatters/TypeValidator.h"
#include "lldb/Target/Language.h"
using namespace lldb;
using namespace lldb_private;
LanguageCategory::LanguageCategory(lldb::LanguageType lang_type)
: m_category_sp(), m_hardcoded_formats(), m_hardcoded_summaries(),
m_hardcoded_synthetics(), m_hardcoded_validators(), m_format_cache(),
m_enabled(false) {
if (Language *language_plugin = Language::FindPlugin(lang_type)) {
m_category_sp = language_plugin->GetFormatters();
m_hardcoded_formats = language_plugin->GetHardcodedFormats();
m_hardcoded_summaries = language_plugin->GetHardcodedSummaries();
m_hardcoded_synthetics = language_plugin->GetHardcodedSynthetics();
m_hardcoded_validators = language_plugin->GetHardcodedValidators();
}
Enable();
}
bool LanguageCategory::Get(FormattersMatchData &match_data,
lldb::TypeFormatImplSP &format_sp) {
if (!m_category_sp)
return false;
if (!IsEnabled())
return false;
if (match_data.GetTypeForCache()) {
if (m_format_cache.GetFormat(match_data.GetTypeForCache(), format_sp))
return format_sp.get() != nullptr;
}
ValueObject &valobj(match_data.GetValueObject());
bool result =
m_category_sp->Get(valobj, match_data.GetMatchesVector(), format_sp);
if (match_data.GetTypeForCache() &&
(!format_sp || !format_sp->NonCacheable())) {
m_format_cache.SetFormat(match_data.GetTypeForCache(), format_sp);
}
return result;
}
bool LanguageCategory::Get(FormattersMatchData &match_data,
lldb::TypeSummaryImplSP &format_sp) {
if (!m_category_sp)
return false;
if (!IsEnabled())
return false;
if (match_data.GetTypeForCache()) {
if (m_format_cache.GetSummary(match_data.GetTypeForCache(), format_sp))
return format_sp.get() != nullptr;
}
ValueObject &valobj(match_data.GetValueObject());
bool result =
m_category_sp->Get(valobj, match_data.GetMatchesVector(), format_sp);
if (match_data.GetTypeForCache() &&
(!format_sp || !format_sp->NonCacheable())) {
m_format_cache.SetSummary(match_data.GetTypeForCache(), format_sp);
}
return result;
}
bool LanguageCategory::Get(FormattersMatchData &match_data,
lldb::SyntheticChildrenSP &format_sp) {
if (!m_category_sp)
return false;
if (!IsEnabled())
return false;
if (match_data.GetTypeForCache()) {
if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(), format_sp))
return format_sp.get() != nullptr;
}
ValueObject &valobj(match_data.GetValueObject());
bool result =
m_category_sp->Get(valobj, match_data.GetMatchesVector(), format_sp);
if (match_data.GetTypeForCache() &&
(!format_sp || !format_sp->NonCacheable())) {
m_format_cache.SetSynthetic(match_data.GetTypeForCache(), format_sp);
}
return result;
}
bool LanguageCategory::Get(FormattersMatchData &match_data,
lldb::TypeValidatorImplSP &format_sp) {
if (!m_category_sp)
return false;
if (!IsEnabled())
return false;
if (match_data.GetTypeForCache()) {
if (m_format_cache.GetValidator(match_data.GetTypeForCache(), format_sp))
return format_sp.get() != nullptr;
}
ValueObject &valobj(match_data.GetValueObject());
bool result =
m_category_sp->Get(valobj, match_data.GetMatchesVector(), format_sp);
if (match_data.GetTypeForCache() &&
(!format_sp || !format_sp->NonCacheable())) {
m_format_cache.SetValidator(match_data.GetTypeForCache(), format_sp);
}
return result;
}
bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
FormattersMatchData &match_data,
lldb::TypeFormatImplSP &format_sp) {
if (!IsEnabled())
return false;
ValueObject &valobj(match_data.GetValueObject());
lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());
for (auto &candidate : m_hardcoded_formats) {
if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
break;
}
if (match_data.GetTypeForCache() &&
(!format_sp || !format_sp->NonCacheable())) {
m_format_cache.SetFormat(match_data.GetTypeForCache(), format_sp);
}
return format_sp.get() != nullptr;
}
bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
FormattersMatchData &match_data,
lldb::TypeSummaryImplSP &format_sp) {
if (!IsEnabled())
return false;
ValueObject &valobj(match_data.GetValueObject());
lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());
for (auto &candidate : m_hardcoded_summaries) {
if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
break;
}
if (match_data.GetTypeForCache() &&
(!format_sp || !format_sp->NonCacheable())) {
m_format_cache.SetSummary(match_data.GetTypeForCache(), format_sp);
}
return format_sp.get() != nullptr;
}
bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
FormattersMatchData &match_data,
lldb::SyntheticChildrenSP &format_sp) {
if (!IsEnabled())
return false;
ValueObject &valobj(match_data.GetValueObject());
lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());
for (auto &candidate : m_hardcoded_synthetics) {
if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
break;
}
if (match_data.GetTypeForCache() &&
(!format_sp || !format_sp->NonCacheable())) {
m_format_cache.SetSynthetic(match_data.GetTypeForCache(), format_sp);
}
return format_sp.get() != nullptr;
}
bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
FormattersMatchData &match_data,
lldb::TypeValidatorImplSP &format_sp) {
if (!IsEnabled())
return false;
ValueObject &valobj(match_data.GetValueObject());
lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());
for (auto &candidate : m_hardcoded_validators) {
if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
break;
}
if (match_data.GetTypeForCache() &&
(!format_sp || !format_sp->NonCacheable())) {
m_format_cache.SetValidator(match_data.GetTypeForCache(), format_sp);
}
return format_sp.get() != nullptr;
}
lldb::TypeCategoryImplSP LanguageCategory::GetCategory() const {
return m_category_sp;
}
FormatCache &LanguageCategory::GetFormatCache() { return m_format_cache; }
void LanguageCategory::Enable() {
if (m_category_sp)
m_category_sp->Enable(true, TypeCategoryMap::Default);
m_enabled = true;
}
void LanguageCategory::Disable() {
if (m_category_sp)
m_category_sp->Disable();
m_enabled = false;
}
bool LanguageCategory::IsEnabled() { return m_enabled; }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,382 @@
//===-- TypeCategoryMap.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/DataFormatters/TypeCategoryMap.h"
#include "lldb/DataFormatters/FormatClasses.h"
#include "lldb/Utility/Log.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
using namespace lldb;
using namespace lldb_private;
TypeCategoryMap::TypeCategoryMap(IFormatChangeListener *lst)
: m_map_mutex(), listener(lst), m_map(), m_active_categories() {
ConstString default_cs("default");
lldb::TypeCategoryImplSP default_sp =
lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
Add(default_cs, default_sp);
Enable(default_cs, First);
}
void TypeCategoryMap::Add(KeyType name, const ValueSP &entry) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
m_map[name] = entry;
if (listener)
listener->Changed();
}
bool TypeCategoryMap::Delete(KeyType name) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
MapIterator iter = m_map.find(name);
if (iter == m_map.end())
return false;
m_map.erase(name);
Disable(name);
if (listener)
listener->Changed();
return true;
}
bool TypeCategoryMap::Enable(KeyType category_name, Position pos) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
ValueSP category;
if (!Get(category_name, category))
return false;
return Enable(category, pos);
}
bool TypeCategoryMap::Disable(KeyType category_name) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
ValueSP category;
if (!Get(category_name, category))
return false;
return Disable(category);
}
bool TypeCategoryMap::Enable(ValueSP category, Position pos) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
if (category.get()) {
Position pos_w = pos;
if (pos == First || m_active_categories.size() == 0)
m_active_categories.push_front(category);
else if (pos == Last || pos == m_active_categories.size())
m_active_categories.push_back(category);
else if (pos < m_active_categories.size()) {
ActiveCategoriesList::iterator iter = m_active_categories.begin();
while (pos_w) {
pos_w--, iter++;
}
m_active_categories.insert(iter, category);
} else
return false;
category->Enable(true, pos);
return true;
}
return false;
}
bool TypeCategoryMap::Disable(ValueSP category) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
if (category.get()) {
m_active_categories.remove_if(delete_matching_categories(category));
category->Disable();
return true;
}
return false;
}
void TypeCategoryMap::EnableAllCategories() {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
std::vector<ValueSP> sorted_categories(m_map.size(), ValueSP());
MapType::iterator iter = m_map.begin(), end = m_map.end();
for (; iter != end; ++iter) {
if (iter->second->IsEnabled())
continue;
auto pos = iter->second->GetLastEnabledPosition();
if (pos >= sorted_categories.size()) {
auto iter = std::find_if(
sorted_categories.begin(), sorted_categories.end(),
[](const ValueSP &sp) -> bool { return sp.get() == nullptr; });
pos = std::distance(sorted_categories.begin(), iter);
}
sorted_categories.at(pos) = iter->second;
}
decltype(sorted_categories)::iterator viter = sorted_categories.begin(),
vend = sorted_categories.end();
for (; viter != vend; viter++)
if (viter->get())
Enable(*viter, Last);
}
void TypeCategoryMap::DisableAllCategories() {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
Position p = First;
for (; false == m_active_categories.empty(); p++) {
m_active_categories.front()->SetEnabledPosition(p);
Disable(m_active_categories.front());
}
}
void TypeCategoryMap::Clear() {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
m_map.clear();
m_active_categories.clear();
if (listener)
listener->Changed();
}
bool TypeCategoryMap::Get(KeyType name, ValueSP &entry) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
MapIterator iter = m_map.find(name);
if (iter == m_map.end())
return false;
entry = iter->second;
return true;
}
bool TypeCategoryMap::Get(uint32_t pos, ValueSP &entry) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
MapIterator iter = m_map.begin();
MapIterator end = m_map.end();
while (pos > 0) {
iter++;
pos--;
if (iter == end)
return false;
}
entry = iter->second;
return false;
}
bool TypeCategoryMap::AnyMatches(
ConstString type_name, TypeCategoryImpl::FormatCategoryItems items,
bool only_enabled, const char **matching_category,
TypeCategoryImpl::FormatCategoryItems *matching_type) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
MapIterator pos, end = m_map.end();
for (pos = m_map.begin(); pos != end; pos++) {
if (pos->second->AnyMatches(type_name, items, only_enabled,
matching_category, matching_type))
return true;
}
return false;
}
lldb::TypeFormatImplSP
TypeCategoryMap::GetFormat(FormattersMatchData &match_data) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
if (log) {
for (auto match : match_data.GetMatchesVector()) {
log->Printf(
"[CategoryMap::GetFormat] candidate match = %s %s %s %s reason = "
"%" PRIu32,
match.GetTypeName().GetCString(),
match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
match.DidStripReference() ? "strip-reference" : "no-strip-reference",
match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
match.GetReason());
}
}
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::TypeFormatImplSP current_format;
if (log)
log->Printf("[TypeCategoryMap::GetFormat] Trying to use category %s",
category_sp->GetName());
if (!category_sp->Get(match_data.GetValueObject(),
match_data.GetMatchesVector(), current_format,
&reason_why))
continue;
return current_format;
}
if (log)
log->Printf(
"[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
return lldb::TypeFormatImplSP();
}
lldb::TypeSummaryImplSP
TypeCategoryMap::GetSummaryFormat(FormattersMatchData &match_data) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
if (log) {
for (auto match : match_data.GetMatchesVector()) {
log->Printf(
"[CategoryMap::GetSummaryFormat] candidate match = %s %s %s %s "
"reason = %" PRIu32,
match.GetTypeName().GetCString(),
match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
match.DidStripReference() ? "strip-reference" : "no-strip-reference",
match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
match.GetReason());
}
}
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::TypeSummaryImplSP current_format;
if (log)
log->Printf("[CategoryMap::GetSummaryFormat] Trying to use category %s",
category_sp->GetName());
if (!category_sp->Get(match_data.GetValueObject(),
match_data.GetMatchesVector(), current_format,
&reason_why))
continue;
return current_format;
}
if (log)
log->Printf(
"[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
return lldb::TypeSummaryImplSP();
}
#ifndef LLDB_DISABLE_PYTHON
lldb::SyntheticChildrenSP
TypeCategoryMap::GetSyntheticChildren(FormattersMatchData &match_data) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
if (log) {
for (auto match : match_data.GetMatchesVector()) {
log->Printf(
"[CategoryMap::GetSyntheticChildren] candidate match = %s %s %s %s "
"reason = %" PRIu32,
match.GetTypeName().GetCString(),
match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
match.DidStripReference() ? "strip-reference" : "no-strip-reference",
match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
match.GetReason());
}
}
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::SyntheticChildrenSP current_format;
if (log)
log->Printf(
"[CategoryMap::GetSyntheticChildren] Trying to use category %s",
category_sp->GetName());
if (!category_sp->Get(match_data.GetValueObject(),
match_data.GetMatchesVector(), current_format,
&reason_why))
continue;
return current_format;
}
if (log)
log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning "
"empty SP");
return lldb::SyntheticChildrenSP();
}
#endif
lldb::TypeValidatorImplSP
TypeCategoryMap::GetValidator(FormattersMatchData &match_data) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
if (log) {
for (auto match : match_data.GetMatchesVector()) {
log->Printf(
"[CategoryMap::GetValidator] candidate match = %s %s %s %s reason = "
"%" PRIu32,
match.GetTypeName().GetCString(),
match.DidStripPointer() ? "strip-pointers" : "no-strip-pointers",
match.DidStripReference() ? "strip-reference" : "no-strip-reference",
match.DidStripTypedef() ? "strip-typedef" : "no-strip-typedef",
match.GetReason());
}
}
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::TypeValidatorImplSP current_format;
if (log)
log->Printf("[CategoryMap::GetValidator] Trying to use category %s",
category_sp->GetName());
if (!category_sp->Get(match_data.GetValueObject(),
match_data.GetMatchesVector(), current_format,
&reason_why))
continue;
return current_format;
}
if (log)
log->Printf(
"[CategoryMap::GetValidator] nothing found - returning empty SP");
return lldb::TypeValidatorImplSP();
}
void TypeCategoryMap::ForEach(ForEachCallback callback) {
if (callback) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
// loop through enabled categories in respective order
{
ActiveCategoriesIterator begin, end = m_active_categories.end();
for (begin = m_active_categories.begin(); begin != end; begin++) {
lldb::TypeCategoryImplSP category = *begin;
if (!callback(category))
break;
}
}
// loop through disabled categories in just any order
{
MapIterator pos, end = m_map.end();
for (pos = m_map.begin(); pos != end; pos++) {
if (pos->second->IsEnabled())
continue;
if (!callback(pos->second))
break;
}
}
}
}
TypeCategoryImplSP TypeCategoryMap::GetAtIndex(uint32_t index) {
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
if (index < m_map.size()) {
MapIterator pos, end = m_map.end();
for (pos = m_map.begin(); pos != end; pos++) {
if (index == 0)
return pos->second;
index--;
}
}
return TypeCategoryImplSP();
}

View File

@@ -0,0 +1,209 @@
//===-- TypeFormat.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/DataFormatters/TypeFormat.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"
using namespace lldb;
using namespace lldb_private;
TypeFormatImpl::TypeFormatImpl(const Flags &flags)
: m_flags(flags), m_my_revision(0) {}
TypeFormatImpl::~TypeFormatImpl() {}
TypeFormatImpl_Format::TypeFormatImpl_Format(lldb::Format f,
const TypeFormatImpl::Flags &flags)
: TypeFormatImpl(flags), m_format(f) {}
TypeFormatImpl_Format::~TypeFormatImpl_Format() {}
bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj,
std::string &dest) const {
if (!valobj)
return false;
if (valobj->CanProvideValue()) {
Value &value(valobj->GetValue());
const Value::ContextType context_type = value.GetContextType();
ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
DataExtractor data;
if (context_type == Value::eContextTypeRegisterInfo) {
const RegisterInfo *reg_info = value.GetRegisterInfo();
if (reg_info) {
Status error;
valobj->GetData(data, error);
if (error.Fail())
return false;
StreamString reg_sstr;
DumpDataExtractor(data, &reg_sstr, 0, GetFormat(), reg_info->byte_size,
1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0,
exe_ctx.GetBestExecutionContextScope());
dest = reg_sstr.GetString();
}
} else {
CompilerType compiler_type = value.GetCompilerType();
if (compiler_type) {
// put custom bytes to display in the DataExtractor to override the
// default value logic
if (GetFormat() == eFormatCString) {
lldb_private::Flags type_flags(compiler_type.GetTypeInfo(
NULL)); // disambiguate w.r.t. TypeFormatImpl::Flags
if (type_flags.Test(eTypeIsPointer) &&
!type_flags.Test(eTypeIsObjC)) {
// if we are dumping a pointer as a c-string, get the pointee data
// as a string
TargetSP target_sp(valobj->GetTargetSP());
if (target_sp) {
size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
Status error;
DataBufferSP buffer_sp(new DataBufferHeap(max_len + 1, 0));
Address address(valobj->GetPointerValue());
if (target_sp->ReadCStringFromMemory(
address, (char *)buffer_sp->GetBytes(), max_len, error) &&
error.Success())
data.SetData(buffer_sp);
}
}
} else {
Status error;
valobj->GetData(data, error);
if (error.Fail())
return false;
}
StreamString sstr;
ExecutionContextScope *exe_scope(
exe_ctx.GetBestExecutionContextScope());
compiler_type.DumpTypeValue(
&sstr, // The stream to use for display
GetFormat(), // Format to display this type with
data, // Data to extract from
0, // Byte offset into "m_data"
compiler_type.GetByteSize(
exe_scope), // Byte size of item in "m_data"
valobj->GetBitfieldBitSize(), // Bitfield bit size
valobj->GetBitfieldBitOffset(), // Bitfield bit offset
exe_scope);
// Given that we do not want to set the ValueObject's m_error
// for a formatting error (or else we wouldn't be able to reformat
// until a next update), an empty string is treated as a "false"
// return from here, but that's about as severe as we get
// CompilerType::DumpTypeValue() should always return
// something, even if that something is an error message
dest = sstr.GetString();
}
}
return !dest.empty();
} else
return false;
}
std::string TypeFormatImpl_Format::GetDescription() {
StreamString sstr;
sstr.Printf("%s%s%s%s", FormatManager::GetFormatAsCString(GetFormat()),
Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "");
return sstr.GetString();
}
TypeFormatImpl_EnumType::TypeFormatImpl_EnumType(
ConstString type_name, const TypeFormatImpl::Flags &flags)
: TypeFormatImpl(flags), m_enum_type(type_name), m_types() {}
TypeFormatImpl_EnumType::~TypeFormatImpl_EnumType() {}
bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj,
std::string &dest) const {
dest.clear();
if (!valobj)
return false;
if (!valobj->CanProvideValue())
return false;
ProcessSP process_sp;
TargetSP target_sp;
void *valobj_key = (process_sp = valobj->GetProcessSP()).get();
if (!valobj_key)
valobj_key = (target_sp = valobj->GetTargetSP()).get();
else
target_sp = process_sp->GetTarget().shared_from_this();
if (!valobj_key)
return false;
auto iter = m_types.find(valobj_key), end = m_types.end();
CompilerType valobj_enum_type;
if (iter == end) {
// probably a redundant check
if (!target_sp)
return false;
const ModuleList &images(target_sp->GetImages());
SymbolContext sc;
TypeList types;
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
images.FindTypes(sc, m_enum_type, false, UINT32_MAX, searched_symbol_files,
types);
if (types.GetSize() == 0)
return false;
for (lldb::TypeSP type_sp : types.Types()) {
if (!type_sp)
continue;
if ((type_sp->GetForwardCompilerType().GetTypeInfo() &
eTypeIsEnumeration) == eTypeIsEnumeration) {
valobj_enum_type = type_sp->GetFullCompilerType();
m_types.emplace(valobj_key, valobj_enum_type);
break;
}
}
} else
valobj_enum_type = iter->second;
if (valobj_enum_type.IsValid() == false)
return false;
DataExtractor data;
Status error;
valobj->GetData(data, error);
if (error.Fail())
return false;
ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
StreamString sstr;
valobj_enum_type.DumpTypeValue(&sstr, lldb::eFormatEnum, data, 0,
data.GetByteSize(), 0, 0,
exe_ctx.GetBestExecutionContextScope());
if (!sstr.GetString().empty())
dest = sstr.GetString();
return !dest.empty();
}
std::string TypeFormatImpl_EnumType::GetDescription() {
StreamString sstr;
sstr.Printf("as type %s%s%s%s", m_enum_type.AsCString("<invalid type>"),
Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "");
return sstr.GetString();
}

View File

@@ -0,0 +1,216 @@
//===-- TypeSummary.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/DataFormatters/TypeSummary.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/StreamString.h"
using namespace lldb;
using namespace lldb_private;
TypeSummaryOptions::TypeSummaryOptions()
: m_lang(eLanguageTypeUnknown), m_capping(eTypeSummaryCapped) {}
TypeSummaryOptions::TypeSummaryOptions(const TypeSummaryOptions &rhs)
: m_lang(rhs.m_lang), m_capping(rhs.m_capping) {}
TypeSummaryOptions &TypeSummaryOptions::
operator=(const TypeSummaryOptions &rhs) {
m_lang = rhs.m_lang;
m_capping = rhs.m_capping;
return *this;
}
lldb::LanguageType TypeSummaryOptions::GetLanguage() const { return m_lang; }
lldb::TypeSummaryCapping TypeSummaryOptions::GetCapping() const {
return m_capping;
}
TypeSummaryOptions &TypeSummaryOptions::SetLanguage(lldb::LanguageType lang) {
m_lang = lang;
return *this;
}
TypeSummaryOptions &
TypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping cap) {
m_capping = cap;
return *this;
}
TypeSummaryImpl::TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags)
: m_flags(flags), m_kind(kind) {}
StringSummaryFormat::StringSummaryFormat(const TypeSummaryImpl::Flags &flags,
const char *format_cstr)
: TypeSummaryImpl(Kind::eSummaryString, flags), m_format_str() {
SetSummaryString(format_cstr);
}
void StringSummaryFormat::SetSummaryString(const char *format_cstr) {
m_format.Clear();
if (format_cstr && format_cstr[0]) {
m_format_str = format_cstr;
m_error = FormatEntity::Parse(format_cstr, m_format);
} else {
m_format_str.clear();
m_error.Clear();
}
}
bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
const TypeSummaryOptions &options) {
if (!valobj) {
retval.assign("NULL ValueObject");
return false;
}
StreamString s;
ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
SymbolContext sc;
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame)
sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
if (IsOneLiner()) {
ValueObjectPrinter printer(valobj, &s, DumpValueObjectOptions());
printer.PrintChildrenOneLiner(HideNames(valobj));
retval = s.GetString();
return true;
} else {
if (FormatEntity::Format(m_format, s, &sc, &exe_ctx,
&sc.line_entry.range.GetBaseAddress(), valobj,
false, false)) {
retval.assign(s.GetString());
return true;
} else {
retval.assign("error: summary string parsing error");
return false;
}
}
}
std::string StringSummaryFormat::GetDescription() {
StreamString sstr;
sstr.Printf("`%s`%s%s%s%s%s%s%s%s%s", m_format_str.c_str(),
m_error.Fail() ? " error: " : "",
m_error.Fail() ? m_error.AsCString() : "",
Cascades() ? "" : " (not cascading)",
!DoesPrintChildren(nullptr) ? "" : " (show children)",
!DoesPrintValue(nullptr) ? " (hide value)" : "",
IsOneLiner() ? " (one-line printout)" : "",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
HideNames(nullptr) ? " (hide member names)" : "");
return sstr.GetString();
}
CXXFunctionSummaryFormat::CXXFunctionSummaryFormat(
const TypeSummaryImpl::Flags &flags, Callback impl, const char *description)
: TypeSummaryImpl(Kind::eCallback, flags), m_impl(impl),
m_description(description ? description : "") {}
bool CXXFunctionSummaryFormat::FormatObject(ValueObject *valobj,
std::string &dest,
const TypeSummaryOptions &options) {
dest.clear();
StreamString stream;
if (!m_impl || m_impl(*valobj, stream, options) == false)
return false;
dest = stream.GetString();
return true;
}
std::string CXXFunctionSummaryFormat::GetDescription() {
StreamString sstr;
sstr.Printf("%s%s%s%s%s%s%s %s", Cascades() ? "" : " (not cascading)",
!DoesPrintChildren(nullptr) ? "" : " (show children)",
!DoesPrintValue(nullptr) ? " (hide value)" : "",
IsOneLiner() ? " (one-line printout)" : "",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
HideNames(nullptr) ? " (hide member names)" : "",
m_description.c_str());
return sstr.GetString();
}
ScriptSummaryFormat::ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags,
const char *function_name,
const char *python_script)
: TypeSummaryImpl(Kind::eScript, flags), m_function_name(),
m_python_script(), m_script_function_sp() {
if (function_name)
m_function_name.assign(function_name);
if (python_script)
m_python_script.assign(python_script);
}
bool ScriptSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
const TypeSummaryOptions &options) {
if (!valobj)
return false;
TargetSP target_sp(valobj->GetTargetSP());
if (!target_sp) {
retval.assign("error: no target");
return false;
}
ScriptInterpreter *script_interpreter =
target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
if (!script_interpreter) {
retval.assign("error: no ScriptInterpreter");
return false;
}
return script_interpreter->GetScriptedSummary(
m_function_name.c_str(), valobj->GetSP(), m_script_function_sp, options,
retval);
}
std::string ScriptSummaryFormat::GetDescription() {
StreamString sstr;
sstr.Printf("%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)",
!DoesPrintChildren(nullptr) ? "" : " (show children)",
!DoesPrintValue(nullptr) ? " (hide value)" : "",
IsOneLiner() ? " (one-line printout)" : "",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
HideNames(nullptr) ? " (hide member names)" : "");
if (m_python_script.empty()) {
if (m_function_name.empty()) {
sstr.PutCString("no backing script");
} else {
sstr.PutCString(m_function_name);
}
} else {
sstr.PutCString(m_python_script);
}
return sstr.GetString();
}

View File

@@ -0,0 +1,227 @@
//===-- TypeSynthetic.cpp ----------------------------------------*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"
#include "lldb/Core/Debugger.h"
#include "lldb/DataFormatters/TypeSynthetic.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/StreamString.h"
using namespace lldb;
using namespace lldb_private;
void TypeFilterImpl::AddExpressionPath(const std::string &path) {
bool need_add_dot = true;
if (path[0] == '.' || (path[0] == '-' && path[1] == '>') || path[0] == '[')
need_add_dot = false;
// add a '.' symbol to help forgetful users
if (!need_add_dot)
m_expression_paths.push_back(path);
else
m_expression_paths.push_back(std::string(".") + path);
}
bool TypeFilterImpl::SetExpressionPathAtIndex(size_t i,
const std::string &path) {
if (i >= GetCount())
return false;
bool need_add_dot = true;
if (path[0] == '.' || (path[0] == '-' && path[1] == '>') || path[0] == '[')
need_add_dot = false;
// add a '.' symbol to help forgetful users
if (!need_add_dot)
m_expression_paths[i] = path;
else
m_expression_paths[i] = std::string(".") + path;
return true;
}
size_t
TypeFilterImpl::FrontEnd::GetIndexOfChildWithName(const ConstString &name) {
const char *name_cstr = name.GetCString();
if (name_cstr) {
for (size_t i = 0; i < filter->GetCount(); i++) {
const char *expr_cstr = filter->GetExpressionPathAtIndex(i);
if (expr_cstr) {
if (*expr_cstr == '.')
expr_cstr++;
else if (*expr_cstr == '-' && *(expr_cstr + 1) == '>')
expr_cstr += 2;
}
if (expr_cstr) {
if (!::strcmp(name_cstr, expr_cstr))
return i;
}
}
}
return UINT32_MAX;
}
std::string TypeFilterImpl::GetDescription() {
StreamString sstr;
sstr.Printf("%s%s%s {\n", Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "");
for (size_t i = 0; i < GetCount(); i++) {
sstr.Printf(" %s\n", GetExpressionPathAtIndex(i));
}
sstr.Printf("}");
return sstr.GetString();
}
std::string CXXSyntheticChildren::GetDescription() {
StreamString sstr;
sstr.Printf("%s%s%s %s", Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
m_description.c_str());
return sstr.GetString();
}
lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromExpression(
llvm::StringRef name, llvm::StringRef expression,
const ExecutionContext &exe_ctx) {
ValueObjectSP valobj_sp(
ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx));
if (valobj_sp)
valobj_sp->SetSyntheticChildrenGenerated(true);
return valobj_sp;
}
lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromAddress(
llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
CompilerType type) {
ValueObjectSP valobj_sp(
ValueObject::CreateValueObjectFromAddress(name, address, exe_ctx, type));
if (valobj_sp)
valobj_sp->SetSyntheticChildrenGenerated(true);
return valobj_sp;
}
lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromData(
llvm::StringRef name, const DataExtractor &data,
const ExecutionContext &exe_ctx, CompilerType type) {
ValueObjectSP valobj_sp(
ValueObject::CreateValueObjectFromData(name, data, exe_ctx, type));
if (valobj_sp)
valobj_sp->SetSyntheticChildrenGenerated(true);
return valobj_sp;
}
#ifndef LLDB_DISABLE_PYTHON
ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass,
ValueObject &backend)
: SyntheticChildrenFrontEnd(backend), m_python_class(pclass),
m_wrapper_sp(), m_interpreter(NULL) {
if (backend == LLDB_INVALID_UID)
return;
TargetSP target_sp = backend.GetTargetSP();
if (!target_sp)
return;
m_interpreter =
target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
if (m_interpreter != NULL)
m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(
m_python_class.c_str(), backend.GetSP());
}
ScriptedSyntheticChildren::FrontEnd::~FrontEnd() {}
lldb::ValueObjectSP
ScriptedSyntheticChildren::FrontEnd::GetChildAtIndex(size_t idx) {
if (!m_wrapper_sp || !m_interpreter)
return lldb::ValueObjectSP();
return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx);
}
bool ScriptedSyntheticChildren::FrontEnd::IsValid() {
return (m_wrapper_sp && m_wrapper_sp->IsValid() && m_interpreter);
}
size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren() {
if (!m_wrapper_sp || m_interpreter == NULL)
return 0;
return m_interpreter->CalculateNumChildren(m_wrapper_sp, UINT32_MAX);
}
size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren(uint32_t max) {
if (!m_wrapper_sp || m_interpreter == NULL)
return 0;
return m_interpreter->CalculateNumChildren(m_wrapper_sp, max);
}
bool ScriptedSyntheticChildren::FrontEnd::Update() {
if (!m_wrapper_sp || m_interpreter == NULL)
return false;
return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
}
bool ScriptedSyntheticChildren::FrontEnd::MightHaveChildren() {
if (!m_wrapper_sp || m_interpreter == NULL)
return false;
return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
}
size_t ScriptedSyntheticChildren::FrontEnd::GetIndexOfChildWithName(
const ConstString &name) {
if (!m_wrapper_sp || m_interpreter == NULL)
return UINT32_MAX;
return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp,
name.GetCString());
}
lldb::ValueObjectSP ScriptedSyntheticChildren::FrontEnd::GetSyntheticValue() {
if (!m_wrapper_sp || m_interpreter == NULL)
return nullptr;
return m_interpreter->GetSyntheticValue(m_wrapper_sp);
}
ConstString ScriptedSyntheticChildren::FrontEnd::GetSyntheticTypeName() {
if (!m_wrapper_sp || m_interpreter == NULL)
return ConstString();
return m_interpreter->GetSyntheticTypeName(m_wrapper_sp);
}
std::string ScriptedSyntheticChildren::GetDescription() {
StreamString sstr;
sstr.Printf("%s%s%s Python class %s", Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "",
m_python_class.c_str());
return sstr.GetString();
}
#endif // #ifndef LLDB_DISABLE_PYTHON

View File

@@ -0,0 +1,58 @@
//===-- TypeValidator.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/TypeValidator.h"
#include "lldb/Utility/StreamString.h"
using namespace lldb;
using namespace lldb_private;
TypeValidatorImpl::TypeValidatorImpl(const Flags &flags)
: m_flags(flags), m_my_revision(0) {}
TypeValidatorImpl::~TypeValidatorImpl() {}
TypeValidatorImpl::ValidationResult TypeValidatorImpl::Success() {
return ValidationResult{TypeValidatorResult::Success, ""};
}
TypeValidatorImpl::ValidationResult
TypeValidatorImpl::Failure(std::string message) {
return ValidationResult{TypeValidatorResult::Failure, message};
}
TypeValidatorImpl_CXX::TypeValidatorImpl_CXX(
ValidatorFunction f, std::string d, const TypeValidatorImpl::Flags &flags)
: TypeValidatorImpl(flags), m_description(d), m_validator_function(f) {}
TypeValidatorImpl_CXX::~TypeValidatorImpl_CXX() {}
TypeValidatorImpl::ValidationResult
TypeValidatorImpl_CXX::FormatObject(ValueObject *valobj) const {
if (!valobj)
return Success(); // I guess there's nothing wrong with a null valueobject..
return m_validator_function(valobj);
}
std::string TypeValidatorImpl_CXX::GetDescription() {
StreamString sstr;
sstr.Printf("%s%s%s%s", m_description.c_str(),
Cascades() ? "" : " (not cascading)",
SkipsPointers() ? " (skip pointers)" : "",
SkipsReferences() ? " (skip references)" : "");
return sstr.GetString();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,299 @@
//===-- VectorType.cpp ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/VectorType.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
static CompilerType GetCompilerTypeForFormat(lldb::Format format,
CompilerType element_type,
TypeSystem *type_system) {
lldbassert(type_system && "type_system needs to be not NULL");
switch (format) {
case lldb::eFormatAddressInfo:
case lldb::eFormatPointer:
return type_system->GetBuiltinTypeForEncodingAndBitSize(
eEncodingUint, 8 * type_system->GetPointerByteSize());
case lldb::eFormatBoolean:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeBool);
case lldb::eFormatBytes:
case lldb::eFormatBytesWithASCII:
case lldb::eFormatChar:
case lldb::eFormatCharArray:
case lldb::eFormatCharPrintable:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
case lldb::eFormatComplex /* lldb::eFormatComplexFloat */:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloatComplex);
case lldb::eFormatCString:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar)
.GetPointerType();
case lldb::eFormatFloat:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
case lldb::eFormatHex:
case lldb::eFormatHexUppercase:
case lldb::eFormatOctal:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeInt);
case lldb::eFormatHexFloat:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
case lldb::eFormatUnicode16:
case lldb::eFormatUnicode32:
case lldb::eFormatUnsigned:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeUnsignedInt);
case lldb::eFormatVectorOfChar:
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeChar);
case lldb::eFormatVectorOfFloat32:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
32);
case lldb::eFormatVectorOfFloat64:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingIEEE754,
64);
case lldb::eFormatVectorOfSInt16:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 16);
case lldb::eFormatVectorOfSInt32:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
case lldb::eFormatVectorOfSInt64:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);
case lldb::eFormatVectorOfSInt8:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 8);
case lldb::eFormatVectorOfUInt128:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 128);
case lldb::eFormatVectorOfUInt16:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16);
case lldb::eFormatVectorOfUInt32:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
case lldb::eFormatVectorOfUInt64:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64);
case lldb::eFormatVectorOfUInt8:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
case lldb::eFormatDefault:
return element_type;
case lldb::eFormatBinary:
case lldb::eFormatComplexInteger:
case lldb::eFormatDecimal:
case lldb::eFormatEnum:
case lldb::eFormatInstruction:
case lldb::eFormatOSType:
case lldb::eFormatVoid:
default:
return type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8);
}
}
static lldb::Format GetItemFormatForFormat(lldb::Format format,
CompilerType element_type) {
switch (format) {
case lldb::eFormatVectorOfChar:
return lldb::eFormatChar;
case lldb::eFormatVectorOfFloat32:
case lldb::eFormatVectorOfFloat64:
return lldb::eFormatFloat;
case lldb::eFormatVectorOfSInt16:
case lldb::eFormatVectorOfSInt32:
case lldb::eFormatVectorOfSInt64:
case lldb::eFormatVectorOfSInt8:
return lldb::eFormatDecimal;
case lldb::eFormatVectorOfUInt128:
case lldb::eFormatVectorOfUInt16:
case lldb::eFormatVectorOfUInt32:
case lldb::eFormatVectorOfUInt64:
case lldb::eFormatVectorOfUInt8:
return lldb::eFormatUnsigned;
case lldb::eFormatBinary:
case lldb::eFormatComplexInteger:
case lldb::eFormatDecimal:
case lldb::eFormatEnum:
case lldb::eFormatInstruction:
case lldb::eFormatOSType:
case lldb::eFormatVoid:
return eFormatHex;
case lldb::eFormatDefault: {
// special case the (default, char) combination to actually display as an
// integer value
// most often, you won't want to see the ASCII characters... (and if you do,
// eFormatChar is a keystroke away)
bool is_char = element_type.IsCharType();
bool is_signed = false;
element_type.IsIntegerType(is_signed);
return is_char ? (is_signed ? lldb::eFormatDecimal : eFormatHex) : format;
} break;
default:
return format;
}
}
static size_t CalculateNumChildren(
CompilerType container_type, CompilerType element_type,
lldb_private::ExecutionContextScope *exe_scope =
nullptr // does not matter here because all we trade in are basic types
) {
auto container_size = container_type.GetByteSize(exe_scope);
auto element_size = element_type.GetByteSize(exe_scope);
if (element_size) {
if (container_size % element_size)
return 0;
return container_size / element_size;
}
return 0;
}
namespace lldb_private {
namespace formatters {
class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
VectorTypeSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
: SyntheticChildrenFrontEnd(*valobj_sp), m_parent_format(eFormatInvalid),
m_item_format(eFormatInvalid), m_child_type(), m_num_children(0) {}
~VectorTypeSyntheticFrontEnd() override = default;
size_t CalculateNumChildren() override { return m_num_children; }
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
if (idx >= CalculateNumChildren())
return lldb::ValueObjectSP();
auto offset = idx * m_child_type.GetByteSize(nullptr);
StreamString idx_name;
idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset(
offset, m_child_type, true, ConstString(idx_name.GetString())));
if (!child_sp)
return child_sp;
child_sp->SetFormat(m_item_format);
return child_sp;
}
bool Update() override {
m_parent_format = m_backend.GetFormat();
CompilerType parent_type(m_backend.GetCompilerType());
CompilerType element_type;
parent_type.IsVectorType(&element_type, nullptr);
TargetSP target_sp(m_backend.GetTargetSP());
m_child_type = ::GetCompilerTypeForFormat(
m_parent_format, element_type,
target_sp
? target_sp->GetScratchTypeSystemForLanguage(nullptr,
lldb::eLanguageTypeC)
: nullptr);
m_num_children = ::CalculateNumChildren(parent_type, m_child_type);
m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
return false;
}
bool MightHaveChildren() override { return true; }
size_t GetIndexOfChildWithName(const ConstString &name) override {
const char *item_name = name.GetCString();
uint32_t idx = ExtractIndexFromString(item_name);
if (idx < UINT32_MAX && idx >= CalculateNumChildren())
return UINT32_MAX;
return idx;
}
private:
lldb::Format m_parent_format;
lldb::Format m_item_format;
CompilerType m_child_type;
size_t m_num_children;
};
} // namespace formatters
} // namespace lldb_private
bool lldb_private::formatters::VectorTypeSummaryProvider(
ValueObject &valobj, Stream &s, const TypeSummaryOptions &) {
auto synthetic_children =
VectorTypeSyntheticFrontEndCreator(nullptr, valobj.GetSP());
if (!synthetic_children)
return false;
synthetic_children->Update();
s.PutChar('(');
bool first = true;
size_t idx = 0, len = synthetic_children->CalculateNumChildren();
for (; idx < len; idx++) {
auto child_sp = synthetic_children->GetChildAtIndex(idx);
if (!child_sp)
continue;
child_sp = child_sp->GetQualifiedRepresentationIfAvailable(
lldb::eDynamicDontRunTarget, true);
const char *child_value = child_sp->GetValueAsCString();
if (child_value && *child_value) {
if (first) {
s.Printf("%s", child_value);
first = false;
} else {
s.Printf(", %s", child_value);
}
}
}
s.PutChar(')');
return true;
}
lldb_private::SyntheticChildrenFrontEnd *
lldb_private::formatters::VectorTypeSyntheticFrontEndCreator(
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
if (!valobj_sp)
return nullptr;
return new VectorTypeSyntheticFrontEnd(valobj_sp);
}