llvm.org GIT mirror llvm / 65ad22d
[YAML] Add support for non-printable characters LLVM IR function names which disable mangling start with '\01' (https://www.llvm.org/docs/LangRef.html#identifiers). When an identifier like "\01@abc@" gets dumped to MIR, it is quoted, but only with single quotes. http://www.yaml.org/spec/1.2/spec.html#id2770814: "The allowed character range explicitly excludes the C0 control block allowed), the surrogate block #xD800-#xDFFF, #xFFFE, and #xFFFF." http://www.yaml.org/spec/1.2/spec.html#id2776092: "All non-printable characters must be escaped. [...] Note that escape sequences are only interpreted in double-quoted scalars." This patch adds support for printing escaped non-printable characters between double quotes if needed. Should also fix PR31743. Differential Revision: https://reviews.llvm.org/D41290 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320996 91177308-0d34-0410-b5e6-96231b3b80d8 Francis Visoiu Mistrih 2 years ago
17 changed file(s) with 246 addition(s) and 77 deletion(s). Raw diff Collapse all Expand all
465465 return StringRef();
466466 }
467467 // Determine if this scalar needs quotes.
468 static bool mustQuote(StringRef) { return true; }
468 static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
469469 };
470470
471471 Block Scalars
5555 return "";
5656 }
5757
58 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
58 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
5959 };
6060
6161 struct FlowStringValue : StringValue {
7272 return ScalarTraits::input(Scalar, Ctx, S);
7373 }
7474
75 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
75 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
7676 };
7777
7878 struct BlockStringValue {
119119 return ScalarTraits::input(Scalar, Ctx, Value.Value);
120120 }
121121
122 static bool mustQuote(StringRef Scalar) {
122 static QuotingType mustQuote(StringRef Scalar) {
123123 return ScalarTraits::mustQuote(Scalar);
124124 }
125125 };
5555 } // end namespace llvm
5656
5757 LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::DebugHSection)
58 LLVM_YAML_DECLARE_SCALAR_TRAITS(CodeViewYAML::GlobalHash, false)
58 LLVM_YAML_DECLARE_SCALAR_TRAITS(CodeViewYAML::GlobalHash, QuotingType::None)
5959 LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::GlobalHash)
6060
6161 #endif // LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H
5757
5858 } // end namespace llvm
5959
60 LLVM_YAML_DECLARE_SCALAR_TRAITS(codeview::GUID, true)
60 LLVM_YAML_DECLARE_SCALAR_TRAITS(codeview::GUID, QuotingType::Single)
6161
6262 LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::LeafRecord)
6363 LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::MemberRecord)
260260 template <> struct ScalarTraits {
261261 static void output(const char_16 &Val, void *, raw_ostream &Out);
262262 static StringRef input(StringRef Scalar, void *, char_16 &Val);
263 static bool mustQuote(StringRef S);
263 static QuotingType mustQuote(StringRef S);
264264 };
265265
266266 // This trait is used for UUIDs. It reads and writes them matching otool's
270270 template <> struct ScalarTraits {
271271 static void output(const uuid_t &Val, void *, raw_ostream &Out);
272272 static StringRef input(StringRef Scalar, void *, uuid_t &Val);
273 static bool mustQuote(StringRef S);
273 static QuotingType mustQuote(StringRef S);
274274 };
275275
276276 // Load Command struct mapping traits
106106 template <> struct ScalarTraits {
107107 static void output(const BinaryRef &, void *, raw_ostream &);
108108 static StringRef input(StringRef, void *, BinaryRef &);
109 static bool mustQuote(StringRef S) { return needsQuotes(S); }
109 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
110110 };
111111
112112 } // end namespace yaml
1111
1212 #include "llvm/ADT/Optional.h"
1313 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringExtras.h"
1415 #include "llvm/ADT/StringMap.h"
1516 #include "llvm/ADT/StringRef.h"
1617 #include "llvm/ADT/Twine.h"
116117 // static void bitset(IO &io, T &value);
117118 };
118119
120 /// Describe which type of quotes should be used when quoting is necessary.
121 /// Some non-printable characters need to be double-quoted, while some others
122 /// are fine with simple-quoting, and some don't need any quoting.
123 enum class QuotingType { None, Single, Double };
124
119125 /// This class should be specialized by type that requires custom conversion
120126 /// to/from a yaml scalar. For example:
121127 ///
130136 /// // return empty string on success, or error string
131137 /// return StringRef();
132138 /// }
133 /// static bool mustQuote(StringRef) { return true; }
139 /// static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
134140 /// };
135141 template
136142 struct ScalarTraits {
144150 //static StringRef input(StringRef scalar, void *ctxt, T &value);
145151 //
146152 // Function to determine if the value should be quoted.
147 //static bool mustQuote(StringRef);
153 //static QuotingType mustQuote(StringRef);
148154 };
149155
150156 /// This class should be specialized by type that requires custom conversion
269275 {
270276 using Signature_input = StringRef (*)(StringRef, void*, T&);
271277 using Signature_output = void (*)(const T&, void*, raw_ostream&);
272 using Signature_mustQuote = bool (*)(StringRef);
278 using Signature_mustQuote = QuotingType (*)(StringRef);
273279
274280 template
275281 static char test(SameType *,
494500 S.equals("false") || S.equals("False") || S.equals("FALSE");
495501 }
496502
497 inline bool needsQuotes(StringRef S) {
503 // 5.1. Character Set
504 // The allowed character range explicitly excludes the C0 control block #x0-#x1F
505 // (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
506 // control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
507 // block #xD800-#xDFFF, #xFFFE, and #xFFFF.
508 inline QuotingType needsQuotes(StringRef S) {
498509 if (S.empty())
499 return true;
510 return QuotingType::Single;
500511 if (isspace(S.front()) || isspace(S.back()))
501 return true;
512 return QuotingType::Single;
502513 if (S.front() == ',')
503 return true;
504
505 static const char ScalarSafeChars[] =
506 "abcdefghijklmnopqrstuvwxyz"
507 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
508 if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
509 return true;
510
514 return QuotingType::Single;
511515 if (isNull(S))
512 return true;
516 return QuotingType::Single;
513517 if (isBool(S))
514 return true;
518 return QuotingType::Single;
515519 if (isNumeric(S))
516 return true;
517
518 return false;
520 return QuotingType::Single;
521
522 QuotingType MaxQuotingNeeded = QuotingType::None;
523 for (unsigned char C : S) {
524 // Alphanum is safe.
525 if (isAlnum(C))
526 continue;
527
528 switch (C) {
529 // Safe scalar characters.
530 case '_':
531 case '-':
532 case '/':
533 case '^':
534 case '.':
535 case ',':
536 case ' ':
537 // TAB (0x9), LF (0xA), CR (0xD) and NEL (0x85) are allowed.
538 case 0x9:
539 case 0xA:
540 case 0xD:
541 case 0x85:
542 continue;
543 // DEL (0x7F) are excluded from the allowed character range.
544 case 0x7F:
545 return QuotingType::Double;
546 default: {
547 // C0 control block (0x0 - 0x1F) is excluded from the allowed character
548 // range.
549 if (C <= 0x1F)
550 return QuotingType::Double;
551 // C1 control block (0x80 - 0x9F) is excluded from the allowed character
552 // range.
553 if (C >= 0x80 && C <= 0x9F)
554 return QuotingType::Double;
555
556 // The character is not safe, at least simple quoting needed.
557 MaxQuotingNeeded = QuotingType::Single;
558 }
559 }
560 }
561
562 return MaxQuotingNeeded;
519563 }
520564
521565 template
580624 virtual bool bitSetMatch(const char*, bool) = 0;
581625 virtual void endBitSetScalar() = 0;
582626
583 virtual void scalarString(StringRef &, bool) = 0;
627 virtual void scalarString(StringRef &, QuotingType) = 0;
584628 virtual void blockScalarString(StringRef &) = 0;
585629
586630 virtual void setError(const Twine &) = 0;
910954 struct ScalarTraits {
911955 static void output(const bool &, void* , raw_ostream &);
912956 static StringRef input(StringRef, void *, bool &);
913 static bool mustQuote(StringRef) { return false; }
957 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
914958 };
915959
916960 template<>
917961 struct ScalarTraits {
918962 static void output(const StringRef &, void *, raw_ostream &);
919963 static StringRef input(StringRef, void *, StringRef &);
920 static bool mustQuote(StringRef S) { return needsQuotes(S); }
964 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
921965 };
922966
923967 template<>
924968 struct ScalarTraits {
925969 static void output(const std::string &, void *, raw_ostream &);
926970 static StringRef input(StringRef, void *, std::string &);
927 static bool mustQuote(StringRef S) { return needsQuotes(S); }
971 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
928972 };
929973
930974 template<>
931975 struct ScalarTraits {
932976 static void output(const uint8_t &, void *, raw_ostream &);
933977 static StringRef input(StringRef, void *, uint8_t &);
934 static bool mustQuote(StringRef) { return false; }
978 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
935979 };
936980
937981 template<>
938982 struct ScalarTraits {
939983 static void output(const uint16_t &, void *, raw_ostream &);
940984 static StringRef input(StringRef, void *, uint16_t &);
941 static bool mustQuote(StringRef) { return false; }
985 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
942986 };
943987
944988 template<>
945989 struct ScalarTraits {
946990 static void output(const uint32_t &, void *, raw_ostream &);
947991 static StringRef input(StringRef, void *, uint32_t &);
948 static bool mustQuote(StringRef) { return false; }
992 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
949993 };
950994
951995 template<>
952996 struct ScalarTraits {
953997 static void output(const uint64_t &, void *, raw_ostream &);
954998 static StringRef input(StringRef, void *, uint64_t &);
955 static bool mustQuote(StringRef) { return false; }
999 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
9561000 };
9571001
9581002 template<>
9591003 struct ScalarTraits {
9601004 static void output(const int8_t &, void *, raw_ostream &);
9611005 static StringRef input(StringRef, void *, int8_t &);
962 static bool mustQuote(StringRef) { return false; }
1006 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
9631007 };
9641008
9651009 template<>
9661010 struct ScalarTraits {
9671011 static void output(const int16_t &, void *, raw_ostream &);
9681012 static StringRef input(StringRef, void *, int16_t &);
969 static bool mustQuote(StringRef) { return false; }
1013 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
9701014 };
9711015
9721016 template<>
9731017 struct ScalarTraits {
9741018 static void output(const int32_t &, void *, raw_ostream &);
9751019 static StringRef input(StringRef, void *, int32_t &);
976 static bool mustQuote(StringRef) { return false; }
1020 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
9771021 };
9781022
9791023 template<>
9801024 struct ScalarTraits {
9811025 static void output(const int64_t &, void *, raw_ostream &);
9821026 static StringRef input(StringRef, void *, int64_t &);
983 static bool mustQuote(StringRef) { return false; }
1027 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
9841028 };
9851029
9861030 template<>
9871031 struct ScalarTraits {
9881032 static void output(const float &, void *, raw_ostream &);
9891033 static StringRef input(StringRef, void *, float &);
990 static bool mustQuote(StringRef) { return false; }
1034 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
9911035 };
9921036
9931037 template<>
9941038 struct ScalarTraits {
9951039 static void output(const double &, void *, raw_ostream &);
9961040 static StringRef input(StringRef, void *, double &);
997 static bool mustQuote(StringRef) { return false; }
1041 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
9981042 };
9991043
10001044 // For endian types, we just use the existing ScalarTraits for the underlying
10181062 return R;
10191063 }
10201064
1021 static bool mustQuote(StringRef Str) {
1065 static QuotingType mustQuote(StringRef Str) {
10221066 return ScalarTraits::mustQuote(Str);
10231067 }
10241068 };
11471191 bool beginBitSetScalar(bool &) override;
11481192 bool bitSetMatch(const char *, bool ) override;
11491193 void endBitSetScalar() override;
1150 void scalarString(StringRef &, bool) override;
1194 void scalarString(StringRef &, QuotingType) override;
11511195 void blockScalarString(StringRef &) override;
11521196 void setError(const Twine &message) override;
11531197 bool canElideEmptySequence() override;
12921336 bool beginBitSetScalar(bool &) override;
12931337 bool bitSetMatch(const char *, bool ) override;
12941338 void endBitSetScalar() override;
1295 void scalarString(StringRef &, bool) override;
1339 void scalarString(StringRef &, QuotingType) override;
12961340 void blockScalarString(StringRef &) override;
12971341 void setError(const Twine &message) override;
12981342 bool canElideEmptySequence() override;
13701414 struct ScalarTraits {
13711415 static void output(const Hex8 &, void *, raw_ostream &);
13721416 static StringRef input(StringRef, void *, Hex8 &);
1373 static bool mustQuote(StringRef) { return false; }
1417 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
13741418 };
13751419
13761420 template<>
13771421 struct ScalarTraits {
13781422 static void output(const Hex16 &, void *, raw_ostream &);
13791423 static StringRef input(StringRef, void *, Hex16 &);
1380 static bool mustQuote(StringRef) { return false; }
1424 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
13811425 };
13821426
13831427 template<>
13841428 struct ScalarTraits {
13851429 static void output(const Hex32 &, void *, raw_ostream &);
13861430 static StringRef input(StringRef, void *, Hex32 &);
1387 static bool mustQuote(StringRef) { return false; }
1431 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
13881432 };
13891433
13901434 template<>
13911435 struct ScalarTraits {
13921436 static void output(const Hex64 &, void *, raw_ostream &);
13931437 static StringRef input(StringRef, void *, Hex64 &);
1394 static bool mustQuote(StringRef) { return false; }
1438 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
13951439 };
13961440
13971441 // Define non-member operator>> so that Input can stream in a document list.
16801724 template <> struct ScalarTraits { \
16811725 static void output(const Type &Value, void *ctx, raw_ostream &Out); \
16821726 static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
1683 static bool mustQuote(StringRef) { return MustQuote; } \
1727 static QuotingType mustQuote(StringRef) { return MustQuote; } \
16841728 }; \
16851729 } \
16861730 }
6565 LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport)
6666 LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData)
6767
68 LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false)
68 LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None)
6969 LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
7070 LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
7171 LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)
4141 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
4242
4343 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
44 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
45 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
44 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
45 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
4646
4747 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
4848 LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
6161
6262 LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
6363
64 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, true)
64 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
6565
6666 StringRef ScalarTraits::input(StringRef S, void *V, TypeName &T) {
6767 return ScalarTraits::input(S, V, T.value);
4747 LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)
4848 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
4949
50 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
51 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
50 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
51 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
5252
5353 LLVM_YAML_DECLARE_ENUM_TRAITS(TypeLeafKind)
5454 LLVM_YAML_DECLARE_ENUM_TRAITS(PointerToMemberRepresentation)
5151 return StringRef();
5252 }
5353
54 bool ScalarTraits::mustQuote(StringRef S) { return needsQuotes(S); }
54 QuotingType ScalarTraits::mustQuote(StringRef S) {
55 return needsQuotes(S);
56 }
5557
5658 void ScalarTraits::output(const uuid_t &Val, void *, raw_ostream &Out) {
5759 Out.write_uuid(Val);
7476 return StringRef();
7577 }
7678
77 bool ScalarTraits::mustQuote(StringRef S) { return needsQuotes(S); }
79 QuotingType ScalarTraits::mustQuote(StringRef S) {
80 return needsQuotes(S);
81 }
7882
7983 void MappingTraits::mapping(
8084 IO &IO, MachOYAML::FileHeader &FileHdr) {
167167 const char *delim = "";
168168 for (const Statistic *Stat : Stats.Stats) {
169169 OS << delim;
170 assert(!yaml::needsQuotes(Stat->getDebugType()) &&
170 assert(yaml::needsQuotes(Stat->getDebugType()) == yaml::QuotingType::None &&
171171 "Statistic group/type name is simple.");
172 assert(!yaml::needsQuotes(Stat->getName()) && "Statistic name is simple");
172 assert(yaml::needsQuotes(Stat->getName()) == yaml::QuotingType::None &&
173 "Statistic name is simple");
173174 OS << "\t\"" << Stat->getDebugType() << '.' << Stat->getName() << "\": "
174175 << Stat->getValue();
175176 delim = ",\n";
361361
362362 void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R,
363363 const char *suffix, double Value) {
364 assert(!yaml::needsQuotes(Name) && "TimerGroup name needs no quotes");
365 assert(!yaml::needsQuotes(R.Name) && "Timer name needs no quotes");
364 assert(yaml::needsQuotes(Name) == yaml::QuotingType::None &&
365 "TimerGroup name needs no quotes");
366 assert(yaml::needsQuotes(R.Name) == yaml::QuotingType::None &&
367 "Timer name needs no quotes");
366368 OS << "\t\"time." << Name << '.' << R.Name << suffix << "\": " << Value;
367369 }
368370
1818 #include "llvm/Support/Format.h"
1919 #include "llvm/Support/LineIterator.h"
2020 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/Unicode.h"
2122 #include "llvm/Support/YAMLParser.h"
2223 #include "llvm/Support/raw_ostream.h"
2324 #include
329330 }
330331 }
331332
332 void Input::scalarString(StringRef &S, bool) {
333 void Input::scalarString(StringRef &S, QuotingType) {
333334 if (ScalarHNode *SN = dyn_cast(CurrentNode)) {
334335 S = SN->value();
335336 } else {
337338 }
338339 }
339340
340 void Input::blockScalarString(StringRef &S) { scalarString(S, false); }
341 void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
341342
342343 void Input::setError(HNode *hnode, const Twine &message) {
343344 assert(hnode && "HNode must not be NULL");
616617 this->outputUpToEndOfLine(" ]");
617618 }
618619
619 void Output::scalarString(StringRef &S, bool MustQuote) {
620 void Output::scalarString(StringRef &S, QuotingType MustQuote) {
620621 this->newLineCheck();
621622 if (S.empty()) {
622623 // Print '' for the empty string because leaving the field empty is not
624625 this->outputUpToEndOfLine("''");
625626 return;
626627 }
627 if (!MustQuote) {
628 if (MustQuote == QuotingType::None) {
628629 // Only quote if we must.
629630 this->outputUpToEndOfLine(S);
630631 return;
631632 }
633
632634 unsigned i = 0;
633635 unsigned j = 0;
634636 unsigned End = S.size();
635 output("'"); // Starting single quote.
636637 const char *Base = S.data();
638
639 const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
640 const char QuoteChar = MustQuote == QuotingType::Single ? '\'' : '"';
641
642 output(Quote); // Starting quote.
643
644 // When using single-quoted strings, any single quote ' must be doubled to be
645 // escaped.
646 // When using double-quoted strings, print \x + hex for non-printable ASCII
647 // characters, and escape double quotes.
637648 while (j < End) {
638 // Escape a single quote by doubling it.
639 if (S[j] == '\'') {
640 output(StringRef(&Base[i], j - i + 1));
641 output("'");
649 if (S[j] == QuoteChar) { // Escape quotes.
650 output(StringRef(&Base[i], j - i)); // "flush".
651 if (MustQuote == QuotingType::Double) { // Print it as \"
652 output(StringLiteral("\\"));
653 output(StringRef(Quote, 1));
654 } else { // Single
655 output(StringLiteral("''")); // Print it as ''
656 }
642657 i = j + 1;
658 } else if (MustQuote == QuotingType::Double &&
659 !sys::unicode::isPrintable(S[j])) {
660 output(StringRef(&Base[i], j - i)); // "flush"
661 output(StringLiteral("\\x"));
662
663 // Output the byte 0x0F as \x0f.
664 auto FormattedHex = format_hex_no_prefix(S[j], 2);
665 Out << FormattedHex;
666 Column += 4; // one for the '\', one for the 'x', and two for the hex
667
668 i = j + 1;
643669 }
644670 ++j;
645671 }
646672 output(StringRef(&Base[i], j - i));
647 this->outputUpToEndOfLine("'"); // Ending single quote.
673 this->outputUpToEndOfLine(Quote); // Ending quote.
648674 }
649675
650676 void Output::blockScalarString(StringRef &S) {
0 ; RUN: llc -mtriple=x86_64-unknown-unknown -stop-after branch-folder -o - %s 2>&1 | FileCheck %s
1
2 define void @"\01?f@@YAXXZ"() {
3 ; CHECK: name: "\x01?f@@YAXXZ"
4 ret void
5 }
231231 template <> struct ScalarTraits {
232232 static void output(const Triple &val, void *, raw_ostream &out);
233233 static StringRef input(StringRef scalar, void *, Triple &value);
234 static bool mustQuote(StringRef) { return true; }
234 static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
235235 };
236236
237237 template <>
859859 return "malformed by";
860860 }
861861 }
862 static bool mustQuote(StringRef) { return true; }
862 static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
863863 };
864864 }
865865 }
10631063 return StringRef();
10641064 }
10651065
1066 static bool mustQuote(StringRef) { return false; }
1066 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
10671067 };
10681068
10691069 template <> struct ScalarTraits {
10741074 static StringRef input(StringRef S, void *Ctx, MyString &V) {
10751075 return Impl::input(S, Ctx, V.value);
10761076 }
1077 static bool mustQuote(StringRef S) { return Impl::mustQuote(S); }
1077 static QuotingType mustQuote(StringRef S) {
1078 return Impl::mustQuote(S);
1079 }
10781080 };
10791081 }
10801082 }
22312233 return "";
22322234 }
22332235
2234 static bool mustQuote(StringRef S) { return false; }
2236 static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
22352237 };
22362238 }
22372239 }
24542456 yin >> Data;
24552457 EXPECT_TRUE((bool)yin.error());
24562458 }
2459
2460 TEST(YAMLIO, TestEscapedSingleQuote) {
2461 std::string Id = "@abc@";
2462
2463 std::string out;
2464 llvm::raw_string_ostream ostr(out);
2465 Output xout(ostr, nullptr, 0);
2466
2467 llvm::yaml::EmptyContext Ctx;
2468 yamlize(xout, Id, true, Ctx);
2469
2470 ostr.flush();
2471 EXPECT_EQ("'@abc@'", out);
2472 }
2473
2474 TEST(YAMLIO, TestEscapedNoQuote) {
2475 std::string Id = "abc/";
2476
2477 std::string out;
2478 llvm::raw_string_ostream ostr(out);
2479 Output xout(ostr, nullptr, 0);
2480
2481 llvm::yaml::EmptyContext Ctx;
2482 yamlize(xout, Id, true, Ctx);
2483
2484 ostr.flush();
2485 EXPECT_EQ("abc/", out);
2486 }
2487
2488 TEST(YAMLIO, TestEscapedDoubleQuoteNonPrintable) {
2489 std::string Id = "\01@abc@";
2490
2491 std::string out;
2492 llvm::raw_string_ostream ostr(out);
2493 Output xout(ostr, nullptr, 0);
2494
2495 llvm::yaml::EmptyContext Ctx;
2496 yamlize(xout, Id, true, Ctx);
2497
2498 ostr.flush();
2499 EXPECT_EQ("\"\\x01@abc@\"", out);
2500 }
2501
2502 TEST(YAMLIO, TestEscapedDoubleQuoteInsideSingleQuote) {
2503 std::string Id = "abc\"fdf";
2504
2505 std::string out;
2506 llvm::raw_string_ostream ostr(out);
2507 Output xout(ostr, nullptr, 0);
2508
2509 llvm::yaml::EmptyContext Ctx;
2510 yamlize(xout, Id, true, Ctx);
2511
2512 ostr.flush();
2513 EXPECT_EQ("'abc\"fdf'", out);
2514 }
2515
2516 TEST(YAMLIO, TestEscapedDoubleQuoteInsideDoubleQuote) {
2517 std::string Id = "\01bc\"fdf";
2518
2519 std::string out;
2520 llvm::raw_string_ostream ostr(out);
2521 Output xout(ostr, nullptr, 0);
2522
2523 llvm::yaml::EmptyContext Ctx;
2524 yamlize(xout, Id, true, Ctx);
2525
2526 ostr.flush();
2527 EXPECT_EQ("\"\\x01bc\\\"fdf\"", out);
2528 }
2529
2530 TEST(YAMLIO, TestEscapedSingleQuoteInsideSingleQuote) {
2531 std::string Id = "abc'fdf";
2532
2533 std::string out;
2534 llvm::raw_string_ostream ostr(out);
2535 Output xout(ostr, nullptr, 0);
2536
2537 llvm::yaml::EmptyContext Ctx;
2538 yamlize(xout, Id, true, Ctx);
2539
2540 ostr.flush();
2541 EXPECT_EQ("'abc''fdf'", out);
2542 }