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