LCOV - code coverage report
Current view: top level - lib/Support - YAMLTraits.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 570 599 95.2 %
Date: 2017-09-14 15:23:50 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/YAMLParser.h"
      23             : #include "llvm/Support/raw_ostream.h"
      24             : #include <algorithm>
      25             : #include <cassert>
      26             : #include <cstdint>
      27             : #include <cstdlib>
      28             : #include <cstring>
      29             : #include <string>
      30             : #include <vector>
      31             : 
      32             : using namespace llvm;
      33             : using namespace yaml;
      34             : 
      35             : //===----------------------------------------------------------------------===//
      36             : //  IO
      37             : //===----------------------------------------------------------------------===//
      38             : 
      39        6841 : IO::IO(void *Context) : Ctxt(Context) {}
      40             : 
      41             : IO::~IO() = default;
      42             : 
      43      292466 : void *IO::getContext() {
      44      292466 :   return Ctxt;
      45             : }
      46             : 
      47        1789 : void IO::setContext(void *Context) {
      48        1789 :   Ctxt = Context;
      49        1789 : }
      50             : 
      51             : //===----------------------------------------------------------------------===//
      52             : //  Input
      53             : //===----------------------------------------------------------------------===//
      54             : 
      55        2971 : Input::Input(StringRef InputContent, void *Ctxt,
      56        2971 :              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
      57       23768 :     : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
      58        2971 :   if (DiagHandler)
      59         746 :     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
      60        5942 :   DocIterator = Strm->begin();
      61        2971 : }
      62             : 
      63           1 : Input::Input(MemoryBufferRef Input, void *Ctxt,
      64           1 :              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
      65           8 :     : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
      66           1 :   if (DiagHandler)
      67           1 :     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
      68           2 :   DocIterator = Strm->begin();
      69           1 : }
      70             : 
      71             : Input::~Input() = default;
      72             : 
      73        5315 : std::error_code Input::error() { return EC; }
      74             : 
      75             : // Pin the vtables to this file.
      76           0 : void Input::HNode::anchor() {}
      77           0 : void Input::EmptyHNode::anchor() {}
      78           0 : void Input::ScalarHNode::anchor() {}
      79           0 : void Input::MapHNode::anchor() {}
      80           0 : void Input::SequenceHNode::anchor() {}
      81             : 
      82      800240 : bool Input::outputting() {
      83      800240 :   return false;
      84             : }
      85             : 
      86        6852 : bool Input::setCurrentDocument() {
      87       20556 :   if (DocIterator != Strm->end()) {
      88       20896 :     Node *N = DocIterator->getRoot();
      89        5224 :     if (!N) {
      90             :       assert(Strm->failed() && "Root is NULL iff parsing failed");
      91           1 :       EC = make_error_code(errc::invalid_argument);
      92           1 :       return false;
      93             :     }
      94             : 
      95       10446 :     if (isa<NullNode>(N)) {
      96             :       // Empty files are allowed and ignored
      97         364 :       ++DocIterator;
      98         364 :       return setCurrentDocument();
      99             :     }
     100       14577 :     TopNode = this->createHNodes(N);
     101        9718 :     CurrentNode = TopNode.get();
     102        4859 :     return true;
     103             :   }
     104             :   return false;
     105             : }
     106             : 
     107        3533 : bool Input::nextDocument() {
     108       10599 :   return ++DocIterator != Strm->end();
     109             : }
     110             : 
     111       19745 : const Node *Input::getCurrentNode() const {
     112       19745 :   return CurrentNode ? CurrentNode->_node : nullptr;
     113             : }
     114             : 
     115        2268 : bool Input::mapTag(StringRef Tag, bool Default) {
     116        4536 :   std::string foundTag = CurrentNode->_node->getVerbatimTag();
     117        2268 :   if (foundTag.empty()) {
     118             :     // If no tag found and 'Tag' is the default, say it was found.
     119             :     return Default;
     120             :   }
     121             :   // Return true iff found tag matches supplied tag.
     122        2268 :   return Tag.equals(foundTag);
     123             : }
     124             : 
     125       32693 : void Input::beginMapping() {
     126       32693 :   if (EC)
     127             :     return;
     128             :   // CurrentNode can be null if the document is empty.
     129       65338 :   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
     130             :   if (MN) {
     131       32647 :     MN->ValidKeys.clear();
     132             :   }
     133             : }
     134             : 
     135          63 : std::vector<StringRef> Input::keys() {
     136         126 :   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
     137          63 :   std::vector<StringRef> Ret;
     138          63 :   if (!MN) {
     139           0 :     setError(CurrentNode, "not a mapping");
     140           0 :     return Ret;
     141             :   }
     142         450 :   for (auto &P : MN->Mapping)
     143         198 :     Ret.push_back(P.first());
     144             :   return Ret;
     145             : }
     146             : 
     147      266566 : bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
     148             :                          void *&SaveInfo) {
     149      266566 :   UseDefault = false;
     150      266566 :   if (EC)
     151             :     return false;
     152             : 
     153             :   // CurrentNode is null for empty documents, which is an error in case required
     154             :   // nodes are present.
     155      266505 :   if (!CurrentNode) {
     156           2 :     if (Required)
     157           1 :       EC = make_error_code(errc::invalid_argument);
     158             :     return false;
     159             :   }
     160             : 
     161      533006 :   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
     162             :   if (!MN) {
     163           0 :     setError(CurrentNode, "not a mapping");
     164           0 :     return false;
     165             :   }
     166     1066012 :   MN->ValidKeys.push_back(Key);
     167      799509 :   HNode *Value = MN->Mapping[Key].get();
     168      266503 :   if (!Value) {
     169      143088 :     if (Required)
     170          95 :       setError(CurrentNode, Twine("missing required key '") + Key + "'");
     171             :     else
     172      143069 :       UseDefault = true;
     173             :     return false;
     174             :   }
     175      123415 :   SaveInfo = CurrentNode;
     176      123415 :   CurrentNode = Value;
     177      123415 :   return true;
     178             : }
     179             : 
     180      123415 : void Input::postflightKey(void *saveInfo) {
     181      123415 :   CurrentNode = reinterpret_cast<HNode *>(saveInfo);
     182      123415 : }
     183             : 
     184       32693 : void Input::endMapping() {
     185       32693 :   if (EC)
     186             :     return;
     187             :   // CurrentNode can be null if the document is empty.
     188       65239 :   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
     189             :   if (!MN)
     190             :     return;
     191      662103 :   for (const auto &NN : MN->Mapping) {
     192      531724 :     if (!is_contained(MN->ValidKeys, NN.first())) {
     193          91 :       setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
     194          13 :       break;
     195             :     }
     196             :   }
     197             : }
     198             : 
     199        9233 : void Input::beginFlowMapping() { beginMapping(); }
     200             : 
     201        9233 : void Input::endFlowMapping() { endMapping(); }
     202             : 
     203        8361 : unsigned Input::beginSequence() {
     204       16193 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
     205       15664 :     return SQ->Entries.size();
     206        1058 :   if (isa<EmptyHNode>(CurrentNode))
     207             :     return 0;
     208             :   // Treat case where there's a scalar "null" value as an empty sequence.
     209          11 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     210           5 :     if (isNull(SN->value()))
     211             :       return 0;
     212             :   }
     213             :   // Any other type of HNode is an error.
     214           3 :   setError(CurrentNode, "not a sequence");
     215           3 :   return 0;
     216             : }
     217             : 
     218        7059 : void Input::endSequence() {
     219        7059 : }
     220             : 
     221       24447 : bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
     222       24447 :   if (EC)
     223             :     return false;
     224       48892 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     225       24446 :     SaveInfo = CurrentNode;
     226       73338 :     CurrentNode = SQ->Entries[Index].get();
     227       24446 :     return true;
     228             :   }
     229             :   return false;
     230             : }
     231             : 
     232       24446 : void Input::postflightElement(void *SaveInfo) {
     233       24446 :   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
     234       24446 : }
     235             : 
     236        1302 : unsigned Input::beginFlowSequence() { return beginSequence(); }
     237             : 
     238        9615 : bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
     239        9615 :   if (EC)
     240             :     return false;
     241       19230 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     242        9615 :     SaveInfo = CurrentNode;
     243       28845 :     CurrentNode = SQ->Entries[index].get();
     244        9615 :     return true;
     245             :   }
     246             :   return false;
     247             : }
     248             : 
     249        9615 : void Input::postflightFlowElement(void *SaveInfo) {
     250        9615 :   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
     251        9615 : }
     252             : 
     253        1302 : void Input::endFlowSequence() {
     254        1302 : }
     255             : 
     256       21683 : void Input::beginEnumScalar() {
     257       21683 :   ScalarMatchFound = false;
     258       21683 : }
     259             : 
     260      521445 : bool Input::matchEnumScalar(const char *Str, bool) {
     261      521445 :   if (ScalarMatchFound)
     262             :     return false;
     263      321504 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     264      321504 :     if (SN->value().equals(Str)) {
     265       21651 :       ScalarMatchFound = true;
     266       21651 :       return true;
     267             :     }
     268             :   }
     269             :   return false;
     270             : }
     271             : 
     272        1203 : bool Input::matchEnumFallback() {
     273        1203 :   if (ScalarMatchFound)
     274             :     return false;
     275          30 :   ScalarMatchFound = true;
     276          30 :   return true;
     277             : }
     278             : 
     279       21683 : void Input::endEnumScalar() {
     280       21683 :   if (!ScalarMatchFound) {
     281           2 :     setError(CurrentNode, "unknown enumerated scalar");
     282             :   }
     283       21683 : }
     284             : 
     285        1827 : bool Input::beginBitSetScalar(bool &DoClear) {
     286        3654 :   BitValuesUsed.clear();
     287        3654 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     288        5481 :     BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
     289             :   } else {
     290           0 :     setError(CurrentNode, "expected sequence of bit values");
     291             :   }
     292        1827 :   DoClear = true;
     293        1827 :   return true;
     294             : }
     295             : 
     296       18436 : bool Input::bitSetMatch(const char *Str, bool) {
     297       18436 :   if (EC)
     298             :     return false;
     299       36872 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     300       18436 :     unsigned Index = 0;
     301      106986 :     for (auto &N : SQ->Entries) {
     302       72106 :       if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
     303       72106 :         if (SN->value().equals(Str)) {
     304        8433 :           BitValuesUsed[Index] = true;
     305        2811 :           return true;
     306             :         }
     307             :       } else {
     308           0 :         setError(CurrentNode, "unexpected scalar in sequence of bit values");
     309             :       }
     310       33242 :       ++Index;
     311             :     }
     312             :   } else {
     313           0 :     setError(CurrentNode, "expected sequence of bit values");
     314             :   }
     315             :   return false;
     316             : }
     317             : 
     318        1827 : void Input::endBitSetScalar() {
     319        1827 :   if (EC)
     320             :     return;
     321        1827 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     322             :     assert(BitValuesUsed.size() == SQ->Entries.size());
     323       12087 :     for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
     324        8436 :       if (!BitValuesUsed[i]) {
     325           3 :         setError(SQ->Entries[i].get(), "unknown bit value");
     326           1 :         return;
     327             :       }
     328             :     }
     329             :   }
     330             : }
     331             : 
     332       97225 : void Input::scalarString(StringRef &S, bool) {
     333      194450 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     334       97225 :     S = SN->value();
     335             :   } else {
     336           0 :     setError(CurrentNode, "unexpected scalar");
     337             :   }
     338       97225 : }
     339             : 
     340        2245 : void Input::blockScalarString(StringRef &S) { scalarString(S, false); }
     341             : 
     342          73 : void Input::setError(HNode *hnode, const Twine &message) {
     343             :   assert(hnode && "HNode must not be NULL");
     344          73 :   this->setError(hnode->_node, message);
     345          73 : }
     346             : 
     347          74 : void Input::setError(Node *node, const Twine &message) {
     348         148 :   Strm->printError(node, message);
     349          74 :   EC = make_error_code(errc::invalid_argument);
     350          74 : }
     351             : 
     352      165264 : std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
     353      330528 :   SmallString<128> StringStorage;
     354      284733 :   if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
     355      119469 :     StringRef KeyStr = SN->getValue(StringStorage);
     356      119469 :     if (!StringStorage.empty()) {
     357             :       // Copy string to permanent storage
     358           7 :       KeyStr = StringStorage.str().copy(StringAllocator);
     359             :     }
     360      477876 :     return llvm::make_unique<ScalarHNode>(N, KeyStr);
     361       48623 :   } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
     362        2828 :     StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
     363       11312 :     return llvm::make_unique<ScalarHNode>(N, ValueCopy);
     364       52666 :   } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
     365       19398 :     auto SQHNode = llvm::make_unique<SequenceHNode>(N);
     366       93304 :     for (Node &SN : *SQ) {
     367       73906 :       auto Entry = this->createHNodes(&SN);
     368       36953 :       if (EC)
     369             :         break;
     370       73906 :       SQHNode->Entries.push_back(std::move(Entry));
     371             :     }
     372       19398 :     return std::move(SQHNode);
     373       65969 :   } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
     374       65402 :     auto mapHNode = llvm::make_unique<MapHNode>(N);
     375      312307 :     for (KeyValueNode &KVN : *Map) {
     376      123453 :       Node *KeyNode = KVN.getKey();
     377      123452 :       ScalarNode *KeyScalar = dyn_cast<ScalarNode>(KeyNode);
     378             :       if (!KeyScalar) {
     379           1 :         setError(KeyNode, "Map key must be a scalar");
     380           2 :         break;
     381             :       }
     382      123452 :       StringStorage.clear();
     383      123452 :       StringRef KeyStr = KeyScalar->getValue(StringStorage);
     384      123452 :       if (!StringStorage.empty()) {
     385             :         // Copy string to permanent storage
     386           0 :         KeyStr = StringStorage.str().copy(StringAllocator);
     387             :       }
     388      246904 :       auto ValueHNode = this->createHNodes(KVN.getValue());
     389      123452 :       if (EC)
     390             :         break;
     391      493808 :       mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
     392             :     }
     393       65402 :     return std::move(mapHNode);
     394        1134 :   } else if (isa<NullNode>(N)) {
     395        2268 :     return llvm::make_unique<EmptyHNode>(N);
     396             :   } else {
     397           0 :     setError(N, "unknown node kind");
     398             :     return nullptr;
     399             :   }
     400             : }
     401             : 
     402          35 : void Input::setError(const Twine &Message) {
     403          35 :   this->setError(CurrentNode, Message);
     404          35 : }
     405             : 
     406       10220 : bool Input::canElideEmptySequence() {
     407       10220 :   return false;
     408             : }
     409             : 
     410             : //===----------------------------------------------------------------------===//
     411             : //  Output
     412             : //===----------------------------------------------------------------------===//
     413             : 
     414        3869 : Output::Output(raw_ostream &yout, void *context, int WrapColumn)
     415        7738 :     : IO(context), Out(yout), WrapColumn(WrapColumn) {}
     416             : 
     417             : Output::~Output() = default;
     418             : 
     419     1039273 : bool Output::outputting() {
     420     1039273 :   return true;
     421             : }
     422             : 
     423       33092 : void Output::beginMapping() {
     424       33092 :   StateStack.push_back(inMapFirstKey);
     425       33092 :   NeedsNewLine = true;
     426       33092 : }
     427             : 
     428         834 : bool Output::mapTag(StringRef Tag, bool Use) {
     429         834 :   if (Use) {
     430             :     // If this tag is being written inside a sequence we should write the start
     431             :     // of the sequence before writing the tag, otherwise the tag won't be
     432             :     // attached to the element in the sequence, but rather the sequence itself.
     433             :     bool SequenceElement =
     434         798 :         StateStack.size() > 1 && (StateStack[StateStack.size() - 2] == inSeq ||
     435          20 :           StateStack[StateStack.size() - 2] == inFlowSeq);
     436          40 :     if (SequenceElement && StateStack.back() == inMapFirstKey) {
     437          20 :       this->newLineCheck();
     438             :     } else {
     439         359 :       this->output(" ");
     440             :     }
     441         379 :     this->output(Tag);
     442         379 :     if (SequenceElement) {
     443             :       // If we're writing the tag during the first element of a map, the tag
     444             :       // takes the place of the first element in the sequence.
     445          40 :       if (StateStack.back() == inMapFirstKey) {
     446          40 :         StateStack.pop_back();
     447          20 :         StateStack.push_back(inMapOtherKey);
     448             :       }
     449             :       // Tags inside maps in sequences should act as keys in the map from a
     450             :       // formatting perspective, so we always want a newline in a sequence.
     451          20 :       NeedsNewLine = true;
     452             :     }
     453             :   }
     454         834 :   return Use;
     455             : }
     456             : 
     457       33092 : void Output::endMapping() {
     458       66184 :   StateStack.pop_back();
     459       33092 : }
     460             : 
     461           0 : std::vector<StringRef> Output::keys() {
     462           0 :   report_fatal_error("invalid call");
     463             : }
     464             : 
     465      310183 : bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
     466             :                           bool &UseDefault, void *&) {
     467      310183 :   UseDefault = false;
     468      310183 :   if (Required || !SameAsDefault || WriteDefaultValues) {
     469      456866 :     auto State = StateStack.back();
     470      228433 :     if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
     471       40239 :       flowKey(Key);
     472             :     } else {
     473      188194 :       this->newLineCheck();
     474      188194 :       this->paddedKey(Key);
     475             :     }
     476             :     return true;
     477             :   }
     478             :   return false;
     479             : }
     480             : 
     481      228433 : void Output::postflightKey(void *) {
     482      456866 :   if (StateStack.back() == inMapFirstKey) {
     483       66070 :     StateStack.pop_back();
     484       33035 :     StateStack.push_back(inMapOtherKey);
     485      390796 :   } else if (StateStack.back() == inFlowMapFirstKey) {
     486       24778 :     StateStack.pop_back();
     487       12389 :     StateStack.push_back(inFlowMapOtherKey);
     488             :   }
     489      228433 : }
     490             : 
     491       12389 : void Output::beginFlowMapping() {
     492       12389 :   StateStack.push_back(inFlowMapFirstKey);
     493       12389 :   this->newLineCheck();
     494       12389 :   ColumnAtMapFlowStart = Column;
     495       12389 :   output("{ ");
     496       12389 : }
     497             : 
     498       12389 : void Output::endFlowMapping() {
     499       24778 :   StateStack.pop_back();
     500       12389 :   this->outputUpToEndOfLine(" }");
     501       12389 : }
     502             : 
     503        4030 : void Output::beginDocuments() {
     504        4030 :   this->outputUpToEndOfLine("---");
     505        4030 : }
     506             : 
     507        4032 : bool Output::preflightDocument(unsigned index) {
     508        4032 :   if (index > 0)
     509           2 :     this->outputUpToEndOfLine("\n---");
     510        4032 :   return true;
     511             : }
     512             : 
     513        4032 : void Output::postflightDocument() {
     514        4032 : }
     515             : 
     516        4030 : void Output::endDocuments() {
     517        4030 :   output("\n...\n");
     518        4030 : }
     519             : 
     520       16904 : unsigned Output::beginSequence() {
     521       16904 :   StateStack.push_back(inSeq);
     522       16904 :   NeedsNewLine = true;
     523       16904 :   return 0;
     524             : }
     525             : 
     526       16904 : void Output::endSequence() {
     527       33808 :   StateStack.pop_back();
     528       16904 : }
     529             : 
     530       44112 : bool Output::preflightElement(unsigned, void *&) {
     531       44112 :   return true;
     532             : }
     533             : 
     534       44112 : void Output::postflightElement(void *) {
     535       44112 : }
     536             : 
     537        1646 : unsigned Output::beginFlowSequence() {
     538        1646 :   StateStack.push_back(inFlowSeq);
     539        1646 :   this->newLineCheck();
     540        1646 :   ColumnAtFlowStart = Column;
     541        1646 :   output("[ ");
     542        1646 :   NeedFlowSequenceComma = false;
     543        1646 :   return 0;
     544             : }
     545             : 
     546        1646 : void Output::endFlowSequence() {
     547        3292 :   StateStack.pop_back();
     548        1646 :   this->outputUpToEndOfLine(" ]");
     549        1646 : }
     550             : 
     551        7570 : bool Output::preflightFlowElement(unsigned, void *&) {
     552        7570 :   if (NeedFlowSequenceComma)
     553        5948 :     output(", ");
     554        7570 :   if (WrapColumn && Column > WrapColumn) {
     555         325 :     output("\n");
     556        7181 :     for (int i = 0; i < ColumnAtFlowStart; ++i)
     557        6856 :       output(" ");
     558         325 :     Column = ColumnAtFlowStart;
     559         325 :     output("  ");
     560             :   }
     561        7570 :   return true;
     562             : }
     563             : 
     564        7570 : void Output::postflightFlowElement(void *) {
     565        7570 :   NeedFlowSequenceComma = true;
     566        7570 : }
     567             : 
     568       29955 : void Output::beginEnumScalar() {
     569       29955 :   EnumerationMatchFound = false;
     570       29955 : }
     571             : 
     572      601969 : bool Output::matchEnumScalar(const char *Str, bool Match) {
     573      601969 :   if (Match && !EnumerationMatchFound) {
     574       29932 :     this->newLineCheck();
     575       29932 :     this->outputUpToEndOfLine(Str);
     576       29932 :     EnumerationMatchFound = true;
     577             :   }
     578      601969 :   return false;
     579             : }
     580             : 
     581        6742 : bool Output::matchEnumFallback() {
     582        6742 :   if (EnumerationMatchFound)
     583             :     return false;
     584          23 :   EnumerationMatchFound = true;
     585          23 :   return true;
     586             : }
     587             : 
     588       29955 : void Output::endEnumScalar() {
     589       29955 :   if (!EnumerationMatchFound)
     590           0 :     llvm_unreachable("bad runtime enum value");
     591       29955 : }
     592             : 
     593         379 : bool Output::beginBitSetScalar(bool &DoClear) {
     594         379 :   this->newLineCheck();
     595         379 :   output("[ ");
     596         379 :   NeedBitValueComma = false;
     597         379 :   DoClear = false;
     598         379 :   return true;
     599             : }
     600             : 
     601        4068 : bool Output::bitSetMatch(const char *Str, bool Matches) {
     602        4068 :   if (Matches) {
     603         929 :     if (NeedBitValueComma)
     604         565 :       output(", ");
     605         929 :     this->output(Str);
     606         929 :     NeedBitValueComma = true;
     607             :   }
     608        4068 :   return false;
     609             : }
     610             : 
     611         379 : void Output::endBitSetScalar() {
     612         379 :   this->outputUpToEndOfLine(" ]");
     613         379 : }
     614             : 
     615      186755 : void Output::scalarString(StringRef &S, bool MustQuote) {
     616      186755 :   this->newLineCheck();
     617      186755 :   if (S.empty()) {
     618             :     // Print '' for the empty string because leaving the field empty is not
     619             :     // allowed.
     620       35679 :     this->outputUpToEndOfLine("''");
     621       35679 :     return;
     622             :   }
     623      151076 :   if (!MustQuote) {
     624             :     // Only quote if we must.
     625      147955 :     this->outputUpToEndOfLine(S);
     626      147955 :     return;
     627             :   }
     628        3121 :   unsigned i = 0;
     629        3121 :   unsigned j = 0;
     630        3121 :   unsigned End = S.size();
     631        3121 :   output("'"); // Starting single quote.
     632        3121 :   const char *Base = S.data();
     633      108333 :   while (j < End) {
     634             :     // Escape a single quote by doubling it.
     635      105212 :     if (S[j] == '\'') {
     636          24 :       output(StringRef(&Base[i], j - i + 1));
     637          12 :       output("'");
     638          12 :       i = j + 1;
     639             :     }
     640       52606 :     ++j;
     641             :   }
     642        6242 :   output(StringRef(&Base[i], j - i));
     643        3121 :   this->outputUpToEndOfLine("'"); // Ending single quote.
     644             : }
     645             : 
     646        3050 : void Output::blockScalarString(StringRef &S) {
     647        3050 :   if (!StateStack.empty())
     648        2461 :     newLineCheck();
     649        3050 :   output(" |");
     650        3050 :   outputNewLine();
     651             : 
     652        5511 :   unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
     653             : 
     654        6100 :   auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
     655       55124 :   for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
     656      147072 :     for (unsigned I = 0; I < Indent; ++I) {
     657       49024 :       output("  ");
     658             :     }
     659       49024 :     output(*Lines);
     660       49024 :     outputNewLine();
     661             :   }
     662        3050 : }
     663             : 
     664           0 : void Output::setError(const Twine &message) {
     665           0 : }
     666             : 
     667       17282 : bool Output::canElideEmptySequence() {
     668             :   // Normally, with an optional key/value where the value is an empty sequence,
     669             :   // the whole key/value can be not written.  But, that produces wrong yaml
     670             :   // if the key/value is the only thing in the map and the map is used in
     671             :   // a sequence.  This detects if the this sequence is the first key/value
     672             :   // in map that itself is embedded in a sequnce.
     673       34564 :   if (StateStack.size() < 2)
     674             :     return true;
     675       32432 :   if (StateStack.back() != inMapFirstKey)
     676             :     return true;
     677         288 :   return (StateStack[StateStack.size()-2] != inSeq);
     678             : }
     679             : 
     680     1523596 : void Output::output(StringRef s) {
     681     1523596 :   Column += s.size();
     682     1523596 :   Out << s;
     683     1523596 : }
     684             : 
     685      235133 : void Output::outputUpToEndOfLine(StringRef s) {
     686      235133 :   this->output(s);
     687      689753 :   if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
     688      434661 :                              StateStack.back() != inFlowMapFirstKey &&
     689      211136 :                              StateStack.back() != inFlowMapOtherKey))
     690      187324 :     NeedsNewLine = true;
     691      235133 : }
     692             : 
     693      262518 : void Output::outputNewLine() {
     694      262518 :   Out << "\n";
     695      262518 :   Column = 0;
     696      262518 : }
     697             : 
     698             : // if seq at top, indent as if map, then add "- "
     699             : // if seq in middle, use "- " if firstKey, else use "  "
     700             : //
     701             : 
     702      421776 : void Output::newLineCheck() {
     703      421776 :   if (!NeedsNewLine)
     704             :     return;
     705      210444 :   NeedsNewLine = false;
     706             : 
     707      210444 :   this->outputNewLine();
     708             : 
     709             :   assert(StateStack.size() > 0);
     710      420888 :   unsigned Indent = StateStack.size() - 1;
     711      210444 :   bool OutputDash = false;
     712             : 
     713      420888 :   if (StateStack.back() == inSeq) {
     714             :     OutputDash = true;
     715      861234 :   } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
     716      267341 :              (StateStack.back() == inFlowSeq) ||
     717      376049 :              (StateStack.back() == inFlowMapFirstKey)) &&
     718      125685 :              (StateStack[StateStack.size() - 2] == inSeq)) {
     719       34153 :     --Indent;
     720       34153 :     OutputDash = true;
     721             :   }
     722             : 
     723      635606 :   for (unsigned i = 0; i < Indent; ++i) {
     724      425162 :     output("  ");
     725             :   }
     726      210444 :   if (OutputDash) {
     727       44112 :     output("- ");
     728             :   }
     729             : 
     730             : }
     731             : 
     732      188194 : void Output::paddedKey(StringRef key) {
     733      188194 :   output(key);
     734      188194 :   output(":");
     735      188194 :   const char *spaces = "                ";
     736      188194 :   if (key.size() < strlen(spaces))
     737      296448 :     output(&spaces[key.size()]);
     738             :   else
     739       39970 :     output(" ");
     740      188194 : }
     741             : 
     742       40239 : void Output::flowKey(StringRef Key) {
     743       80478 :   if (StateStack.back() == inFlowMapOtherKey)
     744       27850 :     output(", ");
     745       40239 :   if (WrapColumn && Column > WrapColumn) {
     746         734 :     output("\n");
     747        4051 :     for (int I = 0; I < ColumnAtMapFlowStart; ++I)
     748        3317 :       output(" ");
     749         734 :     Column = ColumnAtMapFlowStart;
     750         734 :     output("  ");
     751             :   }
     752       40239 :   output(Key);
     753       40239 :   output(": ");
     754       40239 : }
     755             : 
     756             : //===----------------------------------------------------------------------===//
     757             : //  traits for built-in types
     758             : //===----------------------------------------------------------------------===//
     759             : 
     760       35105 : void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
     761       35105 :   Out << (Val ? "true" : "false");
     762       35105 : }
     763             : 
     764        7958 : StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
     765       12098 :   if (Scalar.equals("true")) {
     766        4140 :     Val = true;
     767        4140 :     return StringRef();
     768        7636 :   } else if (Scalar.equals("false")) {
     769        3818 :     Val = false;
     770        3818 :     return StringRef();
     771             :   }
     772           0 :   return "invalid boolean";
     773             : }
     774             : 
     775       21327 : void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
     776             :                                      raw_ostream &Out) {
     777       21327 :   Out << Val;
     778       21327 : }
     779             : 
     780        7297 : StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
     781             :                                          StringRef &Val) {
     782        7297 :   Val = Scalar;
     783        7297 :   return StringRef();
     784             : }
     785             : 
     786        6502 : void ScalarTraits<std::string>::output(const std::string &Val, void *,
     787             :                                      raw_ostream &Out) {
     788        6502 :   Out << Val;
     789        6502 : }
     790             : 
     791        7754 : StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
     792             :                                          std::string &Val) {
     793       15508 :   Val = Scalar.str();
     794        7754 :   return StringRef();
     795             : }
     796             : 
     797       20957 : void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
     798             :                                    raw_ostream &Out) {
     799             :   // use temp uin32_t because ostream thinks uint8_t is a character
     800       20957 :   uint32_t Num = Val;
     801       20957 :   Out << Num;
     802       20957 : }
     803             : 
     804        8529 : StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
     805             :   unsigned long long n;
     806        8529 :   if (getAsUnsignedInteger(Scalar, 0, n))
     807           0 :     return "invalid number";
     808        8529 :   if (n > 0xFF)
     809           1 :     return "out of range number";
     810        8528 :   Val = n;
     811        8528 :   return StringRef();
     812             : }
     813             : 
     814        7211 : void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
     815             :                                     raw_ostream &Out) {
     816       14422 :   Out << Val;
     817        7211 : }
     818             : 
     819        5836 : StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
     820             :                                         uint16_t &Val) {
     821             :   unsigned long long n;
     822        5836 :   if (getAsUnsignedInteger(Scalar, 0, n))
     823           0 :     return "invalid number";
     824        5836 :   if (n > 0xFFFF)
     825           1 :     return "out of range number";
     826        5835 :   Val = n;
     827        5835 :   return StringRef();
     828             : }
     829             : 
     830       41638 : void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
     831             :                                     raw_ostream &Out) {
     832       83276 :   Out << Val;
     833       41638 : }
     834             : 
     835       27636 : StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
     836             :                                         uint32_t &Val) {
     837             :   unsigned long long n;
     838       27636 :   if (getAsUnsignedInteger(Scalar, 0, n))
     839           1 :     return "invalid number";
     840       27635 :   if (n > 0xFFFFFFFFUL)
     841           1 :     return "out of range number";
     842       27634 :   Val = n;
     843       27634 :   return StringRef();
     844             : }
     845             : 
     846        7400 : void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
     847             :                                     raw_ostream &Out) {
     848        7400 :   Out << Val;
     849        7400 : }
     850             : 
     851        3739 : StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
     852             :                                         uint64_t &Val) {
     853             :   unsigned long long N;
     854        3739 :   if (getAsUnsignedInteger(Scalar, 0, N))
     855           1 :     return "invalid number";
     856        3738 :   Val = N;
     857        3738 :   return StringRef();
     858             : }
     859             : 
     860           1 : void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
     861             :   // use temp in32_t because ostream thinks int8_t is a character
     862           1 :   int32_t Num = Val;
     863           1 :   Out << Num;
     864           1 : }
     865             : 
     866          10 : StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
     867             :   long long N;
     868          10 :   if (getAsSignedInteger(Scalar, 0, N))
     869           0 :     return "invalid number";
     870          10 :   if ((N > 127) || (N < -128))
     871           2 :     return "out of range number";
     872           8 :   Val = N;
     873           8 :   return StringRef();
     874             : }
     875             : 
     876           2 : void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
     877             :                                    raw_ostream &Out) {
     878           4 :   Out << Val;
     879           2 : }
     880             : 
     881          12 : StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
     882             :   long long N;
     883          12 :   if (getAsSignedInteger(Scalar, 0, N))
     884           0 :     return "invalid number";
     885          12 :   if ((N > INT16_MAX) || (N < INT16_MIN))
     886           2 :     return "out of range number";
     887          10 :   Val = N;
     888          10 :   return StringRef();
     889             : }
     890             : 
     891        2802 : void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
     892             :                                    raw_ostream &Out) {
     893        5604 :   Out << Val;
     894        2802 : }
     895             : 
     896        2481 : StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
     897             :   long long N;
     898        2481 :   if (getAsSignedInteger(Scalar, 0, N))
     899           0 :     return "invalid number";
     900        2481 :   if ((N > INT32_MAX) || (N < INT32_MIN))
     901           2 :     return "out of range number";
     902        2479 :   Val = N;
     903        2479 :   return StringRef();
     904             : }
     905             : 
     906         731 : void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
     907             :                                    raw_ostream &Out) {
     908         731 :   Out << Val;
     909         731 : }
     910             : 
     911         314 : StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
     912             :   long long N;
     913         314 :   if (getAsSignedInteger(Scalar, 0, N))
     914           2 :     return "invalid number";
     915         312 :   Val = N;
     916         312 :   return StringRef();
     917             : }
     918             : 
     919           4 : void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
     920           8 :   Out << format("%g", Val);
     921           4 : }
     922             : 
     923          15 : StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
     924          30 :   if (to_float(Scalar, Val))
     925          14 :     return StringRef();
     926           1 :   return "invalid floating point number";
     927             : }
     928             : 
     929           2 : void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
     930           4 :   Out << format("%g", Val);
     931           2 : }
     932             : 
     933           8 : StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
     934          16 :   if (to_float(Scalar, Val))
     935           7 :     return StringRef();
     936           1 :   return "invalid floating point number";
     937             : }
     938             : 
     939         399 : void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
     940         399 :   uint8_t Num = Val;
     941         399 :   Out << format("0x%02X", Num);
     942         399 : }
     943             : 
     944        6248 : StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
     945             :   unsigned long long n;
     946        6248 :   if (getAsUnsignedInteger(Scalar, 0, n))
     947           0 :     return "invalid hex8 number";
     948        6248 :   if (n > 0xFF)
     949           1 :     return "out of range hex8 number";
     950       12494 :   Val = n;
     951        6247 :   return StringRef();
     952             : }
     953             : 
     954          12 : void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
     955          12 :   uint16_t Num = Val;
     956          24 :   Out << format("0x%04X", Num);
     957          12 : }
     958             : 
     959          41 : StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
     960             :   unsigned long long n;
     961          41 :   if (getAsUnsignedInteger(Scalar, 0, n))
     962           0 :     return "invalid hex16 number";
     963          41 :   if (n > 0xFFFF)
     964           1 :     return "out of range hex16 number";
     965          80 :   Val = n;
     966          40 :   return StringRef();
     967             : }
     968             : 
     969        1997 : void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
     970        1997 :   uint32_t Num = Val;
     971        3994 :   Out << format("0x%08X", Num);
     972        1997 : }
     973             : 
     974        2321 : StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
     975             :   unsigned long long n;
     976        2321 :   if (getAsUnsignedInteger(Scalar, 0, n))
     977           0 :     return "invalid hex32 number";
     978        2321 :   if (n > 0xFFFFFFFFUL)
     979           1 :     return "out of range hex32 number";
     980        4640 :   Val = n;
     981        2320 :   return StringRef();
     982             : }
     983             : 
     984         838 : void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
     985         838 :   uint64_t Num = Val;
     986        1676 :   Out << format("0x%016llX", Num);
     987         838 : }
     988             : 
     989        3244 : StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
     990             :   unsigned long long Num;
     991        3244 :   if (getAsUnsignedInteger(Scalar, 0, Num))
     992           1 :     return "invalid hex64 number";
     993        6486 :   Val = Num;
     994        3243 :   return StringRef();
     995             : }

Generated by: LCOV version 1.13