LCOV - code coverage report
Current view: top level - lib/Support - YAMLTraits.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 547 575 95.1 %
Date: 2018-02-18 03:11: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        8025 : IO::IO(void *Context) : Ctxt(Context) {}
      41             : 
      42             : IO::~IO() = default;
      43             : 
      44      347919 : void *IO::getContext() {
      45      347919 :   return Ctxt;
      46             : }
      47             : 
      48        2303 : void IO::setContext(void *Context) {
      49        2303 :   Ctxt = Context;
      50        2303 : }
      51             : 
      52             : //===----------------------------------------------------------------------===//
      53             : //  Input
      54             : //===----------------------------------------------------------------------===//
      55             : 
      56        3134 : Input::Input(StringRef InputContent, void *Ctxt,
      57        3134 :              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
      58       12536 :     : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
      59        3134 :   if (DiagHandler)
      60             :     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
      61        3134 :   DocIterator = Strm->begin();
      62        3134 : }
      63             : 
      64           1 : Input::Input(MemoryBufferRef Input, void *Ctxt,
      65           1 :              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
      66           4 :     : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
      67           1 :   if (DiagHandler)
      68             :     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
      69           1 :   DocIterator = Strm->begin();
      70           1 : }
      71             : 
      72             : Input::~Input() = default;
      73             : 
      74        6116 : 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      950236 : bool Input::outputting() {
      84      950236 :   return false;
      85             : }
      86             : 
      87        7911 : bool Input::setCurrentDocument() {
      88       15822 :   if (DocIterator != Strm->end()) {
      89             :     Node *N = DocIterator->getRoot();
      90        6090 :     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        6089 :     if (isa<NullNode>(N)) {
      97             :       // Empty files are allowed and ignored
      98         412 :       ++DocIterator;
      99         412 :       return setCurrentDocument();
     100             :     }
     101       11354 :     TopNode = this->createHNodes(N);
     102        5677 :     CurrentNode = TopNode.get();
     103        5677 :     return true;
     104             :   }
     105             :   return false;
     106             : }
     107             : 
     108        4793 : bool Input::nextDocument() {
     109        9586 :   return ++DocIterator != Strm->end();
     110             : }
     111             : 
     112       33133 : const Node *Input::getCurrentNode() const {
     113       33133 :   return CurrentNode ? CurrentNode->_node : nullptr;
     114             : }
     115             : 
     116        3071 : bool Input::mapTag(StringRef Tag, bool Default) {
     117        3071 :   std::string foundTag = CurrentNode->_node->getVerbatimTag();
     118        3071 :   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       34896 : void Input::beginMapping() {
     127       34896 :   if (EC)
     128             :     return;
     129             :   // CurrentNode can be null if the document is empty.
     130       34893 :   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
     131             :   if (MN) {
     132       34833 :     MN->ValidKeys.clear();
     133             :   }
     134             : }
     135             : 
     136          66 : std::vector<StringRef> Input::keys() {
     137          66 :   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
     138             :   std::vector<StringRef> Ret;
     139          66 :   if (!MN) {
     140           0 :     setError(CurrentNode, "not a mapping");
     141           0 :     return Ret;
     142             :   }
     143         168 :   for (auto &P : MN->Mapping)
     144         204 :     Ret.push_back(P.first());
     145             :   return Ret;
     146             : }
     147             : 
     148      242083 : bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
     149             :                          void *&SaveInfo) {
     150      242083 :   UseDefault = false;
     151      242083 :   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      242020 :   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      484024 :   MN->ValidKeys.push_back(Key);
     169      242012 :   HNode *Value = MN->Mapping[Key].get();
     170      242012 :   if (!Value) {
     171      118320 :     if (Required)
     172          19 :       setError(CurrentNode, Twine("missing required key '") + Key + "'");
     173             :     else
     174      118301 :       UseDefault = true;
     175             :     return false;
     176             :   }
     177      123692 :   SaveInfo = CurrentNode;
     178      123692 :   CurrentNode = Value;
     179      123692 :   return true;
     180             : }
     181             : 
     182      123692 : void Input::postflightKey(void *saveInfo) {
     183      123692 :   CurrentNode = reinterpret_cast<HNode *>(saveInfo);
     184      123692 : }
     185             : 
     186       34896 : void Input::endMapping() {
     187       34896 :   if (EC)
     188             :     return;
     189             :   // CurrentNode can be null if the document is empty.
     190       34843 :   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
     191             :   if (!MN)
     192             :     return;
     193      275966 :   for (const auto &NN : MN->Mapping) {
     194      482390 :     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       13691 : void Input::beginFlowMapping() { beginMapping(); }
     202             : 
     203       13691 : void Input::endFlowMapping() { endMapping(); }
     204             : 
     205        8586 : unsigned Input::beginSequence() {
     206        8586 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
     207        7178 :     return SQ->Entries.size();
     208        1408 :   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        7751 : void Input::endSequence() {
     221        7751 : }
     222             : 
     223       26140 : bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
     224       26140 :   if (EC)
     225             :     return false;
     226       26140 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     227       26140 :     SaveInfo = CurrentNode;
     228       52280 :     CurrentNode = SQ->Entries[Index].get();
     229       26140 :     return true;
     230             :   }
     231             :   return false;
     232             : }
     233             : 
     234       26140 : void Input::postflightElement(void *SaveInfo) {
     235       26140 :   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
     236       26140 : }
     237             : 
     238         835 : unsigned Input::beginFlowSequence() { return beginSequence(); }
     239             : 
     240        8672 : bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
     241        8672 :   if (EC)
     242             :     return false;
     243        8672 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     244        8672 :     SaveInfo = CurrentNode;
     245       17344 :     CurrentNode = SQ->Entries[index].get();
     246        8672 :     return true;
     247             :   }
     248             :   return false;
     249             : }
     250             : 
     251        8672 : void Input::postflightFlowElement(void *SaveInfo) {
     252        8672 :   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
     253        8672 : }
     254             : 
     255         835 : void Input::endFlowSequence() {
     256         835 : }
     257             : 
     258       14947 : void Input::beginEnumScalar() {
     259       14947 :   ScalarMatchFound = false;
     260       14947 : }
     261             : 
     262      681007 : bool Input::matchEnumScalar(const char *Str, bool) {
     263      681007 :   if (ScalarMatchFound)
     264             :     return false;
     265      185538 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     266             :     if (SN->value().equals(Str)) {
     267       14914 :       ScalarMatchFound = true;
     268       14914 :       return true;
     269             :     }
     270             :   }
     271             :   return false;
     272             : }
     273             : 
     274        1506 : bool Input::matchEnumFallback() {
     275        1506 :   if (ScalarMatchFound)
     276             :     return false;
     277          31 :   ScalarMatchFound = true;
     278          31 :   return true;
     279             : }
     280             : 
     281       14947 : void Input::endEnumScalar() {
     282       14947 :   if (!ScalarMatchFound) {
     283           2 :     setError(CurrentNode, "unknown enumerated scalar");
     284             :   }
     285       14947 : }
     286             : 
     287        2467 : bool Input::beginBitSetScalar(bool &DoClear) {
     288        2467 :   BitValuesUsed.clear();
     289        2467 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     290        2467 :     BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
     291             :   } else {
     292           0 :     setError(CurrentNode, "expected sequence of bit values");
     293             :   }
     294        2467 :   DoClear = true;
     295        2467 :   return true;
     296             : }
     297             : 
     298       26610 : bool Input::bitSetMatch(const char *Str, bool) {
     299       26610 :   if (EC)
     300             :     return false;
     301       26610 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     302             :     unsigned Index = 0;
     303       74453 :     for (auto &N : SQ->Entries) {
     304             :       if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
     305             :         if (SN->value().equals(Str)) {
     306        4029 :           BitValuesUsed[Index] = true;
     307             :           return true;
     308             :         }
     309             :       } else {
     310           0 :         setError(CurrentNode, "unexpected scalar in sequence of bit values");
     311             :       }
     312       47843 :       ++Index;
     313             :     }
     314             :   } else {
     315           0 :     setError(CurrentNode, "expected sequence of bit values");
     316             :   }
     317             :   return false;
     318             : }
     319             : 
     320        2467 : void Input::endBitSetScalar() {
     321        2467 :   if (EC)
     322             :     return;
     323        2467 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     324             :     assert(BitValuesUsed.size() == SQ->Entries.size());
     325       17021 :     for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
     326        4030 :       if (!BitValuesUsed[i]) {
     327           1 :         setError(SQ->Entries[i].get(), "unknown bit value");
     328           1 :         return;
     329             :       }
     330             :     }
     331             :   }
     332             : }
     333             : 
     334      102662 : void Input::scalarString(StringRef &S, QuotingType) {
     335      102662 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     336      102662 :     S = SN->value();
     337             :   } else {
     338           0 :     setError(CurrentNode, "unexpected scalar");
     339             :   }
     340      102662 : }
     341             : 
     342        3016 : void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
     343             : 
     344          74 : void Input::setError(HNode *hnode, const Twine &message) {
     345             :   assert(hnode && "HNode must not be NULL");
     346          74 :   this->setError(hnode->_node, message);
     347          74 : }
     348             : 
     349          76 : void Input::setError(Node *node, const Twine &message) {
     350          76 :   Strm->printError(node, message);
     351          76 :   EC = make_error_code(errc::invalid_argument);
     352          76 : }
     353             : 
     354      168154 : std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
     355             :   SmallString<128> StringStorage;
     356             :   if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
     357      118443 :     StringRef KeyStr = SN->getValue(StringStorage);
     358      118443 :     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        3677 :     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       48606 :     for (Node &SN : *SQ) {
     369       38921 :       auto Entry = this->createHNodes(&SN);
     370       38921 :       if (EC)
     371             :         break;
     372       38921 :       SQHNode->Entries.push_back(std::move(Entry));
     373             :     }
     374             :     return std::move(SQHNode);
     375             :   } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
     376       34887 :     auto mapHNode = llvm::make_unique<MapHNode>(N);
     377      158443 :     for (KeyValueNode &KVN : *Map) {
     378      123558 :       Node *KeyNode = KVN.getKey();
     379             :       ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode);
     380      123558 :       Node *Value = KVN.getValue();
     381      123558 :       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      123556 :       StringRef KeyStr = Key->getValue(StringStorage);
     390      123556 :       if (!StringStorage.empty()) {
     391             :         // Copy string to permanent storage
     392           0 :         KeyStr = StringStorage.str().copy(StringAllocator);
     393             :       }
     394      123556 :       auto ValueHNode = this->createHNodes(Value);
     395      123556 :       if (EC)
     396             :         break;
     397      123556 :       mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
     398             :     }
     399             :     return std::move(mapHNode);
     400        1462 :   } 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       10000 : bool Input::canElideEmptySequence() {
     413       10000 :   return false;
     414             : }
     415             : 
     416             : //===----------------------------------------------------------------------===//
     417             : //  Output
     418             : //===----------------------------------------------------------------------===//
     419             : 
     420        4890 : Output::Output(raw_ostream &yout, void *context, int WrapColumn)
     421        9780 :     : IO(context), Out(yout), WrapColumn(WrapColumn) {}
     422             : 
     423             : Output::~Output() = default;
     424             : 
     425     1152164 : bool Output::outputting() {
     426     1152164 :   return true;
     427             : }
     428             : 
     429       36194 : void Output::beginMapping() {
     430       36194 :   StateStack.push_back(inMapFirstKey);
     431       36194 :   NeedsNewLine = true;
     432       36194 : }
     433             : 
     434        1121 : bool Output::mapTag(StringRef Tag, bool Use) {
     435        1121 :   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         595 :         StateStack.size() > 1 && (StateStack[StateStack.size() - 2] == inSeq ||
     441             :           StateStack[StateStack.size() - 2] == inFlowSeq);
     442          33 :     if (SequenceElement && StateStack.back() == inMapFirstKey) {
     443          33 :       this->newLineCheck();
     444             :     } else {
     445         529 :       this->output(" ");
     446             :     }
     447         562 :     this->output(Tag);
     448         562 :     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          33 :       if (StateStack.back() == inMapFirstKey) {
     452          33 :         StateStack.pop_back();
     453          33 :         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          33 :       NeedsNewLine = true;
     458             :     }
     459             :   }
     460        1121 :   return Use;
     461             : }
     462             : 
     463       36194 : void Output::endMapping() {
     464             :   StateStack.pop_back();
     465       36194 : }
     466             : 
     467           0 : std::vector<StringRef> Output::keys() {
     468           0 :   report_fatal_error("invalid call");
     469             : }
     470             : 
     471      377481 : bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
     472             :                           bool &UseDefault, void *&) {
     473      377481 :   UseDefault = false;
     474      377481 :   if (Required || !SameAsDefault || WriteDefaultValues) {
     475      283302 :     auto State = StateStack.back();
     476      283302 :     if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
     477       56436 :       flowKey(Key);
     478             :     } else {
     479      226866 :       this->newLineCheck();
     480      226866 :       this->paddedKey(Key);
     481             :     }
     482             :     return true;
     483             :   }
     484             :   return false;
     485             : }
     486             : 
     487      283302 : void Output::postflightKey(void *) {
     488      283302 :   if (StateStack.back() == inMapFirstKey) {
     489       36030 :     StateStack.pop_back();
     490       36030 :     StateStack.push_back(inMapOtherKey);
     491      247272 :   } else if (StateStack.back() == inFlowMapFirstKey) {
     492       17432 :     StateStack.pop_back();
     493       17432 :     StateStack.push_back(inFlowMapOtherKey);
     494             :   }
     495      283302 : }
     496             : 
     497       17432 : void Output::beginFlowMapping() {
     498       17432 :   StateStack.push_back(inFlowMapFirstKey);
     499       17432 :   this->newLineCheck();
     500       17432 :   ColumnAtMapFlowStart = Column;
     501       17432 :   output("{ ");
     502       17432 : }
     503             : 
     504       17432 : void Output::endFlowMapping() {
     505             :   StateStack.pop_back();
     506       17432 :   this->outputUpToEndOfLine(" }");
     507       17432 : }
     508             : 
     509        5034 : void Output::beginDocuments() {
     510        5034 :   this->outputUpToEndOfLine("---");
     511        5034 : }
     512             : 
     513        5036 : bool Output::preflightDocument(unsigned index) {
     514        5036 :   if (index > 0)
     515           2 :     this->outputUpToEndOfLine("\n---");
     516        5036 :   return true;
     517             : }
     518             : 
     519        5036 : void Output::postflightDocument() {
     520        5036 : }
     521             : 
     522        5034 : void Output::endDocuments() {
     523        5034 :   output("\n...\n");
     524        5034 : }
     525             : 
     526       20494 : unsigned Output::beginSequence() {
     527       20494 :   StateStack.push_back(inSeq);
     528       20494 :   NeedsNewLine = true;
     529       20494 :   return 0;
     530             : }
     531             : 
     532       20494 : void Output::endSequence() {
     533             :   StateStack.pop_back();
     534       20494 : }
     535             : 
     536       50222 : bool Output::preflightElement(unsigned, void *&) {
     537       50222 :   return true;
     538             : }
     539             : 
     540       50222 : void Output::postflightElement(void *) {
     541       50222 : }
     542             : 
     543        1636 : unsigned Output::beginFlowSequence() {
     544        1636 :   StateStack.push_back(inFlowSeq);
     545        1636 :   this->newLineCheck();
     546        1636 :   ColumnAtFlowStart = Column;
     547        1636 :   output("[ ");
     548        1636 :   NeedFlowSequenceComma = false;
     549        1636 :   return 0;
     550             : }
     551             : 
     552        1636 : void Output::endFlowSequence() {
     553             :   StateStack.pop_back();
     554        1636 :   this->outputUpToEndOfLine(" ]");
     555        1636 : }
     556             : 
     557        7540 : bool Output::preflightFlowElement(unsigned, void *&) {
     558        7540 :   if (NeedFlowSequenceComma)
     559        5929 :     output(", ");
     560        7540 :   if (WrapColumn && Column > WrapColumn) {
     561         320 :     output("\n");
     562       13802 :     for (int i = 0; i < ColumnAtFlowStart; ++i)
     563        6741 :       output(" ");
     564         320 :     Column = ColumnAtFlowStart;
     565         320 :     output("  ");
     566             :   }
     567        7540 :   return true;
     568             : }
     569             : 
     570        7540 : void Output::postflightFlowElement(void *) {
     571        7540 :   NeedFlowSequenceComma = true;
     572        7540 : }
     573             : 
     574       31043 : void Output::beginEnumScalar() {
     575       31043 :   EnumerationMatchFound = false;
     576       31043 : }
     577             : 
     578      626770 : bool Output::matchEnumScalar(const char *Str, bool Match) {
     579      626770 :   if (Match && !EnumerationMatchFound) {
     580       31020 :     this->newLineCheck();
     581       31020 :     this->outputUpToEndOfLine(Str);
     582       31020 :     EnumerationMatchFound = true;
     583             :   }
     584      626770 :   return false;
     585             : }
     586             : 
     587        6781 : bool Output::matchEnumFallback() {
     588        6781 :   if (EnumerationMatchFound)
     589             :     return false;
     590          23 :   EnumerationMatchFound = true;
     591          23 :   return true;
     592             : }
     593             : 
     594       31043 : void Output::endEnumScalar() {
     595       31043 :   if (!EnumerationMatchFound)
     596           0 :     llvm_unreachable("bad runtime enum value");
     597       31043 : }
     598             : 
     599         475 : bool Output::beginBitSetScalar(bool &DoClear) {
     600         475 :   this->newLineCheck();
     601         475 :   output("[ ");
     602         475 :   NeedBitValueComma = false;
     603         475 :   DoClear = false;
     604         475 :   return true;
     605             : }
     606             : 
     607        5978 : bool Output::bitSetMatch(const char *Str, bool Matches) {
     608        5978 :   if (Matches) {
     609        1066 :     if (NeedBitValueComma)
     610         619 :       output(", ");
     611        1066 :     this->output(Str);
     612        1066 :     NeedBitValueComma = true;
     613             :   }
     614        5978 :   return false;
     615             : }
     616             : 
     617         475 : void Output::endBitSetScalar() {
     618         475 :   this->outputUpToEndOfLine(" ]");
     619         475 : }
     620             : 
     621      235163 : void Output::scalarString(StringRef &S, QuotingType MustQuote) {
     622      235163 :   this->newLineCheck();
     623      235163 :   if (S.empty()) {
     624             :     // Print '' for the empty string because leaving the field empty is not
     625             :     // allowed.
     626       42440 :     this->outputUpToEndOfLine("''");
     627       42440 :     return;
     628             :   }
     629      192723 :   if (MustQuote == QuotingType::None) {
     630             :     // Only quote if we must.
     631      184329 :     this->outputUpToEndOfLine(S);
     632      184329 :     return;
     633             :   }
     634             : 
     635             :   unsigned i = 0;
     636             :   unsigned j = 0;
     637        8394 :   unsigned End = S.size();
     638             :   const char *Base = S.data();
     639             : 
     640        8394 :   const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
     641        8394 :   const char QuoteChar = MustQuote == QuotingType::Single ? '\'' : '"';
     642             : 
     643        8394 :   output(Quote); // Starting quote.
     644             : 
     645             :   // When using single-quoted strings, any single quote ' must be doubled to be
     646             :   // escaped.
     647             :   // When using double-quoted strings, print \x + hex for non-printable ASCII
     648             :   // characters, and escape double quotes.
     649      390130 :   while (j < End) {
     650      381736 :     if (S[j] == QuoteChar) {                  // Escape quotes.
     651          28 :       output(StringRef(&Base[i], j - i));     // "flush".
     652          14 :       if (MustQuote == QuotingType::Double) { // Print it as \"
     653           1 :         output(StringLiteral("\\"));
     654           1 :         output(StringRef(Quote, 1));
     655             :       } else {                       // Single
     656          13 :         output(StringLiteral("''")); // Print it as ''
     657             :       }
     658          14 :       i = j + 1;
     659          93 :     } else if (MustQuote == QuotingType::Double &&
     660      190890 :                !sys::unicode::isPrintable(S[j]) && (S[j] & 0x80) == 0) {
     661             :       // If we're double quoting non-printable characters, we prefer printing
     662             :       // them as "\x" + their hex representation. Note that special casing is
     663             :       // needed for UTF-8, where a byte may be part of a UTF-8 sequence and
     664             :       // appear as non-printable, in which case we want to print the correct
     665             :       // unicode character and not its hex representation.
     666           8 :       output(StringRef(&Base[i], j - i)); // "flush"
     667           4 :       output(StringLiteral("\\x"));
     668             : 
     669             :       // Output the byte 0x0F as \x0f.
     670           4 :       auto FormattedHex = format_hex_no_prefix(S[j], 2);
     671           4 :       Out << FormattedHex;
     672           4 :       Column += 4; // one for the '\', one for the 'x', and two for the hex
     673             : 
     674           4 :       i = j + 1;
     675             :     }
     676      190868 :     ++j;
     677             :   }
     678       16788 :   output(StringRef(&Base[i], j - i));
     679        8394 :   this->outputUpToEndOfLine(Quote); // Ending quote.
     680             : }
     681             : 
     682        3828 : void Output::blockScalarString(StringRef &S) {
     683        3828 :   if (!StateStack.empty())
     684        3105 :     newLineCheck();
     685        3828 :   output(" |");
     686        3828 :   outputNewLine();
     687             : 
     688        6933 :   unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
     689             : 
     690        3828 :   auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
     691        3828 :   for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
     692      191229 :     for (unsigned I = 0; I < Indent; ++I) {
     693       63743 :       output("  ");
     694             :     }
     695       63743 :     output(*Lines);
     696       63743 :     outputNewLine();
     697             :   }
     698        3828 : }
     699             : 
     700           0 : void Output::setError(const Twine &message) {
     701           0 : }
     702             : 
     703       18027 : bool Output::canElideEmptySequence() {
     704             :   // Normally, with an optional key/value where the value is an empty sequence,
     705             :   // the whole key/value can be not written.  But, that produces wrong yaml
     706             :   // if the key/value is the only thing in the map and the map is used in
     707             :   // a sequence.  This detects if the this sequence is the first key/value
     708             :   // in map that itself is embedded in a sequnce.
     709       18027 :   if (StateStack.size() < 2)
     710             :     return true;
     711       16699 :   if (StateStack.back() != inMapFirstKey)
     712             :     return true;
     713         738 :   return (StateStack[StateStack.size()-2] != inSeq);
     714             : }
     715             : 
     716     1864323 : void Output::output(StringRef s) {
     717     1864323 :   Column += s.size();
     718     1864323 :   Out << s;
     719     1864323 : }
     720             : 
     721      290762 : void Output::outputUpToEndOfLine(StringRef s) {
     722      290762 :   this->output(s);
     723      290762 :   if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
     724      260740 :                              StateStack.back() != inFlowMapFirstKey &&
     725             :                              StateStack.back() != inFlowMapOtherKey))
     726      226786 :     NeedsNewLine = true;
     727      290762 : }
     728             : 
     729      321719 : void Output::outputNewLine() {
     730      321719 :   Out << "\n";
     731      321719 :   Column = 0;
     732      321719 : }
     733             : 
     734             : // if seq at top, indent as if map, then add "- "
     735             : // if seq in middle, use "- " if firstKey, else use "  "
     736             : //
     737             : 
     738      515730 : void Output::newLineCheck() {
     739      515730 :   if (!NeedsNewLine)
     740             :     return;
     741      254148 :   NeedsNewLine = false;
     742             : 
     743      254148 :   this->outputNewLine();
     744             : 
     745             :   assert(StateStack.size() > 0);
     746      254148 :   unsigned Indent = StateStack.size() - 1;
     747             :   bool OutputDash = false;
     748             : 
     749      254148 :   if (StateStack.back() == inSeq) {
     750             :     OutputDash = true;
     751      196346 :   } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
     752      164715 :              (StateStack.back() == inFlowSeq) ||
     753      293057 :              (StateStack.back() == inFlowMapFirstKey)) &&
     754       97786 :              (StateStack[StateStack.size() - 2] == inSeq)) {
     755       40238 :     --Indent;
     756             :     OutputDash = true;
     757             :   }
     758             : 
     759     1244692 :   for (unsigned i = 0; i < Indent; ++i) {
     760      495272 :     output("  ");
     761             :   }
     762      254148 :   if (OutputDash) {
     763       50222 :     output("- ");
     764             :   }
     765             : 
     766             : }
     767             : 
     768      226866 : void Output::paddedKey(StringRef key) {
     769      226866 :   output(key);
     770      226866 :   output(":");
     771             :   const char *spaces = "                ";
     772      226866 :   if (key.size() < strlen(spaces))
     773      364650 :     output(&spaces[key.size()]);
     774             :   else
     775       44541 :     output(" ");
     776      226866 : }
     777             : 
     778       56436 : void Output::flowKey(StringRef Key) {
     779       56436 :   if (StateStack.back() == inFlowMapOtherKey)
     780       39004 :     output(", ");
     781       56436 :   if (WrapColumn && Column > WrapColumn) {
     782         967 :     output("\n");
     783       10681 :     for (int I = 0; I < ColumnAtMapFlowStart; ++I)
     784        4857 :       output(" ");
     785         967 :     Column = ColumnAtMapFlowStart;
     786         967 :     output("  ");
     787             :   }
     788       56436 :   output(Key);
     789       56436 :   output(": ");
     790       56436 : }
     791             : 
     792             : //===----------------------------------------------------------------------===//
     793             : //  traits for built-in types
     794             : //===----------------------------------------------------------------------===//
     795             : 
     796       45298 : void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
     797       45298 :   Out << (Val ? "true" : "false");
     798       45298 : }
     799             : 
     800       12640 : StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
     801             :   if (Scalar.equals("true")) {
     802        4876 :     Val = true;
     803        4876 :     return StringRef();
     804             :   } else if (Scalar.equals("false")) {
     805        7764 :     Val = false;
     806        7764 :     return StringRef();
     807             :   }
     808           0 :   return "invalid boolean";
     809             : }
     810             : 
     811       22555 : void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
     812             :                                      raw_ostream &Out) {
     813       22555 :   Out << Val;
     814       22555 : }
     815             : 
     816        9865 : StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
     817             :                                          StringRef &Val) {
     818        9865 :   Val = Scalar;
     819        9865 :   return StringRef();
     820             : }
     821             : 
     822       16984 : void ScalarTraits<std::string>::output(const std::string &Val, void *,
     823             :                                      raw_ostream &Out) {
     824             :   Out << Val;
     825       16984 : }
     826             : 
     827        5927 : StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
     828             :                                          std::string &Val) {
     829       11854 :   Val = Scalar.str();
     830        5927 :   return StringRef();
     831             : }
     832             : 
     833        7019 : void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
     834             :                                    raw_ostream &Out) {
     835             :   // use temp uin32_t because ostream thinks uint8_t is a character
     836        7019 :   uint32_t Num = Val;
     837             :   Out << Num;
     838        7019 : }
     839             : 
     840        1183 : StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
     841             :   unsigned long long n;
     842        1183 :   if (getAsUnsignedInteger(Scalar, 0, n))
     843           0 :     return "invalid number";
     844        1183 :   if (n > 0xFF)
     845           1 :     return "out of range number";
     846        1182 :   Val = n;
     847        1182 :   return StringRef();
     848             : }
     849             : 
     850        7731 : void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
     851             :                                     raw_ostream &Out) {
     852        7731 :   Out << Val;
     853        7731 : }
     854             : 
     855        3938 : StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
     856             :                                         uint16_t &Val) {
     857             :   unsigned long long n;
     858        3938 :   if (getAsUnsignedInteger(Scalar, 0, n))
     859           0 :     return "invalid number";
     860        3938 :   if (n > 0xFFFF)
     861           1 :     return "out of range number";
     862        3937 :   Val = n;
     863        3937 :   return StringRef();
     864             : }
     865             : 
     866       66930 : void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
     867             :                                     raw_ostream &Out) {
     868       66930 :   Out << Val;
     869       66930 : }
     870             : 
     871       26870 : StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
     872             :                                         uint32_t &Val) {
     873             :   unsigned long long n;
     874       26870 :   if (getAsUnsignedInteger(Scalar, 0, n))
     875           1 :     return "invalid number";
     876       26869 :   if (n > 0xFFFFFFFFUL)
     877           1 :     return "out of range number";
     878       26868 :   Val = n;
     879       26868 :   return StringRef();
     880             : }
     881             : 
     882        8939 : void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
     883             :                                     raw_ostream &Out) {
     884        8939 :   Out << Val;
     885        8939 : }
     886             : 
     887        2808 : StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
     888             :                                         uint64_t &Val) {
     889             :   unsigned long long N;
     890        2808 :   if (getAsUnsignedInteger(Scalar, 0, N))
     891           1 :     return "invalid number";
     892        2807 :   Val = N;
     893        2807 :   return StringRef();
     894             : }
     895             : 
     896           1 : void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
     897             :   // use temp in32_t because ostream thinks int8_t is a character
     898           1 :   int32_t Num = Val;
     899             :   Out << Num;
     900           1 : }
     901             : 
     902          10 : StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
     903             :   long long N;
     904          10 :   if (getAsSignedInteger(Scalar, 0, N))
     905           0 :     return "invalid number";
     906          10 :   if ((N > 127) || (N < -128))
     907           2 :     return "out of range number";
     908           8 :   Val = N;
     909           8 :   return StringRef();
     910             : }
     911             : 
     912           2 : void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
     913             :                                    raw_ostream &Out) {
     914           2 :   Out << Val;
     915           2 : }
     916             : 
     917          12 : StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
     918             :   long long N;
     919          12 :   if (getAsSignedInteger(Scalar, 0, N))
     920           0 :     return "invalid number";
     921          12 :   if ((N > INT16_MAX) || (N < INT16_MIN))
     922           2 :     return "out of range number";
     923          10 :   Val = N;
     924          10 :   return StringRef();
     925             : }
     926             : 
     927        3495 : void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
     928             :                                    raw_ostream &Out) {
     929        3495 :   Out << Val;
     930        3495 : }
     931             : 
     932        3122 : StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
     933             :   long long N;
     934        3122 :   if (getAsSignedInteger(Scalar, 0, N))
     935           0 :     return "invalid number";
     936        3122 :   if ((N > INT32_MAX) || (N < INT32_MIN))
     937           2 :     return "out of range number";
     938        3120 :   Val = N;
     939        3120 :   return StringRef();
     940             : }
     941             : 
     942         856 : void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
     943             :                                    raw_ostream &Out) {
     944         856 :   Out << Val;
     945         856 : }
     946             : 
     947         382 : StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
     948             :   long long N;
     949         382 :   if (getAsSignedInteger(Scalar, 0, N))
     950           2 :     return "invalid number";
     951         380 :   Val = N;
     952         380 :   return StringRef();
     953             : }
     954             : 
     955           4 : void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
     956           4 :   Out << format("%g", Val);
     957           4 : }
     958             : 
     959          15 : StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
     960          15 :   if (to_float(Scalar, Val))
     961          14 :     return StringRef();
     962           1 :   return "invalid floating point number";
     963             : }
     964             : 
     965           2 : void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
     966           2 :   Out << format("%g", Val);
     967           2 : }
     968             : 
     969           8 : StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
     970           8 :   if (to_float(Scalar, Val))
     971           7 :     return StringRef();
     972           1 :   return "invalid floating point number";
     973             : }
     974             : 
     975         399 : void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
     976         399 :   uint8_t Num = Val;
     977         399 :   Out << format("0x%02X", Num);
     978         399 : }
     979             : 
     980        6248 : StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
     981             :   unsigned long long n;
     982        6248 :   if (getAsUnsignedInteger(Scalar, 0, n))
     983           0 :     return "invalid hex8 number";
     984        6248 :   if (n > 0xFF)
     985           1 :     return "out of range hex8 number";
     986        6247 :   Val = n;
     987        6247 :   return StringRef();
     988             : }
     989             : 
     990          12 : void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
     991          12 :   uint16_t Num = Val;
     992          12 :   Out << format("0x%04X", Num);
     993          12 : }
     994             : 
     995          41 : StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
     996             :   unsigned long long n;
     997          41 :   if (getAsUnsignedInteger(Scalar, 0, n))
     998           0 :     return "invalid hex16 number";
     999          41 :   if (n > 0xFFFF)
    1000           1 :     return "out of range hex16 number";
    1001          40 :   Val = n;
    1002          40 :   return StringRef();
    1003             : }
    1004             : 
    1005        2024 : void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
    1006        2024 :   uint32_t Num = Val;
    1007        2024 :   Out << format("0x%08X", Num);
    1008        2024 : }
    1009             : 
    1010        2381 : StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
    1011             :   unsigned long long n;
    1012        2381 :   if (getAsUnsignedInteger(Scalar, 0, n))
    1013           0 :     return "invalid hex32 number";
    1014        2381 :   if (n > 0xFFFFFFFFUL)
    1015           1 :     return "out of range hex32 number";
    1016        2380 :   Val = n;
    1017        2380 :   return StringRef();
    1018             : }
    1019             : 
    1020         913 : void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
    1021         913 :   uint64_t Num = Val;
    1022         913 :   Out << format("0x%016llX", Num);
    1023         913 : }
    1024             : 
    1025        3638 : StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
    1026             :   unsigned long long Num;
    1027        3638 :   if (getAsUnsignedInteger(Scalar, 0, Num))
    1028           1 :     return "invalid hex64 number";
    1029        3637 :   Val = Num;
    1030        3637 :   return StringRef();
    1031             : }

Generated by: LCOV version 1.13