10 #ifndef LLVM_SUPPORT_YAMLTRAITS_H 11 #define LLVM_SUPPORT_YAMLTRAITS_H 35 #include <system_error> 36 #include <type_traits> 48 struct EmptyContext {};
61 struct MappingTraits {
83 template <
class T,
class Context>
struct MappingContextTraits {
106 struct ScalarEnumerationTraits {
123 struct ScalarBitSetTraits {
150 struct ScalarTraits {
180 template <
typename T>
181 struct BlockScalarTraits {
217 template <
typename T>
struct TaggedScalarTraits {
247 template<
typename T,
typename EnableIf =
void>
248 struct SequenceTraits {
260 template<
typename T,
typename EnableIf =
void>
261 struct SequenceElementTraits {
269 struct DocumentListTraits {
278 template <
typename T>
279 struct CustomMappingTraits {
301 template <
typename T>
struct PolymorphicTraits {
310 template <
typename T>
315 struct has_ScalarEnumerationTraits
317 using Signature_enumeration = void (*)(
class IO&,
T&);
319 template <
typename U>
320 static char test(SameType<Signature_enumeration, &U::enumeration>*);
322 template <
typename U>
323 static double test(...);
325 static bool const value =
326 (
sizeof(test<ScalarEnumerationTraits<T>>(
nullptr)) == 1);
331 struct has_ScalarBitSetTraits
333 using Signature_bitset = void (*)(
class IO&,
T&);
335 template <
typename U>
336 static char test(SameType<Signature_bitset, &U::bitset>*);
338 template <
typename U>
339 static double test(...);
341 static bool const value = (
sizeof(test<ScalarBitSetTraits<T>>(
nullptr)) == 1);
346 struct has_ScalarTraits
348 using Signature_input = StringRef (*)(StringRef,
void*,
T&);
349 using Signature_output = void (*)(
const T&,
void*, raw_ostream&);
350 using Signature_mustQuote = QuotingType (*)(StringRef);
352 template <
typename U>
353 static char test(SameType<Signature_input, &U::input> *,
354 SameType<Signature_output, &U::output> *,
355 SameType<Signature_mustQuote, &U::mustQuote> *);
357 template <
typename U>
358 static double test(...);
360 static bool const value =
361 (
sizeof(test<ScalarTraits<T>>(
nullptr,
nullptr,
nullptr)) == 1);
366 struct has_BlockScalarTraits
368 using Signature_input = StringRef (*)(StringRef,
void *,
T &);
369 using Signature_output = void (*)(
const T &,
void *, raw_ostream &);
371 template <
typename U>
372 static char test(SameType<Signature_input, &U::input> *,
373 SameType<Signature_output, &U::output> *);
375 template <
typename U>
376 static double test(...);
378 static bool const value =
379 (
sizeof(test<BlockScalarTraits<T>>(
nullptr,
nullptr)) == 1);
383 template <
class T>
struct has_TaggedScalarTraits {
384 using Signature_input = StringRef (*)(StringRef, StringRef,
void *,
T &);
385 using Signature_output = void (*)(
const T &,
void *, raw_ostream &,
387 using Signature_mustQuote = QuotingType (*)(
const T &, StringRef);
389 template <
typename U>
390 static char test(SameType<Signature_input, &U::input> *,
391 SameType<Signature_output, &U::output> *,
392 SameType<Signature_mustQuote, &U::mustQuote> *);
394 template <
typename U>
static double test(...);
396 static bool const value =
397 (
sizeof(test<TaggedScalarTraits<T>>(
nullptr,
nullptr,
nullptr)) == 1);
401 template <
class T,
class Context>
struct has_MappingTraits {
402 using Signature_mapping = void (*)(
class IO &,
T &,
Context &);
404 template <
typename U>
405 static char test(SameType<Signature_mapping, &U::mapping>*);
407 template <
typename U>
408 static double test(...);
410 static bool const value =
411 (
sizeof(test<MappingContextTraits<T, Context>>(
nullptr)) == 1);
415 template <
class T>
struct has_MappingTraits<
T, EmptyContext> {
416 using Signature_mapping = void (*)(
class IO &,
T &);
418 template <
typename U>
419 static char test(SameType<Signature_mapping, &U::mapping> *);
421 template <
typename U>
static double test(...);
423 static bool const value = (
sizeof(test<MappingTraits<T>>(
nullptr)) == 1);
427 template <
class T,
class Context>
struct has_MappingValidateTraits {
428 using Signature_validate = StringRef (*)(
class IO &,
T &,
Context &);
430 template <
typename U>
431 static char test(SameType<Signature_validate, &U::validate>*);
433 template <
typename U>
434 static double test(...);
436 static bool const value =
437 (
sizeof(test<MappingContextTraits<T, Context>>(
nullptr)) == 1);
441 template <
class T>
struct has_MappingValidateTraits<
T, EmptyContext> {
442 using Signature_validate = StringRef (*)(
class IO &,
T &);
444 template <
typename U>
445 static char test(SameType<Signature_validate, &U::validate> *);
447 template <
typename U>
static double test(...);
449 static bool const value = (
sizeof(test<MappingTraits<T>>(
nullptr)) == 1);
454 struct has_SequenceMethodTraits
456 using Signature_size =
size_t (*)(
class IO&,
T&);
458 template <
typename U>
459 static char test(SameType<Signature_size, &U::size>*);
461 template <
typename U>
462 static double test(...);
464 static bool const value = (
sizeof(test<SequenceTraits<T>>(
nullptr)) == 1);
469 struct has_CustomMappingTraits
471 using Signature_input = void (*)(IO &io, StringRef key,
T &v);
473 template <
typename U>
474 static char test(SameType<Signature_input, &U::inputOne>*);
476 template <
typename U>
477 static double test(...);
479 static bool const value =
480 (
sizeof(test<CustomMappingTraits<T>>(
nullptr)) == 1);
486 template <typename T, bool Enabled = std::is_class<T>::value>
490 static const bool value =
false;
497 struct has_FlowTraits<
T,
true>
499 struct Fallback {
bool flow; };
500 struct Derived :
T, Fallback { };
503 static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
506 static char (&f(...))[2];
508 static bool const value =
sizeof(f<Derived>(
nullptr)) == 2;
513 struct has_SequenceTraits :
public std::integral_constant<bool,
514 has_SequenceMethodTraits<T>::value > { };
518 struct has_DocumentListTraits
520 using Signature_size =
size_t (*)(
class IO &,
T &);
522 template <
typename U>
523 static char test(SameType<Signature_size, &U::size>*);
525 template <
typename U>
526 static double test(...);
528 static bool const value = (
sizeof(test<DocumentListTraits<T>>(
nullptr))==1);
531 template <
class T>
struct has_PolymorphicTraits {
532 using Signature_getKind =
NodeKind (*)(
const T &);
534 template <
typename U>
535 static char test(SameType<Signature_getKind, &U::getKind> *);
537 template <
typename U>
static double test(...);
539 static bool const value = (
sizeof(test<PolymorphicTraits<T>>(
nullptr)) == 1);
542 inline bool isNumeric(StringRef S) {
543 const static auto skipDigits = [](StringRef Input) {
544 return Input.drop_front(
545 std::min(Input.find_first_not_of(
"0123456789"), Input.size()));
550 if (S.empty() || S.equals(
"+") || S.equals(
"-"))
553 if (S.equals(
".nan") || S.equals(
".NaN") || S.equals(
".NAN"))
557 StringRef Tail = (S.front() ==
'-' || S.front() ==
'+') ? S.drop_front() : S;
561 if (Tail.equals(
".inf") || Tail.equals(
".Inf") || Tail.equals(
".INF"))
567 if (S.startswith(
"0o"))
568 return S.size() > 2 &&
571 if (S.startswith(
"0x"))
572 return S.size() > 2 && S.drop_front(2).find_first_not_of(
581 if (S.startswith(
".") &&
583 (S.size() > 1 && std::strchr(
"0123456789", S[1]) ==
nullptr)))
586 if (S.startswith(
"E") || S.startswith(
"e"))
602 if (S.front() ==
'.') {
605 }
else if (S.front() ==
'e' || S.front() ==
'E') {
606 State = FoundExponent;
612 if (State == FoundDot) {
617 if (S.front() ==
'e' || S.front() ==
'E') {
618 State = FoundExponent;
625 assert(State == FoundExponent &&
"Should have found exponent at this point.");
629 if (S.front() ==
'+' || S.front() ==
'-') {
635 return skipDigits(S).empty();
638 inline bool isNull(StringRef S) {
639 return S.equals(
"null") || S.equals(
"Null") || S.equals(
"NULL") ||
643 inline bool isBool(StringRef S) {
644 return S.equals(
"true") || S.equals(
"True") || S.equals(
"TRUE") ||
645 S.equals(
"false") || S.equals(
"False") || S.equals(
"FALSE");
653 inline QuotingType needsQuotes(StringRef S) {
656 if (isspace(S.front()) || isspace(S.back()))
668 static constexpr
char Indicators[] = R
"(-?:\,[]{}#&*!|>'"%@`)"; 669 if (S.find_first_of(Indicators) == 0)
673 for (
unsigned char C : S) {
720 return MaxQuotingNeeded;
723 template <
typename T,
typename Context>
725 :
public std::integral_constant<bool,
726 !has_ScalarEnumerationTraits<T>::value &&
727 !has_ScalarBitSetTraits<T>::value &&
728 !has_ScalarTraits<T>::value &&
729 !has_BlockScalarTraits<T>::value &&
730 !has_TaggedScalarTraits<T>::value &&
731 !has_MappingTraits<T, Context>::value &&
732 !has_SequenceTraits<T>::value &&
733 !has_CustomMappingTraits<T>::value &&
734 !has_DocumentListTraits<T>::value &&
735 !has_PolymorphicTraits<T>::value> {};
737 template <
typename T,
typename Context>
738 struct validatedMappingTraits
739 :
public std::integral_constant<
740 bool, has_MappingTraits<T, Context>::value &&
741 has_MappingValidateTraits<T, Context>::value> {};
743 template <
typename T,
typename Context>
744 struct unvalidatedMappingTraits
745 :
public std::integral_constant<
746 bool, has_MappingTraits<T, Context>::value &&
747 !has_MappingValidateTraits<T, Context>::value> {};
752 IO(
void *Ctxt =
nullptr);
755 virtual bool outputting() = 0;
757 virtual unsigned beginSequence() = 0;
758 virtual bool preflightElement(
unsigned,
void *&) = 0;
759 virtual void postflightElement(
void*) = 0;
760 virtual void endSequence() = 0;
761 virtual bool canElideEmptySequence() = 0;
763 virtual unsigned beginFlowSequence() = 0;
764 virtual bool preflightFlowElement(
unsigned,
void *&) = 0;
765 virtual void postflightFlowElement(
void*) = 0;
766 virtual void endFlowSequence() = 0;
768 virtual bool mapTag(StringRef Tag,
bool Default=
false) = 0;
769 virtual void beginMapping() = 0;
770 virtual void endMapping() = 0;
771 virtual bool preflightKey(
const char*,
bool,
bool,
bool &,
void *&) = 0;
772 virtual void postflightKey(
void*) = 0;
773 virtual std::vector<StringRef> keys() = 0;
775 virtual void beginFlowMapping() = 0;
776 virtual void endFlowMapping() = 0;
778 virtual void beginEnumScalar() = 0;
779 virtual bool matchEnumScalar(
const char*,
bool) = 0;
780 virtual bool matchEnumFallback() = 0;
781 virtual void endEnumScalar() = 0;
783 virtual bool beginBitSetScalar(
bool &) = 0;
784 virtual bool bitSetMatch(
const char*,
bool) = 0;
785 virtual void endBitSetScalar() = 0;
787 virtual void scalarString(StringRef &, QuotingType) = 0;
788 virtual void blockScalarString(StringRef &) = 0;
789 virtual void scalarTag(std::string &) = 0;
793 virtual void setError(
const Twine &) = 0;
795 template <
typename T>
796 void enumCase(
T &Val,
const char* Str,
const T ConstVal) {
797 if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
803 template <
typename T>
804 void enumCase(
T &Val,
const char* Str,
const uint32_t ConstVal) {
805 if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
810 template <
typename FBT,
typename T>
811 void enumFallback(
T &Val) {
812 if (matchEnumFallback()) {
816 yamlize(*
this, Res,
true, Context);
821 template <
typename T>
822 void bitSetCase(
T &Val,
const char* Str,
const T ConstVal) {
823 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
824 Val =
static_cast<T>(Val | ConstVal);
829 template <
typename T>
830 void bitSetCase(
T &Val,
const char* Str,
const uint32_t ConstVal) {
831 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
832 Val =
static_cast<T>(Val | ConstVal);
836 template <
typename T>
837 void maskedBitSetCase(
T &Val,
const char *Str,
T ConstVal,
T Mask) {
838 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
839 Val = Val | ConstVal;
842 template <
typename T>
843 void maskedBitSetCase(
T &Val,
const char *Str,
uint32_t ConstVal,
845 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
846 Val = Val | ConstVal;
850 void setContext(
void *);
852 template <
typename T>
void mapRequired(
const char *
Key,
T &Val) {
854 this->processKey(Key, Val,
true, Ctx);
857 template <
typename T,
typename Context>
858 void mapRequired(
const char *
Key,
T &Val,
Context &Ctx) {
859 this->processKey(Key, Val,
true, Ctx);
862 template <
typename T>
void mapOptional(
const char *
Key,
T &Val) {
864 mapOptionalWithContext(Key, Val, Ctx);
867 template <
typename T>
868 void mapOptional(
const char *
Key,
T &Val,
const T &Default) {
870 mapOptionalWithContext(Key, Val, Default, Ctx);
873 template <
typename T,
typename Context>
874 typename std::enable_if<has_SequenceTraits<T>::value,
void>
::type 875 mapOptionalWithContext(
const char *
Key,
T &Val,
Context &Ctx) {
877 if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
879 this->processKey(Key, Val,
false, Ctx);
882 template <
typename T,
typename Context>
883 void mapOptionalWithContext(
const char *Key, Optional<T> &Val,
Context &Ctx) {
884 this->processKeyWithDefault(Key, Val, Optional<T>(),
false,
888 template <
typename T,
typename Context>
889 typename std::enable_if<!has_SequenceTraits<T>::value,
void>
::type 890 mapOptionalWithContext(
const char *Key,
T &Val,
Context &Ctx) {
891 this->processKey(Key, Val,
false, Ctx);
894 template <
typename T,
typename Context>
895 void mapOptionalWithContext(
const char *Key,
T &Val,
const T &Default,
897 this->processKeyWithDefault(Key, Val, Default,
false, Ctx);
901 template <
typename T,
typename Context>
902 void processKeyWithDefault(
const char *Key, Optional<T> &Val,
903 const Optional<T> &DefaultValue,
bool Required,
905 assert(DefaultValue.hasValue() ==
false &&
906 "Optional<T> shouldn't have a value!");
908 bool UseDefault =
true;
909 const bool sameAsDefault = outputting() && !Val.hasValue();
910 if (!outputting() && !Val.hasValue())
912 if (Val.hasValue() &&
913 this->preflightKey(Key, Required, sameAsDefault, UseDefault,
915 yamlize(*
this, Val.getValue(),
Required, Ctx);
916 this->postflightKey(SaveInfo);
923 template <
typename T,
typename Context>
924 void processKeyWithDefault(
const char *Key,
T &Val,
const T &DefaultValue,
928 const bool sameAsDefault = outputting() && Val == DefaultValue;
929 if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
931 yamlize(*
this, Val, Required, Ctx);
932 this->postflightKey(SaveInfo);
940 template <
typename T,
typename Context>
941 void processKey(
const char *Key,
T &Val,
bool Required,
Context &Ctx) {
944 if ( this->preflightKey(Key, Required,
false, UseDefault, SaveInfo) ) {
945 yamlize(*
this, Val, Required, Ctx);
946 this->postflightKey(SaveInfo);
956 template <
typename T,
typename Context>
957 void doMapping(IO &io,
T &Val,
Context &Ctx) {
958 MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
961 template <
typename T>
void doMapping(IO &io,
T &Val, EmptyContext &Ctx) {
962 MappingTraits<T>::mapping(io, Val);
967 template <
typename T>
968 typename std::enable_if<has_ScalarEnumerationTraits<T>::value,
void>
::type 969 yamlize(IO &io,
T &Val,
bool, EmptyContext &Ctx) {
970 io.beginEnumScalar();
971 ScalarEnumerationTraits<T>::enumeration(io, Val);
975 template <
typename T>
976 typename std::enable_if<has_ScalarBitSetTraits<T>::value,
void>
::type 977 yamlize(IO &io,
T &Val,
bool, EmptyContext &Ctx) {
979 if ( io.beginBitSetScalar(DoClear) ) {
981 Val =
static_cast<T>(0);
982 ScalarBitSetTraits<T>::bitset(io, Val);
983 io.endBitSetScalar();
987 template <
typename T>
988 typename std::enable_if<has_ScalarTraits<T>::value,
void>
::type 989 yamlize(IO &io,
T &Val,
bool, EmptyContext &Ctx) {
990 if ( io.outputting() ) {
992 raw_string_ostream Buffer(Storage);
993 ScalarTraits<T>::output(Val, io.getContext(), Buffer);
994 StringRef Str = Buffer.str();
995 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
999 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
1000 StringRef
Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
1001 if ( !Result.empty() ) {
1002 io.setError(Twine(Result));
1007 template <
typename T>
1008 typename std::enable_if<has_BlockScalarTraits<T>::value,
void>
::type 1009 yamlize(IO &YamlIO,
T &Val,
bool, EmptyContext &Ctx) {
1010 if (YamlIO.outputting()) {
1011 std::string Storage;
1012 raw_string_ostream Buffer(Storage);
1013 BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
1014 StringRef Str = Buffer.str();
1015 YamlIO.blockScalarString(Str);
1018 YamlIO.blockScalarString(Str);
1020 BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
1021 if (!Result.empty())
1022 YamlIO.setError(Twine(Result));
1026 template <
typename T>
1027 typename std::enable_if<has_TaggedScalarTraits<T>::value,
void>
::type 1028 yamlize(IO &io,
T &Val,
bool, EmptyContext &Ctx) {
1029 if (io.outputting()) {
1030 std::string ScalarStorage, TagStorage;
1031 raw_string_ostream ScalarBuffer(ScalarStorage), TagBuffer(TagStorage);
1032 TaggedScalarTraits<T>::output(Val, io.getContext(), ScalarBuffer,
1034 io.scalarTag(TagBuffer.str());
1035 StringRef ScalarStr = ScalarBuffer.str();
1036 io.scalarString(ScalarStr,
1037 TaggedScalarTraits<T>::mustQuote(Val, ScalarStr));
1044 TaggedScalarTraits<T>::input(Str, Tag, io.getContext(), Val);
1045 if (!Result.empty()) {
1046 io.setError(Twine(Result));
1051 template <
typename T,
typename Context>
1052 typename std::enable_if<validatedMappingTraits<T, Context>::value,
void>
::type 1053 yamlize(IO &io,
T &Val,
bool,
Context &Ctx) {
1054 if (has_FlowTraits<MappingTraits<T>>::value)
1055 io.beginFlowMapping();
1058 if (io.outputting()) {
1059 StringRef Err = MappingTraits<T>::validate(io, Val);
1061 errs() << Err <<
"\n";
1062 assert(Err.empty() &&
"invalid struct trying to be written as yaml");
1065 detail::doMapping(io, Val, Ctx);
1066 if (!io.outputting()) {
1067 StringRef Err = MappingTraits<T>::validate(io, Val);
1071 if (has_FlowTraits<MappingTraits<T>>::value)
1072 io.endFlowMapping();
1077 template <
typename T,
typename Context>
1078 typename std::enable_if<unvalidatedMappingTraits<T, Context>::value,
void>
::type 1079 yamlize(IO &io,
T &Val,
bool,
Context &Ctx) {
1080 if (has_FlowTraits<MappingTraits<T>>::value) {
1081 io.beginFlowMapping();
1082 detail::doMapping(io, Val, Ctx);
1083 io.endFlowMapping();
1086 detail::doMapping(io, Val, Ctx);
1091 template <
typename T>
1092 typename std::enable_if<has_CustomMappingTraits<T>::value,
void>
::type 1093 yamlize(IO &io,
T &Val,
bool, EmptyContext &Ctx) {
1094 if ( io.outputting() ) {
1096 CustomMappingTraits<T>::output(io, Val);
1100 for (StringRef key : io.keys())
1101 CustomMappingTraits<T>::inputOne(io, key, Val);
1106 template <
typename T>
1107 typename std::enable_if<has_PolymorphicTraits<T>::value,
void>
::type 1108 yamlize(IO &io,
T &Val,
bool, EmptyContext &Ctx) {
1109 switch (io.outputting() ? PolymorphicTraits<T>::getKind(Val)
1110 : io.getNodeKind()) {
1112 return yamlize(io, PolymorphicTraits<T>::getAsScalar(Val),
true, Ctx);
1114 return yamlize(io, PolymorphicTraits<T>::getAsMap(Val),
true, Ctx);
1116 return yamlize(io, PolymorphicTraits<T>::getAsSequence(Val),
true, Ctx);
1120 template <
typename T>
1121 typename std::enable_if<missingTraits<T, EmptyContext>::value,
void>
::type 1122 yamlize(IO &io,
T &Val,
bool, EmptyContext &Ctx) {
1123 char missing_yaml_trait_for_type[
sizeof(MissingTrait<T>)];
1126 template <
typename T,
typename Context>
1127 typename std::enable_if<has_SequenceTraits<T>::value,
void>
::type 1128 yamlize(IO &io,
T &Seq,
bool,
Context &Ctx) {
1129 if ( has_FlowTraits< SequenceTraits<T>>::value ) {
1130 unsigned incnt = io.beginFlowSequence();
1132 for(
unsigned i=0; i <
count; ++i) {
1134 if ( io.preflightFlowElement(i, SaveInfo) ) {
1135 yamlize(io, SequenceTraits<T>::element(io, Seq, i),
true, Ctx);
1136 io.postflightFlowElement(SaveInfo);
1139 io.endFlowSequence();
1142 unsigned incnt = io.beginSequence();
1144 for(
unsigned i=0; i <
count; ++i) {
1146 if ( io.preflightElement(i, SaveInfo) ) {
1147 yamlize(io, SequenceTraits<T>::element(io, Seq, i),
true, Ctx);
1148 io.postflightElement(SaveInfo);
1156 struct ScalarTraits<
bool> {
1157 static void output(
const bool &,
void* , raw_ostream &);
1158 static StringRef input(StringRef,
void *,
bool &);
1163 struct ScalarTraits<StringRef> {
1164 static void output(
const StringRef &,
void *, raw_ostream &);
1165 static StringRef input(StringRef,
void *, StringRef &);
1166 static QuotingType mustQuote(StringRef S) {
return needsQuotes(S); }
1171 static void output(
const std::string &,
void *, raw_ostream &);
1172 static StringRef input(StringRef,
void *, std::string &);
1173 static QuotingType mustQuote(StringRef S) {
return needsQuotes(S); }
1177 struct ScalarTraits<uint8_t> {
1178 static void output(
const uint8_t &,
void *, raw_ostream &);
1179 static StringRef input(StringRef,
void *, uint8_t &);
1184 struct ScalarTraits<uint16_t> {
1185 static void output(
const uint16_t &,
void *, raw_ostream &);
1186 static StringRef input(StringRef,
void *, uint16_t &);
1192 static void output(
const uint32_t &,
void *, raw_ostream &);
1193 static StringRef input(StringRef,
void *,
uint32_t &);
1198 struct ScalarTraits<uint64_t> {
1199 static void output(
const uint64_t &,
void *, raw_ostream &);
1200 static StringRef input(StringRef,
void *, uint64_t &);
1205 struct ScalarTraits<int8_t> {
1206 static void output(
const int8_t &,
void *, raw_ostream &);
1207 static StringRef input(StringRef,
void *, int8_t &);
1212 struct ScalarTraits<int16_t> {
1213 static void output(
const int16_t &,
void *, raw_ostream &);
1214 static StringRef input(StringRef,
void *, int16_t &);
1219 struct ScalarTraits<int32_t> {
1220 static void output(
const int32_t &,
void *, raw_ostream &);
1221 static StringRef input(StringRef,
void *, int32_t &);
1226 struct ScalarTraits<int64_t> {
1227 static void output(
const int64_t &,
void *, raw_ostream &);
1228 static StringRef input(StringRef,
void *, int64_t &);
1233 struct ScalarTraits<float> {
1234 static void output(
const float &,
void *, raw_ostream &);
1235 static StringRef input(StringRef,
void *,
float &);
1240 struct ScalarTraits<double> {
1241 static void output(
const double &,
void *, raw_ostream &);
1242 static StringRef input(StringRef,
void *,
double &);
1249 template <
typename value_type, support::endianness endian,
size_t alignment>
1250 struct ScalarTraits<support::detail::packed_endian_specific_integral<
1251 value_type, endian, alignment>> {
1253 support::detail::packed_endian_specific_integral<value_type, endian,
1256 static void output(
const endian_type &
E,
void *Ctx, raw_ostream &Stream) {
1257 ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1260 static StringRef input(StringRef Str,
void *Ctx, endian_type &E) {
1262 auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1263 E =
static_cast<endian_type
>(V);
1267 static QuotingType mustQuote(StringRef Str) {
1268 return ScalarTraits<value_type>::mustQuote(Str);
1274 template <
typename TNorm,
typename TFinal>
1275 struct MappingNormalization {
1276 MappingNormalization(IO &i_o, TFinal &Obj)
1277 : io(i_o), BufPtr(nullptr), Result(Obj) {
1278 if ( io.outputting() ) {
1279 BufPtr =
new (&Buffer) TNorm(io, Obj);
1282 BufPtr =
new (&Buffer) TNorm(io);
1286 ~MappingNormalization() {
1287 if ( ! io.outputting() ) {
1288 Result = BufPtr->denormalize(io);
1293 TNorm* operator->() {
return BufPtr; }
1296 using Storage = AlignedCharArrayUnion<TNorm>;
1306 template <
typename TNorm,
typename TFinal>
1307 struct MappingNormalizationHeap {
1308 MappingNormalizationHeap(IO &i_o, TFinal &Obj,
BumpPtrAllocator *allocator)
1309 : io(i_o), Result(Obj) {
1310 if ( io.outputting() ) {
1311 BufPtr =
new (&Buffer) TNorm(io, Obj);
1313 else if (allocator) {
1314 BufPtr = allocator->Allocate<TNorm>();
1315 new (BufPtr) TNorm(io);
1317 BufPtr =
new TNorm(io);
1321 ~MappingNormalizationHeap() {
1322 if ( io.outputting() ) {
1326 Result = BufPtr->denormalize(io);
1330 TNorm* operator->() {
return BufPtr; }
1333 using Storage = AlignedCharArrayUnion<TNorm>;
1337 TNorm *BufPtr =
nullptr;
1353 class Input :
public IO {
1358 Input(StringRef InputContent,
1359 void *Ctxt =
nullptr,
1361 void *DiagHandlerCtxt =
nullptr);
1362 Input(MemoryBufferRef Input,
1363 void *Ctxt =
nullptr,
1365 void *DiagHandlerCtxt =
nullptr);
1369 std::error_code
error();
1372 bool outputting()
override;
1373 bool mapTag(StringRef,
bool)
override;
1374 void beginMapping()
override;
1375 void endMapping()
override;
1376 bool preflightKey(
const char *,
bool,
bool,
bool &,
void *&)
override;
1377 void postflightKey(
void *)
override;
1378 std::vector<StringRef> keys()
override;
1379 void beginFlowMapping()
override;
1380 void endFlowMapping()
override;
1381 unsigned beginSequence()
override;
1382 void endSequence()
override;
1383 bool preflightElement(
unsigned index,
void *&)
override;
1384 void postflightElement(
void *)
override;
1385 unsigned beginFlowSequence()
override;
1386 bool preflightFlowElement(
unsigned ,
void *&)
override;
1387 void postflightFlowElement(
void *)
override;
1388 void endFlowSequence()
override;
1389 void beginEnumScalar()
override;
1390 bool matchEnumScalar(
const char*,
bool)
override;
1391 bool matchEnumFallback()
override;
1392 void endEnumScalar()
override;
1393 bool beginBitSetScalar(
bool &)
override;
1394 bool bitSetMatch(
const char *,
bool )
override;
1395 void endBitSetScalar()
override;
1396 void scalarString(StringRef &, QuotingType)
override;
1397 void blockScalarString(StringRef &)
override;
1398 void scalarTag(std::string &)
override;
1400 void setError(
const Twine &message)
override;
1401 bool canElideEmptySequence()
override;
1404 virtual void anchor();
1407 HNode(Node *n) : _node(n) { }
1408 virtual ~HNode() =
default;
1410 static bool classof(
const HNode *) {
return true; }
1415 class EmptyHNode :
public HNode {
1416 void anchor()
override;
1419 EmptyHNode(Node *n) : HNode(n) { }
1423 static bool classof(
const EmptyHNode *) {
return true; }
1426 class ScalarHNode :
public HNode {
1427 void anchor()
override;
1430 ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1432 StringRef value()
const {
return _value; }
1434 static bool classof(
const HNode *n) {
1439 static bool classof(
const ScalarHNode *) {
return true; }
1445 class MapHNode :
public HNode {
1446 void anchor()
override;
1449 MapHNode(Node *n) : HNode(n) { }
1451 static bool classof(
const HNode *n) {
1455 static bool classof(
const MapHNode *) {
return true; }
1457 using NameToNode = StringMap<std::unique_ptr<HNode>>;
1460 SmallVector<std::string, 6> ValidKeys;
1463 class SequenceHNode :
public HNode {
1464 void anchor()
override;
1467 SequenceHNode(Node *n) : HNode(n) { }
1469 static bool classof(
const HNode *n) {
1473 static bool classof(
const SequenceHNode *) {
return true; }
1475 std::vector<std::unique_ptr<HNode>> Entries;
1478 std::unique_ptr<Input::HNode> createHNodes(Node *node);
1479 void setError(HNode *hnode,
const Twine &message);
1480 void setError(Node *node,
const Twine &message);
1485 bool setCurrentDocument();
1486 bool nextDocument();
1489 const Node *getCurrentNode()
const;
1493 std::unique_ptr<llvm::yaml::Stream> Strm;
1494 std::unique_ptr<HNode> TopNode;
1497 document_iterator DocIterator;
1498 std::vector<bool> BitValuesUsed;
1499 HNode *CurrentNode =
nullptr;
1500 bool ScalarMatchFound;
1507 class Output :
public IO {
1509 Output(raw_ostream &,
void *Ctxt =
nullptr,
int WrapColumn = 70);
1517 void setWriteDefaultValues(
bool Write) { WriteDefaultValues = Write; }
1519 bool outputting()
override;
1520 bool mapTag(StringRef,
bool)
override;
1521 void beginMapping()
override;
1522 void endMapping()
override;
1523 bool preflightKey(
const char *key,
bool,
bool,
bool &,
void *&)
override;
1524 void postflightKey(
void *)
override;
1525 std::vector<StringRef> keys()
override;
1526 void beginFlowMapping()
override;
1527 void endFlowMapping()
override;
1528 unsigned beginSequence()
override;
1529 void endSequence()
override;
1530 bool preflightElement(
unsigned,
void *&)
override;
1531 void postflightElement(
void *)
override;
1532 unsigned beginFlowSequence()
override;
1533 bool preflightFlowElement(
unsigned,
void *&)
override;
1534 void postflightFlowElement(
void *)
override;
1535 void endFlowSequence()
override;
1536 void beginEnumScalar()
override;
1537 bool matchEnumScalar(
const char*,
bool)
override;
1538 bool matchEnumFallback()
override;
1539 void endEnumScalar()
override;
1540 bool beginBitSetScalar(
bool &)
override;
1541 bool bitSetMatch(
const char *,
bool )
override;
1542 void endBitSetScalar()
override;
1543 void scalarString(StringRef &, QuotingType)
override;
1544 void blockScalarString(StringRef &)
override;
1545 void scalarTag(std::string &)
override;
1547 void setError(
const Twine &message)
override;
1548 bool canElideEmptySequence()
override;
1552 void beginDocuments();
1553 bool preflightDocument(
unsigned);
1554 void postflightDocument();
1555 void endDocuments();
1558 void output(StringRef s);
1559 void outputUpToEndOfLine(StringRef s);
1560 void newLineCheck();
1561 void outputNewLine();
1562 void paddedKey(StringRef key);
1563 void flowKey(StringRef Key);
1568 inFlowSeqFirstElement,
1569 inFlowSeqOtherElement,
1576 static bool inSeqAnyElement(InState State);
1577 static bool inFlowSeqAnyElement(InState State);
1578 static bool inMapAnyKey(InState State);
1579 static bool inFlowMapAnyKey(InState State);
1583 SmallVector<InState, 8> StateStack;
1585 int ColumnAtFlowStart = 0;
1586 int ColumnAtMapFlowStart = 0;
1587 bool NeedBitValueComma =
false;
1588 bool NeedFlowSequenceComma =
false;
1589 bool EnumerationMatchFound =
false;
1590 bool NeedsNewLine =
false;
1591 bool WriteDefaultValues =
false;
1602 #define LLVM_YAML_STRONG_TYPEDEF(_base, _type) \ 1604 _type() = default; \ 1605 _type(const _base v) : value(v) {} \ 1606 _type(const _type &v) = default; \ 1607 _type &operator=(const _type &rhs) = default; \ 1608 _type &operator=(const _base &rhs) { value = rhs; return *this; } \ 1609 operator const _base & () const { return value; } \ 1610 bool operator==(const _type &rhs) const { return value == rhs.value; } \ 1611 bool operator==(const _base &rhs) const { return value == rhs; } \ 1612 bool operator<(const _type &rhs) const { return value < rhs.value; } \ 1614 using BaseType = _base; \ 1621 LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
1622 LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
1623 LLVM_YAML_STRONG_TYPEDEF(
uint32_t, Hex32)
1624 LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
1627 struct ScalarTraits<Hex8> {
1628 static void output(
const Hex8 &,
void *, raw_ostream &);
1629 static StringRef input(StringRef,
void *, Hex8 &);
1634 struct ScalarTraits<Hex16> {
1635 static void output(
const Hex16 &,
void *, raw_ostream &);
1636 static StringRef input(StringRef,
void *, Hex16 &);
1641 struct ScalarTraits<Hex32> {
1642 static void output(
const Hex32 &,
void *, raw_ostream &);
1643 static StringRef input(StringRef,
void *, Hex32 &);
1648 struct ScalarTraits<Hex64> {
1649 static void output(
const Hex64 &,
void *, raw_ostream &);
1650 static StringRef input(StringRef,
void *, Hex64 &);
1655 template <
typename T>
1657 typename std::enable_if<has_DocumentListTraits<T>::value, Input &>
::type 1661 while ( yin.setCurrentDocument() ) {
1662 yamlize(yin, DocumentListTraits<T>::element(yin, docList, i),
true, Ctx);
1672 template <
typename T>
1673 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1677 yin.setCurrentDocument();
1678 yamlize(yin, docMap,
true, Ctx);
1684 template <
typename T>
1686 typename std::enable_if<has_SequenceTraits<T>::value, Input &>
::type 1689 if (yin.setCurrentDocument())
1690 yamlize(yin, docSeq,
true, Ctx);
1695 template <
typename T>
1697 typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>
::type 1700 if (In.setCurrentDocument())
1701 yamlize(In, Val,
true, Ctx);
1706 template <
typename T>
1708 typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>
::type 1711 if (In.setCurrentDocument())
1712 yamlize(In, Val,
true, Ctx);
1717 template <
typename T>
1718 inline typename std::enable_if<has_PolymorphicTraits<T>::value, Input &>
::type 1721 if (In.setCurrentDocument())
1722 yamlize(In, Val,
true, Ctx);
1727 template <
typename T>
1728 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1731 char missing_yaml_trait_for_type[
sizeof(MissingTrait<T>)];
1736 template <
typename T>
1738 typename std::enable_if<has_DocumentListTraits<T>::value, Output &>
::type 1741 yout.beginDocuments();
1743 for(
size_t i=0; i <
count; ++i) {
1744 if ( yout.preflightDocument(i) ) {
1745 yamlize(yout, DocumentListTraits<T>::element(yout, docList, i),
true,
1747 yout.postflightDocument();
1750 yout.endDocuments();
1755 template <
typename T>
1756 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1760 yout.beginDocuments();
1761 if ( yout.preflightDocument(0) ) {
1762 yamlize(yout, map,
true, Ctx);
1763 yout.postflightDocument();
1765 yout.endDocuments();
1770 template <
typename T>
1772 typename std::enable_if<has_SequenceTraits<T>::value, Output &>
::type 1775 yout.beginDocuments();
1776 if ( yout.preflightDocument(0) ) {
1777 yamlize(yout, seq,
true, Ctx);
1778 yout.postflightDocument();
1780 yout.endDocuments();
1785 template <
typename T>
1787 typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>
::type 1790 Out.beginDocuments();
1791 if (Out.preflightDocument(0)) {
1792 yamlize(Out, Val,
true, Ctx);
1793 Out.postflightDocument();
1800 template <
typename T>
1802 typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>
::type 1805 Out.beginDocuments();
1806 if (Out.preflightDocument(0)) {
1807 yamlize(Out, Val,
true, Ctx);
1808 Out.postflightDocument();
1816 template <
typename T>
1817 inline typename std::enable_if<has_PolymorphicTraits<T>::value, Output &>
::type 1820 Out.beginDocuments();
1821 if (Out.preflightDocument(0)) {
1824 assert(PolymorphicTraits<T>::getKind(Val) !=
NodeKind::Scalar &&
"plain scalar documents are not supported");
1825 yamlize(Out, Val,
true, Ctx);
1826 Out.postflightDocument();
1833 template <
typename T>
1834 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1837 char missing_yaml_trait_for_type[
sizeof(MissingTrait<T>)];
1841 template <
bool B>
struct IsFlowSequenceBase {};
1842 template <>
struct IsFlowSequenceBase<
true> {
static const bool flow =
true; };
1844 template <
typename T,
bool Flow>
1845 struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1847 using type =
typename T::value_type;
1850 static size_t size(IO &io,
T &seq) {
return seq.size(); }
1852 static type &element(IO &io,
T &seq,
size_t index) {
1853 if (index >= seq.size())
1854 seq.resize(index + 1);
1861 template <
bool>
struct CheckIsBool {
static const bool value =
true; };
1865 template <
typename T>
1866 struct SequenceTraits<
std::vector<T>,
1867 typename std::enable_if<CheckIsBool<
1868 SequenceElementTraits<T>::flow>::value>
::type>
1869 : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1870 template <
typename T,
unsigned N>
1871 struct SequenceTraits<SmallVector<
T,
N>,
1872 typename std::enable_if<CheckIsBool<
1873 SequenceElementTraits<T>::flow>::value>
::type>
1874 : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1877 template <
typename T>
1878 struct SequenceElementTraits<
1879 T, typename std::enable_if<std::is_fundamental<T>::value>
::type> {
1880 static const bool flow =
true;
1884 template<>
struct SequenceElementTraits<std::
string> {
1885 static const bool flow =
false;
1887 template<>
struct SequenceElementTraits<StringRef> {
1888 static const bool flow =
false;
1890 template<>
struct SequenceElementTraits<std::pair<std::string, std::string>> {
1891 static const bool flow =
false;
1895 template <
typename T>
struct StdMapStringCustomMappingTraitsImpl {
1896 using map_type = std::map<std::string, T>;
1898 static void inputOne(IO &io, StringRef key, map_type &v) {
1899 io.mapRequired(key.str().c_str(), v[key]);
1902 static void output(IO &io, map_type &v) {
1904 io.mapRequired(p.first.c_str(), p.second);
1911 #define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW) \ 1915 !std::is_fundamental<TYPE>::value && \ 1916 !std::is_same<TYPE, std::string>::value && \ 1917 !std::is_same<TYPE, llvm::StringRef>::value, \ 1918 "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \ 1919 template <> struct SequenceElementTraits<TYPE> { \ 1920 static const bool flow = FLOW; \ 1927 #define LLVM_YAML_IS_SEQUENCE_VECTOR(type) \ 1928 LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false) 1932 #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type) \ 1933 LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true) 1935 #define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type) \ 1938 template <> struct MappingTraits<Type> { \ 1939 static void mapping(IO &IO, Type &Obj); \ 1944 #define LLVM_YAML_DECLARE_ENUM_TRAITS(Type) \ 1947 template <> struct ScalarEnumerationTraits<Type> { \ 1948 static void enumeration(IO &io, Type &Value); \ 1953 #define LLVM_YAML_DECLARE_BITSET_TRAITS(Type) \ 1956 template <> struct ScalarBitSetTraits<Type> { \ 1957 static void bitset(IO &IO, Type &Options); \ 1962 #define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote) \ 1965 template <> struct ScalarTraits<Type> { \ 1966 static void output(const Type &Value, void *ctx, raw_ostream &Out); \ 1967 static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \ 1968 static QuotingType mustQuote(StringRef) { return MustQuote; } \ 1975 #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \ 1978 template <unsigned N> \ 1979 struct DocumentListTraits<SmallVector<_type, N>> \ 1980 : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \ 1982 struct DocumentListTraits<std::vector<_type>> \ 1983 : public SequenceTraitsImpl<std::vector<_type>, false> {}; \ 1989 #define LLVM_YAML_IS_STRING_MAP(_type) \ 1993 struct CustomMappingTraits<std::map<std::string, _type>> \ 1994 : public StdMapStringCustomMappingTraitsImpl<_type> {}; \ 1998 #endif // LLVM_SUPPORT_YAMLTRAITS_H static bool classof(const Node *N)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
This class represents lattice values for constants.
block Block Frequency true
static bool classof(const Node *N)
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
static bool classof(const Node *N)
static bool classof(const Node *N)
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
iterator_range< detail::value_sequence_iterator< ValueT > > seq(ValueT Begin, ValueT End)
static bool classof(const Node *N)
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
ScaledNumber< DigitsT > operator>>(const ScaledNumber< DigitsT > &L, int16_t Shift)