xref: /freebsd/contrib/llvm-project/llvm/lib/Support/YAMLTraits.cpp (revision 02e9120893770924227138ba49df1edb3896112a)
1 //===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Support/YAMLTraits.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/Support/Casting.h"
16 #include "llvm/Support/Errc.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/LineIterator.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/VersionTuple.h"
22 #include "llvm/Support/YAMLParser.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include <algorithm>
25 #include <cassert>
26 #include <cstdint>
27 #include <cstring>
28 #include <string>
29 #include <vector>
30 
31 using namespace llvm;
32 using namespace yaml;
33 
34 //===----------------------------------------------------------------------===//
35 //  IO
36 //===----------------------------------------------------------------------===//
37 
38 IO::IO(void *Context) : Ctxt(Context) {}
39 
40 IO::~IO() = default;
41 
42 void *IO::getContext() const {
43   return Ctxt;
44 }
45 
46 void IO::setContext(void *Context) {
47   Ctxt = Context;
48 }
49 
50 void IO::setAllowUnknownKeys(bool Allow) {
51   llvm_unreachable("Only supported for Input");
52 }
53 
54 //===----------------------------------------------------------------------===//
55 //  Input
56 //===----------------------------------------------------------------------===//
57 
58 Input::Input(StringRef InputContent, void *Ctxt,
59              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
60     : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
61   if (DiagHandler)
62     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
63   DocIterator = Strm->begin();
64 }
65 
66 Input::Input(MemoryBufferRef Input, void *Ctxt,
67              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
68     : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
69   if (DiagHandler)
70     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
71   DocIterator = Strm->begin();
72 }
73 
74 Input::~Input() = default;
75 
76 std::error_code Input::error() { return EC; }
77 
78 // Pin the vtables to this file.
79 void Input::HNode::anchor() {}
80 void Input::EmptyHNode::anchor() {}
81 void Input::ScalarHNode::anchor() {}
82 void Input::MapHNode::anchor() {}
83 void Input::SequenceHNode::anchor() {}
84 
85 bool Input::outputting() const {
86   return false;
87 }
88 
89 bool Input::setCurrentDocument() {
90   if (DocIterator != Strm->end()) {
91     Node *N = DocIterator->getRoot();
92     if (!N) {
93       EC = make_error_code(errc::invalid_argument);
94       return false;
95     }
96 
97     if (isa<NullNode>(N)) {
98       // Empty files are allowed and ignored
99       ++DocIterator;
100       return setCurrentDocument();
101     }
102     TopNode = createHNodes(N);
103     CurrentNode = TopNode.get();
104     return true;
105   }
106   return false;
107 }
108 
109 bool Input::nextDocument() {
110   return ++DocIterator != Strm->end();
111 }
112 
113 const Node *Input::getCurrentNode() const {
114   return CurrentNode ? CurrentNode->_node : nullptr;
115 }
116 
117 bool Input::mapTag(StringRef Tag, bool Default) {
118   // CurrentNode can be null if setCurrentDocument() was unable to
119   // parse the document because it was invalid or empty.
120   if (!CurrentNode)
121     return false;
122 
123   std::string foundTag = CurrentNode->_node->getVerbatimTag();
124   if (foundTag.empty()) {
125     // If no tag found and 'Tag' is the default, say it was found.
126     return Default;
127   }
128   // Return true iff found tag matches supplied tag.
129   return Tag.equals(foundTag);
130 }
131 
132 void Input::beginMapping() {
133   if (EC)
134     return;
135   // CurrentNode can be null if the document is empty.
136   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
137   if (MN) {
138     MN->ValidKeys.clear();
139   }
140 }
141 
142 std::vector<StringRef> Input::keys() {
143   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
144   std::vector<StringRef> Ret;
145   if (!MN) {
146     setError(CurrentNode, "not a mapping");
147     return Ret;
148   }
149   for (auto &P : MN->Mapping)
150     Ret.push_back(P.first());
151   return Ret;
152 }
153 
154 bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
155                          void *&SaveInfo) {
156   UseDefault = false;
157   if (EC)
158     return false;
159 
160   // CurrentNode is null for empty documents, which is an error in case required
161   // nodes are present.
162   if (!CurrentNode) {
163     if (Required)
164       EC = make_error_code(errc::invalid_argument);
165     return false;
166   }
167 
168   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
169   if (!MN) {
170     if (Required || !isa<EmptyHNode>(CurrentNode))
171       setError(CurrentNode, "not a mapping");
172     else
173       UseDefault = true;
174     return false;
175   }
176   MN->ValidKeys.push_back(Key);
177   HNode *Value = MN->Mapping[Key].first.get();
178   if (!Value) {
179     if (Required)
180       setError(CurrentNode, Twine("missing required key '") + Key + "'");
181     else
182       UseDefault = true;
183     return false;
184   }
185   SaveInfo = CurrentNode;
186   CurrentNode = Value;
187   return true;
188 }
189 
190 void Input::postflightKey(void *saveInfo) {
191   CurrentNode = reinterpret_cast<HNode *>(saveInfo);
192 }
193 
194 void Input::endMapping() {
195   if (EC)
196     return;
197   // CurrentNode can be null if the document is empty.
198   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
199   if (!MN)
200     return;
201   for (const auto &NN : MN->Mapping) {
202     if (!is_contained(MN->ValidKeys, NN.first())) {
203       const SMRange &ReportLoc = NN.second.second;
204       if (!AllowUnknownKeys) {
205         setError(ReportLoc, Twine("unknown key '") + NN.first() + "'");
206         break;
207       } else
208         reportWarning(ReportLoc, Twine("unknown key '") + NN.first() + "'");
209     }
210   }
211 }
212 
213 void Input::beginFlowMapping() { beginMapping(); }
214 
215 void Input::endFlowMapping() { endMapping(); }
216 
217 unsigned Input::beginSequence() {
218   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
219     return SQ->Entries.size();
220   if (isa<EmptyHNode>(CurrentNode))
221     return 0;
222   // Treat case where there's a scalar "null" value as an empty sequence.
223   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
224     if (isNull(SN->value()))
225       return 0;
226   }
227   // Any other type of HNode is an error.
228   setError(CurrentNode, "not a sequence");
229   return 0;
230 }
231 
232 void Input::endSequence() {
233 }
234 
235 bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
236   if (EC)
237     return false;
238   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
239     SaveInfo = CurrentNode;
240     CurrentNode = SQ->Entries[Index].get();
241     return true;
242   }
243   return false;
244 }
245 
246 void Input::postflightElement(void *SaveInfo) {
247   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
248 }
249 
250 unsigned Input::beginFlowSequence() { return beginSequence(); }
251 
252 bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
253   if (EC)
254     return false;
255   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
256     SaveInfo = CurrentNode;
257     CurrentNode = SQ->Entries[index].get();
258     return true;
259   }
260   return false;
261 }
262 
263 void Input::postflightFlowElement(void *SaveInfo) {
264   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
265 }
266 
267 void Input::endFlowSequence() {
268 }
269 
270 void Input::beginEnumScalar() {
271   ScalarMatchFound = false;
272 }
273 
274 bool Input::matchEnumScalar(const char *Str, bool) {
275   if (ScalarMatchFound)
276     return false;
277   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
278     if (SN->value().equals(Str)) {
279       ScalarMatchFound = true;
280       return true;
281     }
282   }
283   return false;
284 }
285 
286 bool Input::matchEnumFallback() {
287   if (ScalarMatchFound)
288     return false;
289   ScalarMatchFound = true;
290   return true;
291 }
292 
293 void Input::endEnumScalar() {
294   if (!ScalarMatchFound) {
295     setError(CurrentNode, "unknown enumerated scalar");
296   }
297 }
298 
299 bool Input::beginBitSetScalar(bool &DoClear) {
300   BitValuesUsed.clear();
301   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
302     BitValuesUsed.resize(SQ->Entries.size());
303   } else {
304     setError(CurrentNode, "expected sequence of bit values");
305   }
306   DoClear = true;
307   return true;
308 }
309 
310 bool Input::bitSetMatch(const char *Str, bool) {
311   if (EC)
312     return false;
313   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
314     unsigned Index = 0;
315     for (auto &N : SQ->Entries) {
316       if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
317         if (SN->value().equals(Str)) {
318           BitValuesUsed[Index] = true;
319           return true;
320         }
321       } else {
322         setError(CurrentNode, "unexpected scalar in sequence of bit values");
323       }
324       ++Index;
325     }
326   } else {
327     setError(CurrentNode, "expected sequence of bit values");
328   }
329   return false;
330 }
331 
332 void Input::endBitSetScalar() {
333   if (EC)
334     return;
335   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
336     assert(BitValuesUsed.size() == SQ->Entries.size());
337     for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
338       if (!BitValuesUsed[i]) {
339         setError(SQ->Entries[i].get(), "unknown bit value");
340         return;
341       }
342     }
343   }
344 }
345 
346 void Input::scalarString(StringRef &S, QuotingType) {
347   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
348     S = SN->value();
349   } else {
350     setError(CurrentNode, "unexpected scalar");
351   }
352 }
353 
354 void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
355 
356 void Input::scalarTag(std::string &Tag) {
357   Tag = CurrentNode->_node->getVerbatimTag();
358 }
359 
360 void Input::setError(HNode *hnode, const Twine &message) {
361   assert(hnode && "HNode must not be NULL");
362   setError(hnode->_node, message);
363 }
364 
365 NodeKind Input::getNodeKind() {
366   if (isa<ScalarHNode>(CurrentNode))
367     return NodeKind::Scalar;
368   else if (isa<MapHNode>(CurrentNode))
369     return NodeKind::Map;
370   else if (isa<SequenceHNode>(CurrentNode))
371     return NodeKind::Sequence;
372   llvm_unreachable("Unsupported node kind");
373 }
374 
375 void Input::setError(Node *node, const Twine &message) {
376   Strm->printError(node, message);
377   EC = make_error_code(errc::invalid_argument);
378 }
379 
380 void Input::setError(const SMRange &range, const Twine &message) {
381   Strm->printError(range, message);
382   EC = make_error_code(errc::invalid_argument);
383 }
384 
385 void Input::reportWarning(HNode *hnode, const Twine &message) {
386   assert(hnode && "HNode must not be NULL");
387   Strm->printError(hnode->_node, message, SourceMgr::DK_Warning);
388 }
389 
390 void Input::reportWarning(Node *node, const Twine &message) {
391   Strm->printError(node, message, SourceMgr::DK_Warning);
392 }
393 
394 void Input::reportWarning(const SMRange &range, const Twine &message) {
395   Strm->printError(range, message, SourceMgr::DK_Warning);
396 }
397 
398 std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
399   SmallString<128> StringStorage;
400   switch (N->getType()) {
401   case Node::NK_Scalar: {
402     ScalarNode *SN = dyn_cast<ScalarNode>(N);
403     StringRef KeyStr = SN->getValue(StringStorage);
404     if (!StringStorage.empty()) {
405       // Copy string to permanent storage
406       KeyStr = StringStorage.str().copy(StringAllocator);
407     }
408     return std::make_unique<ScalarHNode>(N, KeyStr);
409   }
410   case Node::NK_BlockScalar: {
411     BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N);
412     StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
413     return std::make_unique<ScalarHNode>(N, ValueCopy);
414   }
415   case Node::NK_Sequence: {
416     SequenceNode *SQ = dyn_cast<SequenceNode>(N);
417     auto SQHNode = std::make_unique<SequenceHNode>(N);
418     for (Node &SN : *SQ) {
419       auto Entry = createHNodes(&SN);
420       if (EC)
421         break;
422       SQHNode->Entries.push_back(std::move(Entry));
423     }
424     return std::move(SQHNode);
425   }
426   case Node::NK_Mapping: {
427     MappingNode *Map = dyn_cast<MappingNode>(N);
428     auto mapHNode = std::make_unique<MapHNode>(N);
429     for (KeyValueNode &KVN : *Map) {
430       Node *KeyNode = KVN.getKey();
431       ScalarNode *Key = dyn_cast_or_null<ScalarNode>(KeyNode);
432       Node *Value = KVN.getValue();
433       if (!Key || !Value) {
434         if (!Key)
435           setError(KeyNode, "Map key must be a scalar");
436         if (!Value)
437           setError(KeyNode, "Map value must not be empty");
438         break;
439       }
440       StringStorage.clear();
441       StringRef KeyStr = Key->getValue(StringStorage);
442       if (!StringStorage.empty()) {
443         // Copy string to permanent storage
444         KeyStr = StringStorage.str().copy(StringAllocator);
445       }
446       if (mapHNode->Mapping.count(KeyStr))
447         // From YAML spec: "The content of a mapping node is an unordered set of
448         // key/value node pairs, with the restriction that each of the keys is
449         // unique."
450         setError(KeyNode, Twine("duplicated mapping key '") + KeyStr + "'");
451       auto ValueHNode = createHNodes(Value);
452       if (EC)
453         break;
454       mapHNode->Mapping[KeyStr] =
455           std::make_pair(std::move(ValueHNode), KeyNode->getSourceRange());
456     }
457     return std::move(mapHNode);
458   }
459   case Node::NK_Null:
460     return std::make_unique<EmptyHNode>(N);
461   default:
462     setError(N, "unknown node kind");
463     return nullptr;
464   }
465 }
466 
467 void Input::setError(const Twine &Message) {
468   setError(CurrentNode, Message);
469 }
470 
471 void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
472 
473 bool Input::canElideEmptySequence() {
474   return false;
475 }
476 
477 //===----------------------------------------------------------------------===//
478 //  Output
479 //===----------------------------------------------------------------------===//
480 
481 Output::Output(raw_ostream &yout, void *context, int WrapColumn)
482     : IO(context), Out(yout), WrapColumn(WrapColumn) {}
483 
484 Output::~Output() = default;
485 
486 bool Output::outputting() const {
487   return true;
488 }
489 
490 void Output::beginMapping() {
491   StateStack.push_back(inMapFirstKey);
492   PaddingBeforeContainer = Padding;
493   Padding = "\n";
494 }
495 
496 bool Output::mapTag(StringRef Tag, bool Use) {
497   if (Use) {
498     // If this tag is being written inside a sequence we should write the start
499     // of the sequence before writing the tag, otherwise the tag won't be
500     // attached to the element in the sequence, but rather the sequence itself.
501     bool SequenceElement = false;
502     if (StateStack.size() > 1) {
503       auto &E = StateStack[StateStack.size() - 2];
504       SequenceElement = inSeqAnyElement(E) || inFlowSeqAnyElement(E);
505     }
506     if (SequenceElement && StateStack.back() == inMapFirstKey) {
507       newLineCheck();
508     } else {
509       output(" ");
510     }
511     output(Tag);
512     if (SequenceElement) {
513       // If we're writing the tag during the first element of a map, the tag
514       // takes the place of the first element in the sequence.
515       if (StateStack.back() == inMapFirstKey) {
516         StateStack.pop_back();
517         StateStack.push_back(inMapOtherKey);
518       }
519       // Tags inside maps in sequences should act as keys in the map from a
520       // formatting perspective, so we always want a newline in a sequence.
521       Padding = "\n";
522     }
523   }
524   return Use;
525 }
526 
527 void Output::endMapping() {
528   // If we did not map anything, we should explicitly emit an empty map
529   if (StateStack.back() == inMapFirstKey) {
530     Padding = PaddingBeforeContainer;
531     newLineCheck();
532     output("{}");
533     Padding = "\n";
534   }
535   StateStack.pop_back();
536 }
537 
538 std::vector<StringRef> Output::keys() {
539   report_fatal_error("invalid call");
540 }
541 
542 bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
543                           bool &UseDefault, void *&SaveInfo) {
544   UseDefault = false;
545   SaveInfo = nullptr;
546   if (Required || !SameAsDefault || WriteDefaultValues) {
547     auto State = StateStack.back();
548     if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
549       flowKey(Key);
550     } else {
551       newLineCheck();
552       paddedKey(Key);
553     }
554     return true;
555   }
556   return false;
557 }
558 
559 void Output::postflightKey(void *) {
560   if (StateStack.back() == inMapFirstKey) {
561     StateStack.pop_back();
562     StateStack.push_back(inMapOtherKey);
563   } else if (StateStack.back() == inFlowMapFirstKey) {
564     StateStack.pop_back();
565     StateStack.push_back(inFlowMapOtherKey);
566   }
567 }
568 
569 void Output::beginFlowMapping() {
570   StateStack.push_back(inFlowMapFirstKey);
571   newLineCheck();
572   ColumnAtMapFlowStart = Column;
573   output("{ ");
574 }
575 
576 void Output::endFlowMapping() {
577   StateStack.pop_back();
578   outputUpToEndOfLine(" }");
579 }
580 
581 void Output::beginDocuments() {
582   outputUpToEndOfLine("---");
583 }
584 
585 bool Output::preflightDocument(unsigned index) {
586   if (index > 0)
587     outputUpToEndOfLine("\n---");
588   return true;
589 }
590 
591 void Output::postflightDocument() {
592 }
593 
594 void Output::endDocuments() {
595   output("\n...\n");
596 }
597 
598 unsigned Output::beginSequence() {
599   StateStack.push_back(inSeqFirstElement);
600   PaddingBeforeContainer = Padding;
601   Padding = "\n";
602   return 0;
603 }
604 
605 void Output::endSequence() {
606   // If we did not emit anything, we should explicitly emit an empty sequence
607   if (StateStack.back() == inSeqFirstElement) {
608     Padding = PaddingBeforeContainer;
609     newLineCheck(/*EmptySequence=*/true);
610     output("[]");
611     Padding = "\n";
612   }
613   StateStack.pop_back();
614 }
615 
616 bool Output::preflightElement(unsigned, void *&SaveInfo) {
617   SaveInfo = nullptr;
618   return true;
619 }
620 
621 void Output::postflightElement(void *) {
622   if (StateStack.back() == inSeqFirstElement) {
623     StateStack.pop_back();
624     StateStack.push_back(inSeqOtherElement);
625   } else if (StateStack.back() == inFlowSeqFirstElement) {
626     StateStack.pop_back();
627     StateStack.push_back(inFlowSeqOtherElement);
628   }
629 }
630 
631 unsigned Output::beginFlowSequence() {
632   StateStack.push_back(inFlowSeqFirstElement);
633   newLineCheck();
634   ColumnAtFlowStart = Column;
635   output("[ ");
636   NeedFlowSequenceComma = false;
637   return 0;
638 }
639 
640 void Output::endFlowSequence() {
641   StateStack.pop_back();
642   outputUpToEndOfLine(" ]");
643 }
644 
645 bool Output::preflightFlowElement(unsigned, void *&SaveInfo) {
646   if (NeedFlowSequenceComma)
647     output(", ");
648   if (WrapColumn && Column > WrapColumn) {
649     output("\n");
650     for (int i = 0; i < ColumnAtFlowStart; ++i)
651       output(" ");
652     Column = ColumnAtFlowStart;
653     output("  ");
654   }
655   SaveInfo = nullptr;
656   return true;
657 }
658 
659 void Output::postflightFlowElement(void *) {
660   NeedFlowSequenceComma = true;
661 }
662 
663 void Output::beginEnumScalar() {
664   EnumerationMatchFound = false;
665 }
666 
667 bool Output::matchEnumScalar(const char *Str, bool Match) {
668   if (Match && !EnumerationMatchFound) {
669     newLineCheck();
670     outputUpToEndOfLine(Str);
671     EnumerationMatchFound = true;
672   }
673   return false;
674 }
675 
676 bool Output::matchEnumFallback() {
677   if (EnumerationMatchFound)
678     return false;
679   EnumerationMatchFound = true;
680   return true;
681 }
682 
683 void Output::endEnumScalar() {
684   if (!EnumerationMatchFound)
685     llvm_unreachable("bad runtime enum value");
686 }
687 
688 bool Output::beginBitSetScalar(bool &DoClear) {
689   newLineCheck();
690   output("[ ");
691   NeedBitValueComma = false;
692   DoClear = false;
693   return true;
694 }
695 
696 bool Output::bitSetMatch(const char *Str, bool Matches) {
697   if (Matches) {
698     if (NeedBitValueComma)
699       output(", ");
700     output(Str);
701     NeedBitValueComma = true;
702   }
703   return false;
704 }
705 
706 void Output::endBitSetScalar() {
707   outputUpToEndOfLine(" ]");
708 }
709 
710 void Output::scalarString(StringRef &S, QuotingType MustQuote) {
711   newLineCheck();
712   if (S.empty()) {
713     // Print '' for the empty string because leaving the field empty is not
714     // allowed.
715     outputUpToEndOfLine("''");
716     return;
717   }
718   if (MustQuote == QuotingType::None) {
719     // Only quote if we must.
720     outputUpToEndOfLine(S);
721     return;
722   }
723 
724   const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
725   output(Quote); // Starting quote.
726 
727   // When using double-quoted strings (and only in that case), non-printable characters may be
728   // present, and will be escaped using a variety of unicode-scalar and special short-form
729   // escapes. This is handled in yaml::escape.
730   if (MustQuote == QuotingType::Double) {
731     output(yaml::escape(S, /* EscapePrintable= */ false));
732     outputUpToEndOfLine(Quote);
733     return;
734   }
735 
736   unsigned i = 0;
737   unsigned j = 0;
738   unsigned End = S.size();
739   const char *Base = S.data();
740 
741   // When using single-quoted strings, any single quote ' must be doubled to be escaped.
742   while (j < End) {
743     if (S[j] == '\'') {                    // Escape quotes.
744       output(StringRef(&Base[i], j - i));  // "flush".
745       output(StringLiteral("''"));         // Print it as ''
746       i = j + 1;
747     }
748     ++j;
749   }
750   output(StringRef(&Base[i], j - i));
751   outputUpToEndOfLine(Quote); // Ending quote.
752 }
753 
754 void Output::blockScalarString(StringRef &S) {
755   if (!StateStack.empty())
756     newLineCheck();
757   output(" |");
758   outputNewLine();
759 
760   unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
761 
762   auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
763   for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
764     for (unsigned I = 0; I < Indent; ++I) {
765       output("  ");
766     }
767     output(*Lines);
768     outputNewLine();
769   }
770 }
771 
772 void Output::scalarTag(std::string &Tag) {
773   if (Tag.empty())
774     return;
775   newLineCheck();
776   output(Tag);
777   output(" ");
778 }
779 
780 void Output::setError(const Twine &message) {
781 }
782 
783 bool Output::canElideEmptySequence() {
784   // Normally, with an optional key/value where the value is an empty sequence,
785   // the whole key/value can be not written.  But, that produces wrong yaml
786   // if the key/value is the only thing in the map and the map is used in
787   // a sequence.  This detects if the this sequence is the first key/value
788   // in map that itself is embedded in a sequence.
789   if (StateStack.size() < 2)
790     return true;
791   if (StateStack.back() != inMapFirstKey)
792     return true;
793   return !inSeqAnyElement(StateStack[StateStack.size() - 2]);
794 }
795 
796 void Output::output(StringRef s) {
797   Column += s.size();
798   Out << s;
799 }
800 
801 void Output::outputUpToEndOfLine(StringRef s) {
802   output(s);
803   if (StateStack.empty() || (!inFlowSeqAnyElement(StateStack.back()) &&
804                              !inFlowMapAnyKey(StateStack.back())))
805     Padding = "\n";
806 }
807 
808 void Output::outputNewLine() {
809   Out << "\n";
810   Column = 0;
811 }
812 
813 // if seq at top, indent as if map, then add "- "
814 // if seq in middle, use "- " if firstKey, else use "  "
815 //
816 
817 void Output::newLineCheck(bool EmptySequence) {
818   if (Padding != "\n") {
819     output(Padding);
820     Padding = {};
821     return;
822   }
823   outputNewLine();
824   Padding = {};
825 
826   if (StateStack.size() == 0 || EmptySequence)
827     return;
828 
829   unsigned Indent = StateStack.size() - 1;
830   bool OutputDash = false;
831 
832   if (StateStack.back() == inSeqFirstElement ||
833       StateStack.back() == inSeqOtherElement) {
834     OutputDash = true;
835   } else if ((StateStack.size() > 1) &&
836              ((StateStack.back() == inMapFirstKey) ||
837               inFlowSeqAnyElement(StateStack.back()) ||
838               (StateStack.back() == inFlowMapFirstKey)) &&
839              inSeqAnyElement(StateStack[StateStack.size() - 2])) {
840     --Indent;
841     OutputDash = true;
842   }
843 
844   for (unsigned i = 0; i < Indent; ++i) {
845     output("  ");
846   }
847   if (OutputDash) {
848     output("- ");
849   }
850 }
851 
852 void Output::paddedKey(StringRef key) {
853   output(key);
854   output(":");
855   const char *spaces = "                ";
856   if (key.size() < strlen(spaces))
857     Padding = &spaces[key.size()];
858   else
859     Padding = " ";
860 }
861 
862 void Output::flowKey(StringRef Key) {
863   if (StateStack.back() == inFlowMapOtherKey)
864     output(", ");
865   if (WrapColumn && Column > WrapColumn) {
866     output("\n");
867     for (int I = 0; I < ColumnAtMapFlowStart; ++I)
868       output(" ");
869     Column = ColumnAtMapFlowStart;
870     output("  ");
871   }
872   output(Key);
873   output(": ");
874 }
875 
876 NodeKind Output::getNodeKind() { report_fatal_error("invalid call"); }
877 
878 bool Output::inSeqAnyElement(InState State) {
879   return State == inSeqFirstElement || State == inSeqOtherElement;
880 }
881 
882 bool Output::inFlowSeqAnyElement(InState State) {
883   return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement;
884 }
885 
886 bool Output::inMapAnyKey(InState State) {
887   return State == inMapFirstKey || State == inMapOtherKey;
888 }
889 
890 bool Output::inFlowMapAnyKey(InState State) {
891   return State == inFlowMapFirstKey || State == inFlowMapOtherKey;
892 }
893 
894 //===----------------------------------------------------------------------===//
895 //  traits for built-in types
896 //===----------------------------------------------------------------------===//
897 
898 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
899   Out << (Val ? "true" : "false");
900 }
901 
902 StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
903   if (std::optional<bool> Parsed = parseBool(Scalar)) {
904     Val = *Parsed;
905     return StringRef();
906   }
907   return "invalid boolean";
908 }
909 
910 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
911                                      raw_ostream &Out) {
912   Out << Val;
913 }
914 
915 StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
916                                          StringRef &Val) {
917   Val = Scalar;
918   return StringRef();
919 }
920 
921 void ScalarTraits<std::string>::output(const std::string &Val, void *,
922                                        raw_ostream &Out) {
923   Out << Val;
924 }
925 
926 StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
927                                            std::string &Val) {
928   Val = Scalar.str();
929   return StringRef();
930 }
931 
932 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
933                                    raw_ostream &Out) {
934   // use temp uin32_t because ostream thinks uint8_t is a character
935   uint32_t Num = Val;
936   Out << Num;
937 }
938 
939 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
940   unsigned long long n;
941   if (getAsUnsignedInteger(Scalar, 0, n))
942     return "invalid number";
943   if (n > 0xFF)
944     return "out of range number";
945   Val = n;
946   return StringRef();
947 }
948 
949 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
950                                     raw_ostream &Out) {
951   Out << Val;
952 }
953 
954 StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
955                                         uint16_t &Val) {
956   unsigned long long n;
957   if (getAsUnsignedInteger(Scalar, 0, n))
958     return "invalid number";
959   if (n > 0xFFFF)
960     return "out of range number";
961   Val = n;
962   return StringRef();
963 }
964 
965 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
966                                     raw_ostream &Out) {
967   Out << Val;
968 }
969 
970 StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
971                                         uint32_t &Val) {
972   unsigned long long n;
973   if (getAsUnsignedInteger(Scalar, 0, n))
974     return "invalid number";
975   if (n > 0xFFFFFFFFUL)
976     return "out of range number";
977   Val = n;
978   return StringRef();
979 }
980 
981 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
982                                     raw_ostream &Out) {
983   Out << Val;
984 }
985 
986 StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
987                                         uint64_t &Val) {
988   unsigned long long N;
989   if (getAsUnsignedInteger(Scalar, 0, N))
990     return "invalid number";
991   Val = N;
992   return StringRef();
993 }
994 
995 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
996   // use temp in32_t because ostream thinks int8_t is a character
997   int32_t Num = Val;
998   Out << Num;
999 }
1000 
1001 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
1002   long long N;
1003   if (getAsSignedInteger(Scalar, 0, N))
1004     return "invalid number";
1005   if ((N > 127) || (N < -128))
1006     return "out of range number";
1007   Val = N;
1008   return StringRef();
1009 }
1010 
1011 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
1012                                    raw_ostream &Out) {
1013   Out << Val;
1014 }
1015 
1016 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
1017   long long N;
1018   if (getAsSignedInteger(Scalar, 0, N))
1019     return "invalid number";
1020   if ((N > INT16_MAX) || (N < INT16_MIN))
1021     return "out of range number";
1022   Val = N;
1023   return StringRef();
1024 }
1025 
1026 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
1027                                    raw_ostream &Out) {
1028   Out << Val;
1029 }
1030 
1031 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
1032   long long N;
1033   if (getAsSignedInteger(Scalar, 0, N))
1034     return "invalid number";
1035   if ((N > INT32_MAX) || (N < INT32_MIN))
1036     return "out of range number";
1037   Val = N;
1038   return StringRef();
1039 }
1040 
1041 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
1042                                    raw_ostream &Out) {
1043   Out << Val;
1044 }
1045 
1046 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
1047   long long N;
1048   if (getAsSignedInteger(Scalar, 0, N))
1049     return "invalid number";
1050   Val = N;
1051   return StringRef();
1052 }
1053 
1054 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
1055   Out << format("%g", Val);
1056 }
1057 
1058 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
1059   if (to_float(Scalar, Val))
1060     return StringRef();
1061   return "invalid floating point number";
1062 }
1063 
1064 void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
1065   Out << format("%g", Val);
1066 }
1067 
1068 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
1069   if (to_float(Scalar, Val))
1070     return StringRef();
1071   return "invalid floating point number";
1072 }
1073 
1074 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
1075   Out << format("0x%" PRIX8, (uint8_t)Val);
1076 }
1077 
1078 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
1079   unsigned long long n;
1080   if (getAsUnsignedInteger(Scalar, 0, n))
1081     return "invalid hex8 number";
1082   if (n > 0xFF)
1083     return "out of range hex8 number";
1084   Val = n;
1085   return StringRef();
1086 }
1087 
1088 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
1089   Out << format("0x%" PRIX16, (uint16_t)Val);
1090 }
1091 
1092 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
1093   unsigned long long n;
1094   if (getAsUnsignedInteger(Scalar, 0, n))
1095     return "invalid hex16 number";
1096   if (n > 0xFFFF)
1097     return "out of range hex16 number";
1098   Val = n;
1099   return StringRef();
1100 }
1101 
1102 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
1103   Out << format("0x%" PRIX32, (uint32_t)Val);
1104 }
1105 
1106 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
1107   unsigned long long n;
1108   if (getAsUnsignedInteger(Scalar, 0, n))
1109     return "invalid hex32 number";
1110   if (n > 0xFFFFFFFFUL)
1111     return "out of range hex32 number";
1112   Val = n;
1113   return StringRef();
1114 }
1115 
1116 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
1117   Out << format("0x%" PRIX64, (uint64_t)Val);
1118 }
1119 
1120 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
1121   unsigned long long Num;
1122   if (getAsUnsignedInteger(Scalar, 0, Num))
1123     return "invalid hex64 number";
1124   Val = Num;
1125   return StringRef();
1126 }
1127 
1128 void ScalarTraits<VersionTuple>::output(const VersionTuple &Val, void *,
1129                                         llvm::raw_ostream &Out) {
1130   Out << Val.getAsString();
1131 }
1132 
1133 StringRef ScalarTraits<VersionTuple>::input(StringRef Scalar, void *,
1134                                             VersionTuple &Val) {
1135   if (Val.tryParse(Scalar))
1136     return "invalid version format";
1137   return StringRef();
1138 }
1139