LCOV - code coverage report
Current view: top level - lib/Support - YAMLTraits.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 544 572 95.1 %
Date: 2018-09-23 13:06:45 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       10975 : IO::IO(void *Context) : Ctxt(Context) {}
      41             : 
      42             : IO::~IO() = default;
      43             : 
      44      490084 : void *IO::getContext() {
      45      490084 :   return Ctxt;
      46             : }
      47             : 
      48        3165 : void IO::setContext(void *Context) {
      49        3165 :   Ctxt = Context;
      50        3165 : }
      51             : 
      52             : //===----------------------------------------------------------------------===//
      53             : //  Input
      54             : //===----------------------------------------------------------------------===//
      55             : 
      56        3903 : Input::Input(StringRef InputContent, void *Ctxt,
      57        3903 :              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
      58        3903 :     : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
      59        3903 :   if (DiagHandler)
      60             :     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
      61        3903 :   DocIterator = Strm->begin();
      62        3903 : }
      63             : 
      64           3 : Input::Input(MemoryBufferRef Input, void *Ctxt,
      65           3 :              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
      66           3 :     : 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        7960 : 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     1441534 : bool Input::outputting() {
      84     1441534 :   return false;
      85             : }
      86             : 
      87       10445 : bool Input::setCurrentDocument() {
      88       10445 :   if (DocIterator != Strm->end()) {
      89        8187 :     Node *N = DocIterator->getRoot();
      90        8187 :     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        8186 :     if (isa<NullNode>(N)) {
      97             :       // Empty files are allowed and ignored
      98         516 :       ++DocIterator;
      99         516 :       return setCurrentDocument();
     100             :     }
     101       15340 :     TopNode = this->createHNodes(N);
     102        7670 :     CurrentNode = TopNode.get();
     103        7670 :     return true;
     104             :   }
     105             :   return false;
     106             : }
     107             : 
     108        6561 : bool Input::nextDocument() {
     109        6561 :   return ++DocIterator != Strm->end();
     110             : }
     111             : 
     112       42235 : const Node *Input::getCurrentNode() const {
     113       42235 :   return CurrentNode ? CurrentNode->_node : nullptr;
     114             : }
     115             : 
     116        3833 : bool Input::mapTag(StringRef Tag, bool Default) {
     117        3833 :   std::string foundTag = CurrentNode->_node->getVerbatimTag();
     118        3833 :   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       46258 : void Input::beginMapping() {
     127       46258 :   if (EC)
     128             :     return;
     129             :   // CurrentNode can be null if the document is empty.
     130       46255 :   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
     131             :   if (MN) {
     132       46183 :     MN->ValidKeys.clear();
     133             :   }
     134             : }
     135             : 
     136          85 : std::vector<StringRef> Input::keys() {
     137          85 :   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
     138             :   std::vector<StringRef> Ret;
     139          85 :   if (!MN) {
     140           0 :     setError(CurrentNode, "not a mapping");
     141           0 :     return Ret;
     142             :   }
     143         325 :   for (auto &P : MN->Mapping)
     144         155 :     Ret.push_back(P.first());
     145             :   return Ret;
     146             : }
     147             : 
     148      319564 : bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
     149             :                          void *&SaveInfo) {
     150      319564 :   UseDefault = false;
     151      319564 :   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      319500 :   if (!CurrentNode) {
     157           2 :     if (Required)
     158           1 :       EC = make_error_code(errc::invalid_argument);
     159           2 :     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           6 :     return false;
     167             :   }
     168      638984 :   MN->ValidKeys.push_back(Key);
     169      319492 :   HNode *Value = MN->Mapping[Key].get();
     170      319492 :   if (!Value) {
     171      154493 :     if (Required)
     172          22 :       setError(CurrentNode, Twine("missing required key '") + Key + "'");
     173             :     else
     174      154471 :       UseDefault = true;
     175      154493 :     return false;
     176             :   }
     177      164999 :   SaveInfo = CurrentNode;
     178      164999 :   CurrentNode = Value;
     179      164999 :   return true;
     180             : }
     181             : 
     182      164999 : void Input::postflightKey(void *saveInfo) {
     183      164999 :   CurrentNode = reinterpret_cast<HNode *>(saveInfo);
     184      164999 : }
     185             : 
     186       46258 : void Input::endMapping() {
     187       46258 :   if (EC)
     188             :     return;
     189             :   // CurrentNode can be null if the document is empty.
     190       46202 :   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
     191             :   if (!MN)
     192             :     return;
     193      410680 :   for (const auto &NN : MN->Mapping) {
     194      636862 :     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       16762 : void Input::beginFlowMapping() { beginMapping(); }
     202             : 
     203       16762 : void Input::endFlowMapping() { endMapping(); }
     204             : 
     205       11399 : unsigned Input::beginSequence() {
     206       11399 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
     207       18156 :     return SQ->Entries.size();
     208        2321 :   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       10479 : void Input::endSequence() {
     221       10479 : }
     222             : 
     223       33749 : bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
     224       33749 :   if (EC)
     225             :     return false;
     226       33749 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     227       33749 :     SaveInfo = CurrentNode;
     228       33749 :     CurrentNode = SQ->Entries[Index].get();
     229       33749 :     return true;
     230             :   }
     231             :   return false;
     232             : }
     233             : 
     234       33749 : void Input::postflightElement(void *SaveInfo) {
     235       33749 :   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
     236       33749 : }
     237             : 
     238         920 : unsigned Input::beginFlowSequence() { return beginSequence(); }
     239             : 
     240        8888 : bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
     241        8888 :   if (EC)
     242             :     return false;
     243        8888 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     244        8888 :     SaveInfo = CurrentNode;
     245        8888 :     CurrentNode = SQ->Entries[index].get();
     246        8888 :     return true;
     247             :   }
     248             :   return false;
     249             : }
     250             : 
     251        8888 : void Input::postflightFlowElement(void *SaveInfo) {
     252        8888 :   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
     253        8888 : }
     254             : 
     255         920 : void Input::endFlowSequence() {
     256         920 : }
     257             : 
     258       19820 : void Input::beginEnumScalar() {
     259       19820 :   ScalarMatchFound = false;
     260       19820 : }
     261             : 
     262     1071747 : bool Input::matchEnumScalar(const char *Str, bool) {
     263     1071747 :   if (ScalarMatchFound)
     264             :     return false;
     265      270929 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     266             :     if (SN->value().equals(Str)) {
     267       19786 :       ScalarMatchFound = true;
     268       19786 :       return true;
     269             :     }
     270             :   }
     271             :   return false;
     272             : }
     273             : 
     274        1790 : bool Input::matchEnumFallback() {
     275        1790 :   if (ScalarMatchFound)
     276             :     return false;
     277          32 :   ScalarMatchFound = true;
     278          32 :   return true;
     279             : }
     280             : 
     281       19820 : void Input::endEnumScalar() {
     282       19820 :   if (!ScalarMatchFound) {
     283           2 :     setError(CurrentNode, "unknown enumerated scalar");
     284             :   }
     285       19820 : }
     286             : 
     287        3374 : bool Input::beginBitSetScalar(bool &DoClear) {
     288        3374 :   BitValuesUsed.clear();
     289        3374 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     290        6748 :     BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
     291             :   } else {
     292           0 :     setError(CurrentNode, "expected sequence of bit values");
     293             :   }
     294        3374 :   DoClear = true;
     295        3374 :   return true;
     296             : }
     297             : 
     298       37183 : bool Input::bitSetMatch(const char *Str, bool) {
     299       37183 :   if (EC)
     300             :     return false;
     301       37183 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     302             :     unsigned Index = 0;
     303      105411 :     for (auto &N : SQ->Entries) {
     304             :       if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
     305             :         if (SN->value().equals(Str)) {
     306        5995 :           BitValuesUsed[Index] = true;
     307             :           return true;
     308             :         }
     309             :       } else {
     310           0 :         setError(CurrentNode, "unexpected scalar in sequence of bit values");
     311             :       }
     312       68228 :       ++Index;
     313             :     }
     314             :   } else {
     315           0 :     setError(CurrentNode, "expected sequence of bit values");
     316             :   }
     317             :   return false;
     318             : }
     319             : 
     320        3374 : void Input::endBitSetScalar() {
     321        3374 :   if (EC)
     322             :     return;
     323        3374 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     324             :     assert(BitValuesUsed.size() == SQ->Entries.size());
     325       12743 :     for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
     326       11992 :       if (!BitValuesUsed[i]) {
     327           1 :         setError(SQ->Entries[i].get(), "unknown bit value");
     328           1 :         return;
     329             :       }
     330             :     }
     331             :   }
     332             : }
     333             : 
     334      133616 : void Input::scalarString(StringRef &S, QuotingType) {
     335      133616 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     336      133616 :     S = SN->value();
     337             :   } else {
     338           0 :     setError(CurrentNode, "unexpected scalar");
     339             :   }
     340      133616 : }
     341             : 
     342        4453 : 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      221051 : std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
     355             :   SmallString<128> StringStorage;
     356             :   if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
     357      154591 :     StringRef KeyStr = SN->getValue(StringStorage);
     358      154591 :     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        5331 :     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       61217 :     for (Node &SN : *SQ) {
     369       48719 :       auto Entry = this->createHNodes(&SN);
     370       48719 :       if (EC)
     371             :         break;
     372       48719 :       SQHNode->Entries.push_back(std::move(Entry));
     373             :     }
     374             :     return std::move(SQHNode);
     375             :   } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
     376       46244 :     auto mapHNode = llvm::make_unique<MapHNode>(N);
     377      210906 :     for (KeyValueNode &KVN : *Map) {
     378      164664 :       Node *KeyNode = KVN.getKey();
     379             :       ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode);
     380      164664 :       Node *Value = KVN.getValue();
     381      164664 :       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      164662 :       StringRef KeyStr = Key->getValue(StringStorage);
     390      164662 :       if (!StringStorage.empty()) {
     391             :         // Copy string to permanent storage
     392           0 :         KeyStr = StringStorage.str().copy(StringAllocator);
     393             :       }
     394      164662 :       auto ValueHNode = this->createHNodes(Value);
     395      164662 :       if (EC)
     396             :         break;
     397      164662 :       mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
     398             :     }
     399             :     return std::move(mapHNode);
     400        2387 :   } 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       11288 : bool Input::canElideEmptySequence() {
     413       11288 :   return false;
     414             : }
     415             : 
     416             : //===----------------------------------------------------------------------===//
     417             : //  Output
     418             : //===----------------------------------------------------------------------===//
     419             : 
     420        7069 : Output::Output(raw_ostream &yout, void *context, int WrapColumn)
     421        7069 :     : IO(context), Out(yout), WrapColumn(WrapColumn) {}
     422             : 
     423             : Output::~Output() = default;
     424             : 
     425     1897146 : bool Output::outputting() {
     426     1897146 :   return true;
     427             : }
     428             : 
     429       55205 : void Output::beginMapping() {
     430       55205 :   StateStack.push_back(inMapFirstKey);
     431       55205 :   NeedsNewLine = true;
     432       55205 : }
     433             : 
     434        1419 : bool Output::mapTag(StringRef Tag, bool Use) {
     435        1419 :   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        1462 :         StateStack.size() > 1 && (StateStack[StateStack.size() - 2] == inSeq ||
     441             :           StateStack[StateStack.size() - 2] == inFlowSeq);
     442          50 :     if (SequenceElement && StateStack.back() == inMapFirstKey) {
     443          50 :       this->newLineCheck();
     444             :     } else {
     445         681 :       this->output(" ");
     446             :     }
     447         731 :     this->output(Tag);
     448         731 :     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          50 :       if (StateStack.back() == inMapFirstKey) {
     452          50 :         StateStack.pop_back();
     453          50 :         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          50 :       NeedsNewLine = true;
     458             :     }
     459             :   }
     460        1419 :   return Use;
     461             : }
     462             : 
     463       55205 : void Output::endMapping() {
     464             :   StateStack.pop_back();
     465       55205 : }
     466             : 
     467           0 : std::vector<StringRef> Output::keys() {
     468           0 :   report_fatal_error("invalid call");
     469             : }
     470             : 
     471      578508 : bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
     472             :                           bool &UseDefault, void *&) {
     473      578508 :   UseDefault = false;
     474      578508 :   if (Required || !SameAsDefault || WriteDefaultValues) {
     475      427322 :     auto State = StateStack.back();
     476      427322 :     if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
     477       81551 :       flowKey(Key);
     478             :     } else {
     479      345771 :       this->newLineCheck();
     480      345771 :       this->paddedKey(Key);
     481             :     }
     482      427322 :     return true;
     483             :   }
     484             :   return false;
     485             : }
     486             : 
     487      427322 : void Output::postflightKey(void *) {
     488      427322 :   if (StateStack.back() == inMapFirstKey) {
     489       55002 :     StateStack.pop_back();
     490       55002 :     StateStack.push_back(inMapOtherKey);
     491      372320 :   } else if (StateStack.back() == inFlowMapFirstKey) {
     492       24906 :     StateStack.pop_back();
     493       24906 :     StateStack.push_back(inFlowMapOtherKey);
     494             :   }
     495      427322 : }
     496             : 
     497       24906 : void Output::beginFlowMapping() {
     498       24906 :   StateStack.push_back(inFlowMapFirstKey);
     499       24906 :   this->newLineCheck();
     500       24906 :   ColumnAtMapFlowStart = Column;
     501       24906 :   output("{ ");
     502       24906 : }
     503             : 
     504       24906 : void Output::endFlowMapping() {
     505             :   StateStack.pop_back();
     506       24906 :   this->outputUpToEndOfLine(" }");
     507       24906 : }
     508             : 
     509        7241 : void Output::beginDocuments() {
     510        7241 :   this->outputUpToEndOfLine("---");
     511        7241 : }
     512             : 
     513        7243 : bool Output::preflightDocument(unsigned index) {
     514        7243 :   if (index > 0)
     515           2 :     this->outputUpToEndOfLine("\n---");
     516        7243 :   return true;
     517             : }
     518             : 
     519        7243 : void Output::postflightDocument() {
     520        7243 : }
     521             : 
     522        7241 : void Output::endDocuments() {
     523        7241 :   output("\n...\n");
     524        7241 : }
     525             : 
     526       30777 : unsigned Output::beginSequence() {
     527       30777 :   StateStack.push_back(inSeq);
     528       30777 :   NeedsNewLine = true;
     529       30777 :   return 0;
     530             : }
     531             : 
     532       30777 : void Output::endSequence() {
     533             :   StateStack.pop_back();
     534       30777 : }
     535             : 
     536       69684 : bool Output::preflightElement(unsigned, void *&) {
     537       69684 :   return true;
     538             : }
     539             : 
     540       69684 : void Output::postflightElement(void *) {
     541       69684 : }
     542             : 
     543        1937 : unsigned Output::beginFlowSequence() {
     544        1937 :   StateStack.push_back(inFlowSeq);
     545        1937 :   this->newLineCheck();
     546        1937 :   ColumnAtFlowStart = Column;
     547        1937 :   output("[ ");
     548        1937 :   NeedFlowSequenceComma = false;
     549        1937 :   return 0;
     550             : }
     551             : 
     552        1937 : void Output::endFlowSequence() {
     553             :   StateStack.pop_back();
     554        1937 :   this->outputUpToEndOfLine(" ]");
     555        1937 : }
     556             : 
     557        8475 : bool Output::preflightFlowElement(unsigned, void *&) {
     558        8475 :   if (NeedFlowSequenceComma)
     559        6563 :     output(", ");
     560        8475 :   if (WrapColumn && Column > WrapColumn) {
     561         337 :     output("\n");
     562        7457 :     for (int i = 0; i < ColumnAtFlowStart; ++i)
     563        7120 :       output(" ");
     564         337 :     Column = ColumnAtFlowStart;
     565         337 :     output("  ");
     566             :   }
     567        8475 :   return true;
     568             : }
     569             : 
     570        8475 : void Output::postflightFlowElement(void *) {
     571        8475 :   NeedFlowSequenceComma = true;
     572        8475 : }
     573             : 
     574       49246 : void Output::beginEnumScalar() {
     575       49246 :   EnumerationMatchFound = false;
     576       49246 : }
     577             : 
     578     1100315 : bool Output::matchEnumScalar(const char *Str, bool Match) {
     579     1100315 :   if (Match && !EnumerationMatchFound) {
     580       49223 :     this->newLineCheck();
     581       49223 :     this->outputUpToEndOfLine(Str);
     582       49223 :     EnumerationMatchFound = true;
     583             :   }
     584     1100315 :   return false;
     585             : }
     586             : 
     587        6796 : bool Output::matchEnumFallback() {
     588        6796 :   if (EnumerationMatchFound)
     589             :     return false;
     590          23 :   EnumerationMatchFound = true;
     591          23 :   return true;
     592             : }
     593             : 
     594       49246 : void Output::endEnumScalar() {
     595       49246 :   if (!EnumerationMatchFound)
     596           0 :     llvm_unreachable("bad runtime enum value");
     597       49246 : }
     598             : 
     599        1425 : bool Output::beginBitSetScalar(bool &DoClear) {
     600        1425 :   this->newLineCheck();
     601        1425 :   output("[ ");
     602        1425 :   NeedBitValueComma = false;
     603        1425 :   DoClear = false;
     604        1425 :   return true;
     605             : }
     606             : 
     607       12173 : bool Output::bitSetMatch(const char *Str, bool Matches) {
     608       12173 :   if (Matches) {
     609        2624 :     if (NeedBitValueComma)
     610        1462 :       output(", ");
     611        2624 :     this->output(Str);
     612        2624 :     NeedBitValueComma = true;
     613             :   }
     614       12173 :   return false;
     615             : }
     616             : 
     617        1425 : void Output::endBitSetScalar() {
     618        1425 :   this->outputUpToEndOfLine(" ]");
     619        1425 : }
     620             : 
     621      343696 : void Output::scalarString(StringRef &S, QuotingType MustQuote) {
     622      343696 :   this->newLineCheck();
     623      343696 :   if (S.empty()) {
     624             :     // Print '' for the empty string because leaving the field empty is not
     625             :     // allowed.
     626       54978 :     this->outputUpToEndOfLine("''");
     627       54978 :     return;
     628             :   }
     629      288718 :   if (MustQuote == QuotingType::None) {
     630             :     // Only quote if we must.
     631      275553 :     this->outputUpToEndOfLine(S);
     632      275553 :     return;
     633             :   }
     634             : 
     635             :   unsigned i = 0;
     636             :   unsigned j = 0;
     637       13165 :   unsigned End = S.size();
     638             :   const char *Base = S.data();
     639             : 
     640       13165 :   const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
     641       13165 :   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       13165 :   if (MustQuote == QuotingType::Double) {
     647          10 :     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      296492 :   while (j < End) {
     654      566668 :     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      283334 :     ++j;
     660             :   }
     661       26316 :   output(StringRef(&Base[i], j - i));
     662       13158 :   this->outputUpToEndOfLine(Quote); // Ending quote.
     663             : }
     664             : 
     665        5716 : void Output::blockScalarString(StringRef &S) {
     666        5716 :   if (!StateStack.empty())
     667        4632 :     newLineCheck();
     668        5716 :   output(" |");
     669        5716 :   outputNewLine();
     670             : 
     671        5716 :   unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
     672             : 
     673        5716 :   auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
     674      102640 :   for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
     675      193848 :     for (unsigned I = 0; I < Indent; ++I) {
     676       96924 :       output("  ");
     677             :     }
     678       96924 :     output(*Lines);
     679       96924 :     outputNewLine();
     680             :   }
     681        5716 : }
     682             : 
     683           0 : void Output::setError(const Twine &message) {
     684           0 : }
     685             : 
     686       21320 : 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       42640 :   if (StateStack.size() < 2)
     693             :     return true;
     694       19616 :   if (StateStack.back() != inMapFirstKey)
     695             :     return true;
     696         770 :   return (StateStack[StateStack.size()-2] != inSeq);
     697             : }
     698             : 
     699     2820788 : void Output::output(StringRef s) {
     700     2820788 :   Column += s.size();
     701     2820788 :   Out << s;
     702     2820788 : }
     703             : 
     704      428430 : void Output::outputUpToEndOfLine(StringRef s) {
     705      428430 :   this->output(s);
     706      428430 :   if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
     707      387791 :                              StateStack.back() != inFlowMapFirstKey &&
     708             :                              StateStack.back() != inFlowMapOtherKey))
     709      338404 :     NeedsNewLine = true;
     710      428430 : }
     711             : 
     712      483238 : void Output::outputNewLine() {
     713      483238 :   Out << "\n";
     714      483238 :   Column = 0;
     715      483238 : }
     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      771640 : void Output::newLineCheck() {
     722      771640 :   if (!NeedsNewLine)
     723             :     return;
     724      380598 :   NeedsNewLine = false;
     725             : 
     726      380598 :   this->outputNewLine();
     727             : 
     728             :   assert(StateStack.size() > 0);
     729      761196 :   unsigned Indent = StateStack.size() - 1;
     730             :   bool OutputDash = false;
     731             : 
     732      380598 :   if (StateStack.back() == inSeq) {
     733             :     OutputDash = true;
     734      296552 :   } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
     735      247795 :              (StateStack.back() == inFlowSeq) ||
     736      370550 :              (StateStack.back() == inFlowMapFirstKey)) &&
     737      146966 :              (StateStack[StateStack.size() - 2] == inSeq)) {
     738       59636 :     --Indent;
     739             :     OutputDash = true;
     740             :   }
     741             : 
     742     1152017 :   for (unsigned i = 0; i < Indent; ++i) {
     743      771419 :     output("  ");
     744             :   }
     745      380598 :   if (OutputDash) {
     746       69684 :     output("- ");
     747             :   }
     748             : 
     749             : }
     750             : 
     751      345771 : void Output::paddedKey(StringRef key) {
     752      345771 :   output(key);
     753      345771 :   output(":");
     754             :   const char *spaces = "                ";
     755      345771 :   if (key.size() < strlen(spaces))
     756      566180 :     output(&spaces[key.size()]);
     757             :   else
     758       62681 :     output(" ");
     759      345771 : }
     760             : 
     761       81551 : void Output::flowKey(StringRef Key) {
     762       81551 :   if (StateStack.back() == inFlowMapOtherKey)
     763       56645 :     output(", ");
     764       81551 :   if (WrapColumn && Column > WrapColumn) {
     765        1967 :     output("\n");
     766       10944 :     for (int I = 0; I < ColumnAtMapFlowStart; ++I)
     767        8977 :       output(" ");
     768        1967 :     Column = ColumnAtMapFlowStart;
     769        1967 :     output("  ");
     770             :   }
     771       81551 :   output(Key);
     772       81551 :   output(": ");
     773       81551 : }
     774             : 
     775             : //===----------------------------------------------------------------------===//
     776             : //  traits for built-in types
     777             : //===----------------------------------------------------------------------===//
     778             : 
     779       70286 : void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
     780      130467 :   Out << (Val ? "true" : "false");
     781       70286 : }
     782             : 
     783       17301 : StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
     784             :   if (Scalar.equals("true")) {
     785        6896 :     Val = true;
     786        6896 :     return StringRef();
     787             :   } else if (Scalar.equals("false")) {
     788       10405 :     Val = false;
     789       10405 :     return StringRef();
     790             :   }
     791           0 :   return "invalid boolean";
     792             : }
     793             : 
     794       27063 : void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
     795             :                                      raw_ostream &Out) {
     796       27063 :   Out << Val;
     797       27063 : }
     798             : 
     799       13791 : StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
     800             :                                          StringRef &Val) {
     801       13791 :   Val = Scalar;
     802       13791 :   return StringRef();
     803             : }
     804             : 
     805       23665 : void ScalarTraits<std::string>::output(const std::string &Val, void *,
     806             :                                      raw_ostream &Out) {
     807             :   Out << Val;
     808       23665 : }
     809             : 
     810        7950 : StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
     811             :                                          std::string &Val) {
     812       15900 :   Val = Scalar.str();
     813        7950 :   return StringRef();
     814             : }
     815             : 
     816        7364 : 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        7364 :   uint32_t Num = Val;
     820             :   Out << Num;
     821        7364 : }
     822             : 
     823        1294 : StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
     824             :   unsigned long long n;
     825        1294 :   if (getAsUnsignedInteger(Scalar, 0, n))
     826           0 :     return "invalid number";
     827        1294 :   if (n > 0xFF)
     828           1 :     return "out of range number";
     829        1293 :   Val = n;
     830        1293 :   return StringRef();
     831             : }
     832             : 
     833       11784 : void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
     834             :                                     raw_ostream &Out) {
     835       11784 :   Out << Val;
     836       11784 : }
     837             : 
     838        5365 : StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
     839             :                                         uint16_t &Val) {
     840             :   unsigned long long n;
     841        5365 :   if (getAsUnsignedInteger(Scalar, 0, n))
     842           0 :     return "invalid number";
     843        5365 :   if (n > 0xFFFF)
     844           1 :     return "out of range number";
     845        5364 :   Val = n;
     846        5364 :   return StringRef();
     847             : }
     848             : 
     849      103714 : void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
     850             :                                     raw_ostream &Out) {
     851      103714 :   Out << Val;
     852      103714 : }
     853             : 
     854       36113 : StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
     855             :                                         uint32_t &Val) {
     856             :   unsigned long long n;
     857       36113 :   if (getAsUnsignedInteger(Scalar, 0, n))
     858           1 :     return "invalid number";
     859       36112 :   if (n > 0xFFFFFFFFUL)
     860           1 :     return "out of range number";
     861       36111 :   Val = n;
     862       36111 :   return StringRef();
     863             : }
     864             : 
     865       12585 : void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
     866             :                                     raw_ostream &Out) {
     867       12585 :   Out << Val;
     868       12585 : }
     869             : 
     870        4001 : StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
     871             :                                         uint64_t &Val) {
     872             :   unsigned long long N;
     873        4001 :   if (getAsUnsignedInteger(Scalar, 0, N))
     874           1 :     return "invalid number";
     875        4000 :   Val = N;
     876        4000 :   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        5645 : void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
     911             :                                    raw_ostream &Out) {
     912        5645 :   Out << Val;
     913        5645 : }
     914             : 
     915        3886 : StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
     916             :   long long N;
     917        3886 :   if (getAsSignedInteger(Scalar, 0, N))
     918           0 :     return "invalid number";
     919        3886 :   if ((N > INT32_MAX) || (N < INT32_MIN))
     920           2 :     return "out of range number";
     921        3884 :   Val = N;
     922        3884 :   return StringRef();
     923             : }
     924             : 
     925        1192 : void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
     926             :                                    raw_ostream &Out) {
     927        1192 :   Out << Val;
     928        1192 : }
     929             : 
     930         484 : StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
     931             :   long long N;
     932         484 :   if (getAsSignedInteger(Scalar, 0, N))
     933           2 :     return "invalid number";
     934         482 :   Val = N;
     935         482 :   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        2578 : void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
     989        2578 :   uint32_t Num = Val;
     990        2578 :   Out << format("0x%08X", Num);
     991        2578 : }
     992             : 
     993        2516 : StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
     994             :   unsigned long long n;
     995        2516 :   if (getAsUnsignedInteger(Scalar, 0, n))
     996           0 :     return "invalid hex32 number";
     997        2516 :   if (n > 0xFFFFFFFFUL)
     998           1 :     return "out of range hex32 number";
     999        2515 :   Val = n;
    1000        2515 :   return StringRef();
    1001             : }
    1002             : 
    1003         934 : void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
    1004         934 :   uint64_t Num = Val;
    1005         934 :   Out << format("0x%016llX", Num);
    1006         934 : }
    1007             : 
    1008        4111 : StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
    1009             :   unsigned long long Num;
    1010        4111 :   if (getAsUnsignedInteger(Scalar, 0, Num))
    1011           1 :     return "invalid hex64 number";
    1012        4110 :   Val = Num;
    1013        4110 :   return StringRef();
    1014             : }

Generated by: LCOV version 1.13