10 #ifndef LLVM_SUPPORT_YAMLTRAITS_H
11 #define LLVM_SUPPORT_YAMLTRAITS_H
27 #include <system_error>
140 template <
typename T>
190 template <
typename T, T>
194 template <
typename T>
205 template <
typename U>
208 template <
typename U>
209 static double test(...);
213 (
sizeof(test<ScalarEnumerationTraits<T> >(
nullptr)) == 1);
223 template <
typename U>
226 template <
typename U>
227 static double test(...);
230 static bool const value = (
sizeof(test<ScalarBitSetTraits<T> >(
nullptr)) == 1);
242 template <
typename U>
247 template <
typename U>
248 static double test(...);
252 (
sizeof(test<ScalarTraits<T>>(
nullptr,
nullptr,
nullptr)) == 1);
263 template <
typename U>
267 template <
typename U>
268 static double test(...);
272 (
sizeof(test<BlockScalarTraits<T>>(
nullptr,
nullptr)) == 1);
282 template <
typename U>
285 template <
typename U>
286 static double test(...);
289 static bool const value = (
sizeof(test<MappingTraits<T> >(
nullptr)) == 1);
298 template <
typename U>
301 template <
typename U>
302 static double test(...);
305 static bool const value = (
sizeof(test<MappingTraits<T> >(
nullptr)) == 1);
316 template <
typename U>
319 template <
typename U>
320 static double test(...);
323 static bool const value = (
sizeof(test<SequenceTraits<T> >(
nullptr)) == 1);
330 template <typename T, bool Enabled = std::is_class<T>::value>
343 struct Fallback {
bool flow; };
344 struct Derived :
T, Fallback { };
350 static char (&f(...))[2];
353 static bool const value =
sizeof(f<Derived>(
nullptr)) == 2;
361 has_SequenceMethodTraits<T>::value > { };
370 template <
typename U>
373 template <
typename U>
374 static double test(...);
377 static bool const value = (
sizeof(test<DocumentListTraits<T> >(
nullptr))==1);
381 static const char OctalChars[] =
"01234567";
390 static const char HexChars[] =
"0123456789abcdefABCDEF";
395 static const char DecChars[] =
"0123456789";
402 Regex FloatMatcher(
"^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
403 if (FloatMatcher.
match(S))
435 if (isspace(S.
front()) || isspace(S.
back()))
437 if (S.
front() ==
',')
440 static const char ScalarSafeChars[] =
441 "abcdefghijklmnopqrstuvwxyz"
442 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
459 !has_ScalarEnumerationTraits<T>::value
460 && !has_ScalarBitSetTraits<T>::value
461 && !has_ScalarTraits<T>::value
462 && !has_BlockScalarTraits<T>::value
463 && !has_MappingTraits<T>::value
464 && !has_SequenceTraits<T>::value
465 && !has_DocumentListTraits<T>::value > {};
469 has_MappingTraits<T>::value
470 && has_MappingValidateTraits<T>::value> {};
474 has_MappingTraits<T>::value
475 && !has_MappingValidateTraits<T>::value> {};
480 IO(
void *Ctxt=
nullptr);
499 virtual bool preflightKey(
const char*,
bool,
bool,
bool &,
void *&) = 0;
519 template <
typename T>
527 template <
typename T>
528 void enumCase(
T &Val,
const char* Str,
const uint32_t ConstVal) {
534 template <
typename FBT,
typename T>
538 FBT Res = (uint64_t)Val;
544 template <
typename T>
547 Val = Val | ConstVal;
552 template <
typename T>
553 void bitSetCase(
T &Val,
const char* Str,
const uint32_t ConstVal) {
555 Val = Val | ConstVal;
559 template <
typename T>
562 Val = Val | ConstVal;
565 template <
typename T>
569 Val = Val | ConstVal;
575 template <
typename T>
577 this->processKey(Key, Val,
true);
580 template <
typename T>
581 typename std::enable_if<has_SequenceTraits<T>::value,
void>::type
586 this->processKey(Key, Val,
false);
589 template <
typename T>
591 processKeyWithDefault(Key, Val,
Optional<T>(),
false);
594 template <
typename T>
595 typename std::enable_if<!has_SequenceTraits<T>::value,
void>::type
597 this->processKey(Key, Val,
false);
600 template <
typename T>
602 this->processKeyWithDefault(Key, Val, Default,
false);
606 template <
typename T>
607 void processKeyWithDefault(
const char *Key,
Optional<T> &Val,
609 assert(DefaultValue.
hasValue() ==
false &&
610 "Optional<T> shouldn't have a value!");
616 if (this->
preflightKey(Key, Required, sameAsDefault, UseDefault,
626 template <
typename T>
627 void processKeyWithDefault(
const char *Key,
T &Val,
const T& DefaultValue,
631 const bool sameAsDefault =
outputting() && Val == DefaultValue;
632 if ( this->
preflightKey(Key, Required, sameAsDefault, UseDefault,
643 template <
typename T>
644 void processKey(
const char *Key,
T &Val,
bool Required) {
647 if ( this->
preflightKey(Key, Required,
false, UseDefault, SaveInfo) ) {
660 typename std::enable_if<has_ScalarEnumerationTraits<T>::value,
void>::type
668 typename std::enable_if<has_ScalarBitSetTraits<T>::value,
void>::type
673 Val =
static_cast<T>(0);
681 typename std::enable_if<has_ScalarTraits<T>::value,
void>::type
694 if ( !Result.
empty() ) {
700 template <
typename T>
701 typename std::enable_if<has_BlockScalarTraits<T>::value,
void>::type
720 typename std::enable_if<validatedMappingTraits<T>::value,
void>::type
730 assert(Err.
empty() &&
"invalid struct trying to be written as yaml");
746 typename std::enable_if<unvalidatedMappingTraits<T>::value,
void>::type
760 typename std::enable_if<missingTraits<T>::value,
void>::type
766 typename std::enable_if<has_SequenceTraits<T>::value,
void>::type
771 for(
unsigned i=0; i < count; ++i) {
783 for(
unsigned i=0; i < count; ++i) {
890 template <
typename TNorm,
typename TFinal>
893 : io(i_o), BufPtr(nullptr), Result(Obj) {
895 BufPtr =
new (&Buffer) TNorm(io, Obj);
898 BufPtr =
new (&Buffer) TNorm(io);
904 Result = BufPtr->denormalize(io);
924 template <
typename TNorm,
typename TFinal>
927 : io(i_o), BufPtr(NULL), Result(Obj) {
929 BufPtr =
new (&Buffer) TNorm(io, Obj);
932 BufPtr =
new TNorm(io);
941 Result = BufPtr->denormalize(io);
976 void *Ctxt =
nullptr,
978 void *DiagHandlerCtxt =
nullptr);
982 std::error_code
error();
985 bool outputting()
override;
987 void beginMapping()
override;
988 void endMapping()
override;
989 bool preflightKey(
const char *,
bool,
bool,
bool &,
void *&)
override;
990 void postflightKey(
void *)
override;
991 void beginFlowMapping()
override;
992 void endFlowMapping()
override;
993 unsigned beginSequence()
override;
994 void endSequence()
override;
995 bool preflightElement(
unsigned index,
void *&)
override;
996 void postflightElement(
void *)
override;
997 unsigned beginFlowSequence()
override;
998 bool preflightFlowElement(
unsigned ,
void *&)
override;
999 void postflightFlowElement(
void *)
override;
1000 void endFlowSequence()
override;
1001 void beginEnumScalar()
override;
1002 bool matchEnumScalar(
const char*,
bool)
override;
1003 bool matchEnumFallback()
override;
1004 void endEnumScalar()
override;
1005 bool beginBitSetScalar(
bool &)
override;
1006 bool bitSetMatch(
const char *,
bool )
override;
1007 void endBitSetScalar()
override;
1008 void scalarString(
StringRef &,
bool)
override;
1009 void blockScalarString(
StringRef &)
override;
1010 void setError(
const Twine &message)
override;
1011 bool canElideEmptySequence()
override;
1014 virtual void anchor();
1016 HNode(
Node *n) : _node(n) { }
1017 virtual ~HNode() { }
1018 static inline bool classof(
const HNode *) {
return true; }
1023 class EmptyHNode :
public HNode {
1024 void anchor()
override;
1026 EmptyHNode(
Node *n) : HNode(n) { }
1027 static inline bool classof(
const HNode *n) {
1030 static inline bool classof(
const EmptyHNode *) {
return true; }
1033 class ScalarHNode :
public HNode {
1034 void anchor()
override;
1038 StringRef value()
const {
return _value; }
1040 static inline bool classof(
const HNode *n) {
1044 static inline bool classof(
const ScalarHNode *) {
return true; }
1049 class MapHNode :
public HNode {
1050 void anchor()
override;
1053 MapHNode(
Node *n) : HNode(n) { }
1055 static inline bool classof(
const HNode *n) {
1058 static inline bool classof(
const MapHNode *) {
return true; }
1068 class SequenceHNode :
public HNode {
1069 void anchor()
override;
1072 SequenceHNode(
Node *n) : HNode(n) { }
1074 static inline bool classof(
const HNode *n) {
1077 static inline bool classof(
const SequenceHNode *) {
return true; }
1079 std::vector<std::unique_ptr<HNode>> Entries;
1082 std::unique_ptr<Input::HNode> createHNodes(
Node *node);
1083 void setError(HNode *hnode,
const Twine &message);
1084 void setError(
Node *node,
const Twine &message);
1098 std::unique_ptr<llvm::yaml::Stream> Strm;
1099 std::unique_ptr<HNode> TopNode;
1103 std::vector<bool> BitValuesUsed;
1105 bool ScalarMatchFound;
1124 bool preflightKey(
const char *key,
bool,
bool,
bool &,
void *&)
override;
1158 void newLineCheck();
1159 void outputNewLine();
1176 int ColumnAtFlowStart;
1177 int ColumnAtMapFlowStart;
1178 bool NeedBitValueComma;
1179 bool NeedFlowSequenceComma;
1180 bool EnumerationMatchFound;
1195 #define LLVM_YAML_STRONG_TYPEDEF(_base, _type) \
1198 _type(const _base v) : value(v) { } \
1199 _type(const _type &v) : value(v.value) {} \
1200 _type &operator=(const _type &rhs) { value = rhs.value; return *this; }\
1201 _type &operator=(const _base &rhs) { value = rhs; return *this; } \
1202 operator const _base & () const { return value; } \
1203 bool operator==(const _type &rhs) const { return value == rhs.value; } \
1204 bool operator==(const _base &rhs) const { return value == rhs; } \
1205 bool operator<(const _type &rhs) const { return value < rhs.value; } \
1251 template <
typename T>
1253 typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
1267 template <
typename T>
1269 typename std::enable_if<has_MappingTraits<T>::value, Input &>::type
1278 template <
typename T>
1280 typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
1288 template <
typename T>
1290 typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
1298 template <
typename T>
1300 typename std::enable_if<missingTraits<T>::value, Input &>::type
1308 template <
typename T>
1310 typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
1314 for(
size_t i=0; i < count; ++i) {
1325 template <
typename T>
1327 typename std::enable_if<has_MappingTraits<T>::value, Output &>::type
1339 template <
typename T>
1341 typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
1353 template <
typename T>
1355 typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
1367 template <
typename T>
1369 typename std::enable_if<missingTraits<T>::value, Output &>::type
1382 #define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \
1386 struct SequenceTraits< std::vector<_type> > { \
1387 static size_t size(IO &io, std::vector<_type> &seq) { \
1388 return seq.size(); \
1390 static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
1391 if ( index >= seq.size() ) \
1392 seq.resize(index+1); \
1393 return seq[index]; \
1401 #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \
1405 struct SequenceTraits< std::vector<_type> > { \
1406 static size_t size(IO &io, std::vector<_type> &seq) { \
1407 return seq.size(); \
1409 static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
1411 if ( index >= seq.size() ) \
1412 seq.resize(index+1); \
1413 return seq[index]; \
1415 static const bool flow = true; \
1422 #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \
1426 struct DocumentListTraits< std::vector<_type> > { \
1427 static size_t size(IO &io, std::vector<_type> &seq) { \
1428 return seq.size(); \
1430 static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
1431 if ( index >= seq.size() ) \
1432 seq.resize(index+1); \
1433 return seq[index]; \
1441 #endif // LLVM_SUPPORT_YAMLTRAITS_H
static bool classof(const Node *N)
void setError(const Twine &message) override
static char test(SameType< Signature_input,&U::input > *, SameType< Signature_output,&U::output > *)
static bool mustQuote(StringRef)
static char test(SameType< Signature_enumeration,&U::enumeration > *)
void bitSetCase(T &Val, const char *Str, const T ConstVal)
bool preflightElement(unsigned, void *&) override
std::enable_if< has_SequenceTraits< T >::value, void >::type mapOptional(const char *Key, T &Val)
bool preflightDocument(unsigned)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static bool mustQuote(StringRef S)
static bool mustQuote(StringRef)
virtual bool beginBitSetScalar(bool &)=0
void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask)
static char test(SameType< Signature_input,&U::input > *, SameType< Signature_output,&U::output > *, SameType< Signature_mustQuote,&U::mustQuote > *)
virtual bool preflightFlowElement(unsigned, void *&)=0
static bool mustQuote(StringRef)
static char test(SameType< Signature_validate,&U::validate > *)
void beginMapping() override
virtual void endFlowMapping()=0
void(* Signature_enumeration)(class IO &, T &)
virtual void scalarString(StringRef &, bool)=0
void endFlowMapping() override
void endSequence() override
void enumCase(T &Val, const char *Str, const uint32_t ConstVal)
virtual void endEnumScalar()=0
static char test(SameType< Signature_size,&U::size > *)
bool needsQuotes(StringRef S)
MappingNormalizationHeap(IO &i_o, TFinal &Obj)
static bool mustQuote(StringRef)
static bool classof(const Node *N)
std::enable_if< has_ScalarEnumerationTraits< T >::value, void >::type yamlize(IO &io, T &Val, bool)
virtual void setError(const Twine &)=0
virtual bool matchEnumFallback()=0
virtual void postflightElement(void *)=0
virtual unsigned beginSequence()=0
This class should be specialized by any type that needs to be converted to/from a YAML sequence...
void beginFlowMapping() override
static bool mustQuote(StringRef)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void postflightElement(void *) override
void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal, uint32_t Mask)
static bool classof(const Node *N)
bool matchEnumScalar(const char *, bool) override
Output(llvm::raw_ostream &, void *Ctxt=nullptr, int WrapColumn=70)
virtual bool preflightElement(unsigned, void *&)=0
void scalarString(StringRef &, bool) override
bool matchEnumFallback() override
void enumFallback(T &Val)
bool beginBitSetScalar(bool &) override
This class should be specialized by any type that needs to be converted to/from a YAML mapping...
const T & getValue() const LLVM_LVALUE_FUNCTION
bool outputting() override
StringRef(* Signature_input)(StringRef, void *, T &)
std::enable_if<!has_SequenceTraits< T >::value, void >::type mapOptional(const char *Key, T &Val)
void bitSetCase(T &Val, const char *Str, const uint32_t ConstVal)
bool(* Signature_mustQuote)(StringRef)
static bool mustQuote(StringRef)
std::enable_if< has_DocumentListTraits< T >::value, Output & >::type operator<<(Output &yout, T &docList)
virtual bool mapTag(StringRef Tag, bool Default=false)=0
bool mapTag(StringRef, bool) override
static bool classof(const Node *N)
void(* Signature_output)(const T &, void *, llvm::raw_ostream &)
static bool mustQuote(StringRef)
std::enable_if< has_DocumentListTraits< T >::value, Input & >::type operator>>(Input &yin, T &docList)
void endMapping() override
void enumCase(T &Val, const char *Str, const T ConstVal)
virtual void endFlowSequence()=0
void postflightDocument()
void(* Signature_mapping)(class IO &, T &)
size_t(* Signature_size)(class IO &, T &)
Allocate memory in an ever growing pool, as if by bump-pointer.
virtual void beginEnumScalar()=0
void postflightFlowElement(void *) override
This class should be specialized by any type that needs to be converted to/from a list of YAML docume...
static bool mustQuote(StringRef)
char back() const
back - Get the last character in the string.
void(* DiagHandlerTy)(const SMDiagnostic &, void *Context)
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
static bool mustQuote(StringRef)
virtual bool preflightKey(const char *, bool, bool, bool &, void *&)=0
virtual bool canElideEmptySequence()=0
virtual void blockScalarString(StringRef &)=0
virtual void endBitSetScalar()=0
void endFlowSequence() override
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
bool preflightKey(const char *key, bool, bool, bool &, void *&) override
The Output class is used to generate a yaml document from in-memory structs and vectors.
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
virtual void beginMapping()=0
MappingNormalization(IO &i_o, TFinal &Obj)
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
static bool mustQuote(StringRef)
StringRef(* Signature_validate)(class IO &, T &)
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
This class should be specialized by any integral type that converts to/from a YAML scalar where there...
#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)
YAML I/O does conversion based on types.
bool preflightFlowElement(unsigned, void *&) override
virtual bool bitSetMatch(const char *, bool)=0
This class should be specialized by type that requires custom conversion to/from a yaml scalar...
void endBitSetScalar() override
bool bitSetMatch(const char *, bool) override
static bool mustQuote(StringRef)
virtual void postflightKey(void *)=0
static char test(SameType< Signature_mapping,&U::mapping > *)
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
virtual void beginFlowMapping()=0
static bool mustQuote(StringRef S)
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
virtual unsigned beginFlowSequence()=0
unsigned beginFlowSequence() override
static char test(SameType< Signature_bitset,&U::bitset > *)
bool isNumber(StringRef S)
void(* Signature_bitset)(class IO &, T &)
static bool classof(const Node *N)
This class should be specialized by type that requires custom conversion to/from a YAML literal block...
size_t(* Signature_size)(class IO &, T &)
virtual void endMapping()=0
virtual void postflightFlowElement(void *)=0
virtual bool matchEnumScalar(const char *, bool)=0
virtual bool outputting()=0
~MappingNormalizationHeap()
This class should be specialized by any integer type that is a union of bit values and the YAML repre...
char front() const
front - Get the first character in the string.
Iterator abstraction for Documents over a Stream.
static bool mustQuote(StringRef)
static bool mustQuote(StringRef)
static bool mustQuote(StringRef)
void mapOptional(const char *Key, T &Val, const T &Default)
A raw_ostream that writes to an std::string.
virtual void endSequence()=0
void mapOptional(const char *Key, Optional< T > &Val)
void beginEnumScalar() override
unsigned beginSequence() override
This class implements an extremely fast bulk output stream that can only output to a stream...
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr)
matches - Match the regex against a given String.
StringRef - Represent a constant reference to a string, i.e.
void mapRequired(const char *Key, T &Val)
void endEnumScalar() override
void(* Signature_output)(const T &, void *, llvm::raw_ostream &)
static bool mustQuote(StringRef)
void postflightKey(void *) override
void blockScalarString(StringRef &) override
static char test(SameType< Signature_size,&U::size > *)
StringRef(* Signature_input)(StringRef, void *, T &)
bool canElideEmptySequence() override
bool isNumeric(StringRef S)
bool empty() const
empty - Check if the string is empty.
Abstract base class for all Nodes.