LCOV - code coverage report
Current view: top level - lib/Support - YAMLTraits.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 539 567 95.1 %
Date: 2018-06-17 00:07:59 Functions: 111 118 94.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13