Introduce the notion of a "type validator" formatter

Type Validators have the purpose of looking at a ValueObject, and making sure that there is nothing semantically wrong about the object's contents
For instance, if you have a class that represents a speed, the validator might trigger if the speed value is greater than the speed of light

This first patch hooks up the moving parts in the formatters subsystem, but does not link ValueObjects to TypeValidators, nor lets the SB API be exposed to validators
It also lacks the notion of Python validators

llvm-svn: 217277
This commit is contained in:
Enrico Granata 2014-09-05 20:45:07 +00:00
parent afe6794bc2
commit c582713ce6
16 changed files with 724 additions and 13 deletions

View File

@ -72,6 +72,13 @@ public:
lldb::DynamicValueType use_dynamic);
#endif
static lldb::TypeValidatorImplSP
GetValidator (ValueObject& valobj,
lldb::DynamicValueType use_dynamic);
static lldb::TypeValidatorImplSP
GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp);
static bool
AnyMatches(ConstString type_name,
TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,

View File

@ -31,16 +31,19 @@ private:
bool m_format_cached : 1;
bool m_summary_cached : 1;
bool m_synthetic_cached : 1;
bool m_validator_cached : 1;
lldb::TypeFormatImplSP m_format_sp;
lldb::TypeSummaryImplSP m_summary_sp;
lldb::SyntheticChildrenSP m_synthetic_sp;
lldb::TypeValidatorImplSP m_validator_sp;
public:
Entry ();
Entry (lldb::TypeFormatImplSP);
Entry (lldb::TypeSummaryImplSP);
Entry (lldb::SyntheticChildrenSP);
Entry (lldb::TypeFormatImplSP,lldb::TypeSummaryImplSP,lldb::SyntheticChildrenSP);
Entry (lldb::TypeValidatorImplSP);
Entry (lldb::TypeFormatImplSP,lldb::TypeSummaryImplSP,lldb::SyntheticChildrenSP,lldb::TypeValidatorImplSP);
bool
IsFormatCached ();
@ -51,6 +54,9 @@ private:
bool
IsSyntheticCached ();
bool
IsValidatorCached ();
lldb::TypeFormatImplSP
GetFormat ();
@ -60,6 +66,9 @@ private:
lldb::SyntheticChildrenSP
GetSynthetic ();
lldb::TypeValidatorImplSP
GetValidator ();
void
SetFormat (lldb::TypeFormatImplSP);
@ -68,6 +77,9 @@ private:
void
SetSynthetic (lldb::SyntheticChildrenSP);
void
SetValidator (lldb::TypeValidatorImplSP);
};
typedef std::map<ConstString,Entry> CacheMap;
CacheMap m_map;
@ -91,6 +103,9 @@ public:
bool
GetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp);
bool
GetValidator (const ConstString& type,lldb::TypeValidatorImplSP& summary_sp);
void
SetFormat (const ConstString& type,lldb::TypeFormatImplSP& format_sp);
@ -100,6 +115,9 @@ public:
void
SetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp);
void
SetValidator (const ConstString& type,lldb::TypeValidatorImplSP& synthetic_sp);
void
Clear ();

View File

@ -148,6 +148,9 @@ public:
GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
#endif
lldb::TypeValidatorImplSP
GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp);
lldb::TypeFormatImplSP
GetFormat (ValueObject& valobj,
lldb::DynamicValueType use_dynamic);
@ -162,6 +165,10 @@ public:
lldb::DynamicValueType use_dynamic);
#endif
lldb::TypeValidatorImplSP
GetValidator (ValueObject& valobj,
lldb::DynamicValueType use_dynamic);
bool
AnyMatches (ConstString type_name,
TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
@ -272,6 +279,7 @@ private:
HardcodedFormatterFinders<TypeFormatImpl> m_hardcoded_formats;
HardcodedFormatterFinders<TypeSummaryImpl> m_hardcoded_summaries;
HardcodedFormatterFinders<SyntheticChildren> m_hardcoded_synthetics;
HardcodedFormatterFinders<TypeValidatorImpl> m_hardcoded_validators;
lldb::TypeFormatImplSP
GetHardcodedFormat (ValueObject&,lldb::DynamicValueType);
@ -282,6 +290,9 @@ private:
lldb::SyntheticChildrenSP
GetHardcodedSyntheticChildren (ValueObject&,lldb::DynamicValueType);
lldb::TypeValidatorImplSP
GetHardcodedValidator (ValueObject&,lldb::DynamicValueType);
TypeCategoryMap&
GetCategories ()
{

View File

@ -29,6 +29,7 @@
#include "lldb/DataFormatters/TypeFormat.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/DataFormatters/TypeSynthetic.h"
#include "lldb/DataFormatters/TypeValidator.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTType.h"

View File

@ -71,6 +71,7 @@ namespace lldb_private {
typedef FormatterContainerPair<TypeFormatImpl> FormatContainer;
typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer;
typedef FormatterContainerPair<TypeFilterImpl> FilterContainer;
typedef FormatterContainerPair<TypeValidatorImpl> ValidatorContainer;
#ifndef LLDB_DISABLE_PYTHON
typedef FormatterContainerPair<ScriptedSyntheticChildren> SynthContainer;
@ -94,6 +95,9 @@ namespace lldb_private {
typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP;
#endif // #ifndef LLDB_DISABLE_PYTHON
typedef ValidatorContainer::ExactMatchContainerSP ValidatorContainerSP;
typedef ValidatorContainer::RegexMatchContainerSP RegexValidatorContainerSP;
TypeCategoryImpl (IFormatChangeListener* clist,
ConstString name);
@ -147,6 +151,9 @@ namespace lldb_private {
GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
#endif
ValidatorContainer::MapValueType
GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp);
lldb::TypeNameSpecifierImplSP
GetTypeNameSpecifierForFormatAtIndex (size_t index);
@ -183,9 +190,26 @@ namespace lldb_private {
lldb::TypeNameSpecifierImplSP
GetTypeNameSpecifierForSyntheticAtIndex (size_t index);
#endif // #ifndef LLDB_DISABLE_PYTHON
ValidatorContainerSP
GetTypeValidatorsContainer ()
{
return m_validator_cont.GetExactMatch();
}
RegexValidatorContainerSP
GetRegexTypeValidatorsContainer ()
{
return m_validator_cont.GetRegexMatch();
}
ValidatorContainer::MapValueType
GetValidatorAtIndex (size_t index);
lldb::TypeNameSpecifierImplSP
GetTypeNameSpecifierForValidatorAtIndex (size_t index);
bool
IsEnabled () const
{
@ -219,6 +243,12 @@ namespace lldb_private {
lldb::SyntheticChildrenSP& entry,
uint32_t* reason = NULL);
bool
Get (ValueObject& valobj,
const FormattersMatchVector& candidates,
lldb::TypeValidatorImplSP& entry,
uint32_t* reason = NULL);
void
Clear (FormatCategoryItems items = ALL_ITEM_TYPES);
@ -246,14 +276,12 @@ namespace lldb_private {
private:
FormatContainer m_format_cont;
SummaryContainer m_summary_cont;
FilterContainer m_filter_cont;
#ifndef LLDB_DISABLE_PYTHON
SynthContainer m_synth_cont;
#endif // #ifndef LLDB_DISABLE_PYTHON
ValidatorContainer m_validator_cont;
bool m_enabled;
@ -289,6 +317,9 @@ namespace lldb_private {
friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>;
friend class FormattersContainer<lldb::RegularExpressionSP, ScriptedSyntheticChildren>;
#endif // #ifndef LLDB_DISABLE_PYTHON
friend class FormattersContainer<ConstString, TypeValidatorImpl>;
friend class FormattersContainer<lldb::RegularExpressionSP, TypeValidatorImpl>;
};
} // namespace lldb_private

View File

@ -108,6 +108,10 @@ namespace lldb_private {
lldb::DynamicValueType use_dynamic);
#endif
lldb::TypeValidatorImplSP
GetValidator (ValueObject& valobj,
lldb::DynamicValueType use_dynamic);
private:
class delete_matching_categories

View File

@ -0,0 +1,282 @@
//===-- TypeValidator.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef lldb_TypeValidator_h_
#define lldb_TypeValidator_h_
// C Includes
// C++ Includes
#include <string>
#include <functional>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/lldb-enumerations.h"
namespace lldb_private {
class TypeValidatorImpl
{
public:
class Flags
{
public:
Flags () :
m_flags (lldb::eTypeOptionCascade)
{}
Flags (const Flags& other) :
m_flags (other.m_flags)
{}
Flags (uint32_t value) :
m_flags (value)
{}
Flags&
operator = (const Flags& rhs)
{
if (&rhs != this)
m_flags = rhs.m_flags;
return *this;
}
Flags&
operator = (const uint32_t& rhs)
{
m_flags = rhs;
return *this;
}
Flags&
Clear()
{
m_flags = 0;
return *this;
}
bool
GetCascades () const
{
return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
}
Flags&
SetCascades (bool value = true)
{
if (value)
m_flags |= lldb::eTypeOptionCascade;
else
m_flags &= ~lldb::eTypeOptionCascade;
return *this;
}
bool
GetSkipPointers () const
{
return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
}
Flags&
SetSkipPointers (bool value = true)
{
if (value)
m_flags |= lldb::eTypeOptionSkipPointers;
else
m_flags &= ~lldb::eTypeOptionSkipPointers;
return *this;
}
bool
GetSkipReferences () const
{
return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
}
Flags&
SetSkipReferences (bool value = true)
{
if (value)
m_flags |= lldb::eTypeOptionSkipReferences;
else
m_flags &= ~lldb::eTypeOptionSkipReferences;
return *this;
}
uint32_t
GetValue ()
{
return m_flags;
}
void
SetValue (uint32_t value)
{
m_flags = value;
}
private:
uint32_t m_flags;
};
TypeValidatorImpl (const Flags& flags = Flags());
typedef std::shared_ptr<TypeValidatorImpl> SharedPointer;
typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeValidatorImplSP&);
virtual ~TypeValidatorImpl ();
bool
Cascades () const
{
return m_flags.GetCascades();
}
bool
SkipsPointers () const
{
return m_flags.GetSkipPointers();
}
bool
SkipsReferences () const
{
return m_flags.GetSkipReferences();
}
void
SetCascades (bool value)
{
m_flags.SetCascades(value);
}
void
SetSkipsPointers (bool value)
{
m_flags.SetSkipPointers(value);
}
void
SetSkipsReferences (bool value)
{
m_flags.SetSkipReferences(value);
}
uint32_t
GetOptions ()
{
return m_flags.GetValue();
}
void
SetOptions (uint32_t value)
{
m_flags.SetValue(value);
}
uint32_t&
GetRevision ()
{
return m_my_revision;
}
enum class Type
{
eTypeUnknown,
eTypeCXX
};
struct ValidationResult {
enum class ResultType {
eSuccess,
eFailure
} m_result;
std::string m_message;
};
virtual Type
GetType ()
{
return Type::eTypeUnknown;
}
// we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
// extended periods of time and we trust the ValueObject to stay around for as long as it is required
// for us to generate its value
virtual ValidationResult
FormatObject (ValueObject *valobj) const = 0;
virtual std::string
GetDescription() = 0;
static ValidationResult
Success ();
static ValidationResult
Failure (std::string message);
protected:
Flags m_flags;
uint32_t m_my_revision;
private:
DISALLOW_COPY_AND_ASSIGN(TypeValidatorImpl);
};
class TypeValidatorImpl_CXX : public TypeValidatorImpl
{
public:
typedef std::function<TypeValidatorImpl::ValidationResult(ValueObject* valobj)> ValidatorFunction;
TypeValidatorImpl_CXX (ValidatorFunction f, std::string d, const TypeValidatorImpl::Flags& flags = Flags());
typedef std::shared_ptr<TypeValidatorImpl_CXX> SharedPointer;
typedef bool(*ValueCallback)(void*, ConstString, const TypeValidatorImpl_CXX::SharedPointer&);
virtual ~TypeValidatorImpl_CXX ();
ValidatorFunction
GetValidatorFunction () const
{
return m_validator_function;
}
void
SetValidatorFunction (ValidatorFunction f)
{
m_validator_function = f;
}
virtual TypeValidatorImpl::Type
GetType ()
{
return TypeValidatorImpl::Type::eTypeCXX;
}
virtual ValidationResult
FormatObject (ValueObject *valobj) const;
virtual std::string
GetDescription();
protected:
std::string m_description;
ValidatorFunction m_validator_function;
private:
DISALLOW_COPY_AND_ASSIGN(TypeValidatorImpl_CXX);
};
} // namespace lldb_private
#endif // lldb_TypeValidator_h_

View File

@ -248,8 +248,10 @@ class TypeListImpl;
class TypeMemberImpl;
class TypeEnumMemberImpl;
class TypeEnumMemberListImpl;
class TypeFormatImpl;
class TypeNameSpecifierImpl;
class TypePair;
class TypeValidatorImpl;
class UUID;
class UnixSignals;
class Unwind;
@ -258,7 +260,6 @@ class UnwindPlan;
class UnwindTable;
class VMRange;
class Value;
class TypeFormatImpl;
class ValueList;
class ValueObject;
class ValueObjectChild;
@ -394,6 +395,7 @@ namespace lldb {
typedef std::shared_ptr<lldb_private::TypeFormatImpl> TypeFormatImplSP;
typedef std::shared_ptr<lldb_private::TypeNameSpecifierImpl> TypeNameSpecifierImplSP;
typedef std::shared_ptr<lldb_private::TypeSummaryImpl> TypeSummaryImplSP;
typedef std::shared_ptr<lldb_private::TypeValidatorImpl> TypeValidatorImplSP;
#ifndef LLDB_DISABLE_PYTHON
typedef std::shared_ptr<lldb_private::ScriptedSyntheticChildren> ScriptedSyntheticChildrenSP;
#endif

View File

@ -163,7 +163,9 @@ typedef enum FormatCategoryItem
eFormatCategoryItemSynth = 0x0010,
eFormatCategoryItemRegexSynth = 0x0020,
eFormatCategoryItemValue = 0x0040,
eFormatCategoryItemRegexValue = 0x0080
eFormatCategoryItemRegexValue = 0x0080,
eFormatCategoryItemValidator = 0x0100,
eFormatCategoryItemRegexValidator = 0x0200
} FormatCategoryItem;
//------------------------------------------------------------------

View File

@ -662,6 +662,7 @@
94CB257116B0A4270059775D /* TypeSummary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256E16B0A4260059775D /* TypeSummary.cpp */; };
94CB257216B0A4270059775D /* TypeSynthetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256F16B0A4270059775D /* TypeSynthetic.cpp */; };
94CB257416B1D3880059775D /* FormatCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB257316B1D3870059775D /* FormatCache.cpp */; };
94CD131A19BA33B400DB7BED /* TypeValidator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD131919BA33B400DB7BED /* TypeValidator.cpp */; };
94CD704D16F8DDEA00CF1E42 /* CF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704B16F8DDEA00CF1E42 /* CF.cpp */; };
94CD704E16F8DDEA00CF1E42 /* Cocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */; };
94CD705016F8DF1C00CF1E42 /* LibCxxList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */; };
@ -1975,6 +1976,8 @@
94CB256F16B0A4270059775D /* TypeSynthetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSynthetic.cpp; path = source/DataFormatters/TypeSynthetic.cpp; sourceTree = "<group>"; };
94CB257316B1D3870059775D /* FormatCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatCache.cpp; path = source/DataFormatters/FormatCache.cpp; sourceTree = "<group>"; };
94CB257516B1D3910059775D /* FormatCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatCache.h; path = include/lldb/DataFormatters/FormatCache.h; sourceTree = "<group>"; };
94CD131819BA33A100DB7BED /* TypeValidator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeValidator.h; path = include/lldb/DataFormatters/TypeValidator.h; sourceTree = "<group>"; };
94CD131919BA33B400DB7BED /* TypeValidator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeValidator.cpp; path = source/DataFormatters/TypeValidator.cpp; sourceTree = "<group>"; };
94CD704B16F8DDEA00CF1E42 /* CF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CF.cpp; path = source/DataFormatters/CF.cpp; sourceTree = "<group>"; };
94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Cocoa.cpp; path = source/DataFormatters/Cocoa.cpp; sourceTree = "<group>"; };
94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxList.cpp; path = source/DataFormatters/LibCxxList.cpp; sourceTree = "<group>"; };
@ -4188,6 +4191,8 @@
94CB256E16B0A4260059775D /* TypeSummary.cpp */,
94CB256C16B0A4040059775D /* TypeSynthetic.h */,
94CB256F16B0A4270059775D /* TypeSynthetic.cpp */,
94CD131819BA33A100DB7BED /* TypeValidator.h */,
94CD131919BA33B400DB7BED /* TypeValidator.cpp */,
945215DD17F639E600521C0B /* ValueObjectPrinter.h */,
945215DE17F639EE00521C0B /* ValueObjectPrinter.cpp */,
);
@ -5134,6 +5139,7 @@
AF45FDE518A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp in Sources */,
26D5E15F135BAEA2006EA0A7 /* OptionGroupArchitecture.cpp in Sources */,
26D5E163135BB054006EA0A7 /* OptionGroupPlatform.cpp in Sources */,
94CD131A19BA33B400DB7BED /* TypeValidator.cpp in Sources */,
26BD407F135D2AE000237D80 /* FileLineResolver.cpp in Sources */,
26A7A035135E6E4200FB369E /* OptionValue.cpp in Sources */,
9A22A161135E30370024DDC3 /* EmulateInstructionARM.cpp in Sources */,

View File

@ -101,6 +101,18 @@ DataVisualization::GetSyntheticForType (lldb::TypeNameSpecifierImplSP 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,

View File

@ -25,16 +25,20 @@ 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_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_synthetic_sp(),
m_validator_sp()
{
SetFormat (format_sp);
}
@ -42,8 +46,10 @@ m_synthetic_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_synthetic_sp(),
m_validator_sp()
{
SetSummary (summary_sp);
}
@ -51,17 +57,31 @@ m_synthetic_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_summary_sp(),
m_validator_sp()
{
SetSynthetic (synthetic_sp);
}
FormatCache::Entry::Entry (lldb::TypeFormatImplSP format_sp, lldb::TypeSummaryImplSP summary_sp, lldb::SyntheticChildrenSP 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
@ -82,6 +102,12 @@ FormatCache::Entry::IsSyntheticCached ()
return m_synthetic_cached;
}
bool
FormatCache::Entry::IsValidatorCached ()
{
return m_validator_cached;
}
lldb::TypeFormatImplSP
FormatCache::Entry::GetFormat ()
{
@ -100,6 +126,12 @@ FormatCache::Entry::GetSynthetic ()
return m_synthetic_sp;
}
lldb::TypeValidatorImplSP
FormatCache::Entry::GetValidator ()
{
return m_validator_sp;
}
void
FormatCache::Entry::SetFormat (lldb::TypeFormatImplSP format_sp)
{
@ -121,6 +153,13 @@ FormatCache::Entry::SetSynthetic (lldb::SyntheticChildrenSP synthetic_sp)
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 (Mutex::eMutexTypeRecursive)
@ -201,6 +240,26 @@ FormatCache::GetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& sy
return false;
}
bool
FormatCache::GetValidator (const ConstString& type,lldb::TypeValidatorImplSP& validator_sp)
{
Mutex::Locker lock(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)
{
@ -222,6 +281,13 @@ FormatCache::SetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& sy
GetEntry(type).SetSynthetic(synthetic_sp);
}
void
FormatCache::SetValidator (const ConstString& type,lldb::TypeValidatorImplSP& validator_sp)
{
Mutex::Locker lock(m_mutex);
GetEntry(type).SetValidator(validator_sp);
}
void
FormatCache::Clear ()
{

View File

@ -447,6 +447,32 @@ FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_s
}
#endif
lldb::TypeValidatorImplSP
FormatManager::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
{
if (!type_sp)
return lldb::TypeValidatorImplSP();
lldb::TypeValidatorImplSP validator_chosen_sp;
uint32_t num_categories = m_categories_map.GetCount();
lldb::TypeCategoryImplSP category_sp;
uint32_t prio_category = UINT32_MAX;
for (uint32_t category_id = 0;
category_id < num_categories;
category_id++)
{
category_sp = GetCategoryAtIndex(category_id);
if (category_sp->IsEnabled() == false)
continue;
lldb::TypeValidatorImplSP validator_current_sp(category_sp->GetValidatorForType(type_sp).get());
if (validator_current_sp && (validator_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
{
prio_category = category_sp->GetEnabledPosition();
validator_chosen_sp = validator_current_sp;
}
}
return validator_chosen_sp;
}
lldb::TypeCategoryImplSP
FormatManager::GetCategory (const ConstString& category_name,
bool can_create)
@ -756,6 +782,63 @@ FormatManager::GetSyntheticChildren (ValueObject& valobj,
}
#endif
lldb::TypeValidatorImplSP
FormatManager::GetValidator (ValueObject& valobj,
lldb::DynamicValueType use_dynamic)
{
TypeValidatorImplSP retval;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
if (valobj_type)
{
if (log)
log->Printf("\n\n[FormatManager::GetValidator] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
if (m_format_cache.GetValidator(valobj_type,retval))
{
if (log)
{
log->Printf("[FormatManager::GetValidator] Cache search success. Returning.");
if (log->GetDebug())
log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
}
return retval;
}
if (log)
log->Printf("[FormatManager::GetValidator] Cache search failed. Going normal route");
}
retval = m_categories_map.GetValidator(valobj, use_dynamic);
if (!retval)
{
if (log)
log->Printf("[FormatManager::GetValidator] Search failed. Giving hardcoded a chance.");
retval = GetHardcodedValidator(valobj, use_dynamic);
}
else if (valobj_type)
{
if (log)
log->Printf("[FormatManager::GetValidator] Caching %p for type %s",
static_cast<void*>(retval.get()),
valobj_type.AsCString("<invalid>"));
m_format_cache.SetValidator(valobj_type,retval);
}
if (log && log->GetDebug())
log->Printf("[FormatManager::GetValidator] Cache hits: %" PRIu64 " - Cache Misses: %" PRIu64, m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
return retval;
}
lldb::TypeValidatorImplSP
FormatManager::GetHardcodedValidator (ValueObject& valobj,
lldb::DynamicValueType use_dynamic)
{
for (const auto& candidate: m_hardcoded_validators)
{
auto result = candidate(valobj,use_dynamic,*this);
if (result)
return result;
}
return nullptr;
}
FormatManager::FormatManager() :
m_format_cache(),
m_named_summaries_map(this),
@ -773,7 +856,8 @@ FormatManager::FormatManager() :
m_appkit_category_name(ConstString("AppKit")),
m_hardcoded_formats(),
m_hardcoded_summaries(),
m_hardcoded_synthetics()
m_hardcoded_synthetics(),
m_hardcoded_validators()
{
LoadSystemFormatters();
@ -1475,4 +1559,7 @@ FormatManager::LoadHardcodedFormatters()
{
// insert code to load synthetics here
}
{
// insert code to load validators here
}
}

View File

@ -27,6 +27,7 @@ m_filter_cont("filter","regex-filter",clist),
#ifndef LLDB_DISABLE_PYTHON
m_synth_cont("synth","regex-synth",clist),
#endif
m_validator_cont("validator","regex-validator",clist),
m_enabled(false),
m_change_listener(clist),
m_mutex(Mutex::eMutexTypeRecursive),
@ -129,6 +130,22 @@ TypeCategoryImpl::Get (ValueObject& valobj,
return false;
}
bool
TypeCategoryImpl::Get (ValueObject& valobj,
const FormattersMatchVector& candidates,
lldb::TypeValidatorImplSP& entry,
uint32_t* reason)
{
if (!IsEnabled())
return false;
if (GetTypeValidatorsContainer()->Get(candidates, entry, reason))
return true;
bool regex = GetRegexTypeValidatorsContainer()->Get(candidates, entry, reason);
if (regex && reason)
*reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
return regex;
}
void
TypeCategoryImpl::Clear (FormatCategoryItems items)
{
@ -153,6 +170,11 @@ TypeCategoryImpl::Clear (FormatCategoryItems items)
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
GetRegexTypeSyntheticsContainer()->Clear();
#endif
if ( (items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator )
GetTypeValidatorsContainer()->Clear();
if ( (items & eFormatCategoryItemRegexValidator) == eFormatCategoryItemRegexValidator )
GetRegexTypeValidatorsContainer()->Clear();
}
bool
@ -182,6 +204,12 @@ TypeCategoryImpl::Delete (ConstString name,
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
success = GetRegexTypeSyntheticsContainer()->Delete(name) || success;
#endif
if ( (items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator )
success = GetTypeValidatorsContainer()->Delete(name) || success;
if ( (items & eFormatCategoryItemRegexValidator) == eFormatCategoryItemRegexValidator )
success = GetRegexTypeValidatorsContainer()->Delete(name) || success;
return success;
}
@ -211,6 +239,12 @@ TypeCategoryImpl::GetCount (FormatCategoryItems items)
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
count += GetRegexTypeSyntheticsContainer()->GetCount();
#endif
if ( (items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator )
count += GetTypeValidatorsContainer()->GetCount();
if ( (items & eFormatCategoryItemRegexValidator) == eFormatCategoryItemRegexValidator )
count += GetRegexTypeValidatorsContainer()->GetCount();
return count;
}
@ -230,6 +264,7 @@ TypeCategoryImpl::AnyMatches(ConstString type_name,
#ifndef LLDB_DISABLE_PYTHON
ScriptedSyntheticChildren::SharedPointer synth_sp;
#endif
TypeValidatorImpl::SharedPointer validator_sp;
if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
{
@ -324,6 +359,30 @@ TypeCategoryImpl::AnyMatches(ConstString type_name,
}
}
#endif
if ( (items & eFormatCategoryItemValidator) == eFormatCategoryItemValidator )
{
if (GetTypeValidatorsContainer()->Get(type_name, validator_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemValidator;
return true;
}
}
if ( (items & eFormatCategoryItemRegexValidator) == eFormatCategoryItemRegexValidator )
{
if (GetRegexTypeValidatorsContainer()->Get(type_name, validator_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemRegexValidator;
return true;
}
}
return false;
}
@ -393,6 +452,22 @@ TypeCategoryImpl::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
}
#endif
TypeCategoryImpl::ValidatorContainer::MapValueType
TypeCategoryImpl::GetValidatorForType (lldb::TypeNameSpecifierImplSP type_sp)
{
ValidatorContainer::MapValueType retval;
if (type_sp)
{
if (type_sp->IsRegex())
GetRegexTypeValidatorsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
else
GetTypeValidatorsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
}
return retval;
}
lldb::TypeNameSpecifierImplSP
TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex (size_t index)
{
@ -467,6 +542,24 @@ TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex (size_t index)
}
#endif
TypeCategoryImpl::ValidatorContainer::MapValueType
TypeCategoryImpl::GetValidatorAtIndex (size_t index)
{
if (index < GetTypeValidatorsContainer()->GetCount())
return GetTypeValidatorsContainer()->GetAtIndex(index);
else
return GetRegexTypeValidatorsContainer()->GetAtIndex(index-GetTypeValidatorsContainer()->GetCount());
}
lldb::TypeNameSpecifierImplSP
TypeCategoryImpl::GetTypeNameSpecifierForValidatorAtIndex (size_t index)
{
if (index < GetTypeValidatorsContainer()->GetCount())
return GetTypeValidatorsContainer()->GetTypeNameSpecifierAtIndex(index);
else
return GetRegexTypeValidatorsContainer()->GetTypeNameSpecifierAtIndex(index - GetTypeValidatorsContainer()->GetCount());
}
void
TypeCategoryImpl::Enable (bool value, uint32_t position)
{

View File

@ -266,6 +266,34 @@ TypeCategoryMap::GetSyntheticChildren (ValueObject& valobj,
}
#endif
lldb::TypeValidatorImplSP
TypeCategoryMap::GetValidator (ValueObject& valobj,
lldb::DynamicValueType use_dynamic)
{
Mutex::Locker locker(m_map_mutex);
uint32_t reason_why;
ActiveCategoriesIterator begin, end = m_active_categories.end();
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
FormattersMatchVector matches = FormatManager::GetPossibleMatches(valobj, use_dynamic);
for (begin = m_active_categories.begin(); begin != end; begin++)
{
lldb::TypeCategoryImplSP category_sp = *begin;
lldb::TypeValidatorImplSP current_format;
if (log)
log->Printf("\n[CategoryMap::GetValidator] Trying to use category %s", category_sp->GetName());
if (!category_sp->Get(valobj, matches, current_format, &reason_why))
continue;
return current_format;
}
if (log)
log->Printf("[CategoryMap::GetValidator] nothing found - returning empty SP");
return lldb::TypeValidatorImplSP();
}
void
TypeCategoryMap::LoopThrough(CallbackType callback, void* param)
{

View File

@ -0,0 +1,61 @@
//===-- 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"
#import "lldb/Core/StreamString.h"
using namespace lldb;
using namespace lldb_private;
TypeValidatorImpl::ValidationResult
TypeValidatorImpl::Success ()
{
return ValidationResult { ValidationResult::ResultType::eSuccess, "" };
}
TypeValidatorImpl::ValidationResult
TypeValidatorImpl::Failure (std::string message)
{
return ValidationResult { ValidationResult::ResultType::eFailure, message };
}
TypeValidatorImpl_CXX::TypeValidatorImpl_CXX (ValidatorFunction f, std::string d, const TypeValidatorImpl::Flags& flags) :
TypeValidatorImpl(flags),
m_description(d),
m_validator_function(f)
{
}
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();
}