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