YAML I/O add support for validate()

MappingTrait template specializations can now have a validate() method which 
performs semantic checking. For details, see <http://llvm.org/docs/YamlIO.html>.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195286 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Kledzik
2013-11-21 00:28:07 +00:00
parent 25f01786ea
commit 9fd7416b3b
3 changed files with 132 additions and 7 deletions

View File

@@ -44,6 +44,8 @@ template<class T>
struct MappingTraits {
// Must provide:
// static void mapping(IO &io, T &fields);
// Optionally may provide:
// static StringRef validate(IO &io, T &fields);
};
@@ -226,6 +228,23 @@ public:
static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
};
// Test if MappingTraits<T>::validate() is defined on type T.
template <class T>
struct has_MappingValidateTraits
{
typedef StringRef (*Signature_validate)(class IO&, T&);
template <typename U>
static char test(SameType<Signature_validate, &U::validate>*);
template <typename U>
static double test(...);
public:
static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
};
// Test if SequenceTraits<T> is defined on type T.
template <class T>
@@ -309,7 +328,15 @@ struct missingTraits : public llvm::integral_constant<bool,
&& !has_SequenceTraits<T>::value
&& !has_DocumentListTraits<T>::value > {};
template<typename T>
struct validatedMappingTraits : public llvm::integral_constant<bool,
has_MappingTraits<T>::value
&& has_MappingValidateTraits<T>::value> {};
template<typename T>
struct unvalidatedMappingTraits : public llvm::integral_constant<bool,
has_MappingTraits<T>::value
&& !has_MappingValidateTraits<T>::value> {};
// Base class for Input and Output.
class IO {
public:
@@ -483,7 +510,27 @@ yamlize(IO &io, T &Val, bool) {
template<typename T>
typename llvm::enable_if_c<has_MappingTraits<T>::value, void>::type
typename llvm::enable_if_c<validatedMappingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
io.beginMapping();
if (io.outputting()) {
StringRef Err = MappingTraits<T>::validate(io, Val);
if (!Err.empty()) {
llvm::errs() << Err << "\n";
assert(Err.empty() && "invalid struct trying to be written as yaml");
}
}
MappingTraits<T>::mapping(io, Val);
if (!io.outputting()) {
StringRef Err = MappingTraits<T>::validate(io, Val);
if (!Err.empty())
io.setError(Err);
}
io.endMapping();
}
template<typename T>
typename llvm::enable_if_c<unvalidatedMappingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
io.beginMapping();
MappingTraits<T>::mapping(io, Val);