LCOV - code coverage report
Current view: top level - lib/Support - YAMLTraits.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 544 572 95.1 %
Date: 2018-10-20 13:21:21 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       11241 : IO::IO(void *Context) : Ctxt(Context) {}
      41             : 
      42             : IO::~IO() = default;
      43             : 
      44      502951 : void *IO::getContext() {
      45      502951 :   return Ctxt;
      46             : }
      47             : 
      48        3180 : void IO::setContext(void *Context) {
      49        3180 :   Ctxt = Context;
      50        3180 : }
      51             : 
      52             : //===----------------------------------------------------------------------===//
      53             : //  Input
      54             : //===----------------------------------------------------------------------===//
      55             : 
      56        4009 : Input::Input(StringRef InputContent, void *Ctxt,
      57        4009 :              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
      58        4009 :     : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
      59        4009 :   if (DiagHandler)
      60             :     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
      61        4009 :   DocIterator = Strm->begin();
      62        4009 : }
      63             : 
      64           3 : Input::Input(MemoryBufferRef Input, void *Ctxt,
      65           3 :              SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
      66           3 :     : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
      67           3 :   if (DiagHandler)
      68             :     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
      69           3 :   DocIterator = Strm->begin();
      70           3 : }
      71             : 
      72             : Input::~Input() = default;
      73             : 
      74        8153 : 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     1451722 : bool Input::outputting() {
      84     1451722 :   return false;
      85             : }
      86             : 
      87       10737 : bool Input::setCurrentDocument() {
      88       10737 :   if (DocIterator != Strm->end()) {
      89        8406 :     Node *N = DocIterator->getRoot();
      90        8406 :     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        8405 :     if (isa<NullNode>(N)) {
      97             :       // Empty files are allowed and ignored
      98         554 :       ++DocIterator;
      99         554 :       return setCurrentDocument();
     100             :     }
     101       15702 :     TopNode = createHNodes(N);
     102        7851 :     CurrentNode = TopNode.get();
     103        7851 :     return true;
     104             :   }
     105             :   return false;
     106             : }
     107             : 
     108        6709 : bool Input::nextDocument() {
     109        6709 :   return ++DocIterator != Strm->end();
     110             : }
     111             : 
     112       43399 : const Node *Input::getCurrentNode() const {
     113       43399 :   return CurrentNode ? CurrentNode->_node : nullptr;
     114             : }
     115             : 
     116        3959 : bool Input::mapTag(StringRef Tag, bool Default) {
     117        3959 :   std::string foundTag = CurrentNode->_node->getVerbatimTag();
     118        3959 :   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       46993 : void Input::beginMapping() {
     127       46993 :   if (EC)
     128             :     return;
     129             :   // CurrentNode can be null if the document is empty.
     130       46990 :   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
     131             :   if (MN) {
     132       46914 :     MN->ValidKeys.clear();
     133             :   }
     134             : }
     135             : 
     136          85 : std::vector<StringRef> Input::keys() {
     137          85 :   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
     138             :   std::vector<StringRef> Ret;
     139          85 :   if (!MN) {
     140           0 :     setError(CurrentNode, "not a mapping");
     141           0 :     return Ret;
     142             :   }
     143         325 :   for (auto &P : MN->Mapping)
     144         155 :     Ret.push_back(P.first());
     145             :   return Ret;
     146             : }
     147             : 
     148      325291 : bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
     149             :                          void *&SaveInfo) {
     150      325291 :   UseDefault = false;
     151      325291 :   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      325227 :   if (!CurrentNode) {
     157           2 :     if (Required)
     158           1 :       EC = make_error_code(errc::invalid_argument);
     159           2 :     return false;
     160             :   }
     161             : 
     162             :   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
     163             :   if (!MN) {
     164           6 :     if (Required || !isa<EmptyHNode>(CurrentNode))
     165           0 :       setError(CurrentNode, "not a mapping");
     166           6 :     return false;
     167             :   }
     168      650438 :   MN->ValidKeys.push_back(Key);
     169      325219 :   HNode *Value = MN->Mapping[Key].get();
     170      325219 :   if (!Value) {
     171      157613 :     if (Required)
     172          23 :       setError(CurrentNode, Twine("missing required key '") + Key + "'");
     173             :     else
     174      157590 :       UseDefault = true;
     175      157613 :     return false;
     176             :   }
     177      167606 :   SaveInfo = CurrentNode;
     178      167606 :   CurrentNode = Value;
     179      167606 :   return true;
     180             : }
     181             : 
     182      167606 : void Input::postflightKey(void *saveInfo) {
     183      167606 :   CurrentNode = reinterpret_cast<HNode *>(saveInfo);
     184      167606 : }
     185             : 
     186       46993 : void Input::endMapping() {
     187       46993 :   if (EC)
     188             :     return;
     189             :   // CurrentNode can be null if the document is empty.
     190       46936 :   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
     191             :   if (!MN)
     192             :     return;
     193      417912 :   for (const auto &NN : MN->Mapping) {
     194      648406 :     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       17050 : void Input::beginFlowMapping() { beginMapping(); }
     202             : 
     203       17050 : void Input::endFlowMapping() { endMapping(); }
     204             : 
     205       11697 : unsigned Input::beginSequence() {
     206       11697 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
     207       18418 :     return SQ->Entries.size();
     208        2488 :   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       10763 : void Input::endSequence() {
     221       10763 : }
     222             : 
     223       34001 : bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
     224       34001 :   if (EC)
     225             :     return false;
     226       34001 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     227       34001 :     SaveInfo = CurrentNode;
     228       34001 :     CurrentNode = SQ->Entries[Index].get();
     229       34001 :     return true;
     230             :   }
     231             :   return false;
     232             : }
     233             : 
     234       34001 : void Input::postflightElement(void *SaveInfo) {
     235       34001 :   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
     236       34001 : }
     237             : 
     238         934 : unsigned Input::beginFlowSequence() { return beginSequence(); }
     239             : 
     240        8907 : bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
     241        8907 :   if (EC)
     242             :     return false;
     243        8907 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     244        8907 :     SaveInfo = CurrentNode;
     245        8907 :     CurrentNode = SQ->Entries[index].get();
     246        8907 :     return true;
     247             :   }
     248             :   return false;
     249             : }
     250             : 
     251        8907 : void Input::postflightFlowElement(void *SaveInfo) {
     252        8907 :   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
     253        8907 : }
     254             : 
     255         934 : void Input::endFlowSequence() {
     256         934 : }
     257             : 
     258       19810 : void Input::beginEnumScalar() {
     259       19810 :   ScalarMatchFound = false;
     260       19810 : }
     261             : 
     262     1074265 : bool Input::matchEnumScalar(const char *Str, bool) {
     263     1074265 :   if (ScalarMatchFound)
     264             :     return false;
     265      273383 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     266             :     if (SN->value().equals(Str)) {
     267       19777 :       ScalarMatchFound = true;
     268       19777 :       return true;
     269             :     }
     270             :   }
     271             :   return false;
     272             : }
     273             : 
     274        1644 : bool Input::matchEnumFallback() {
     275        1644 :   if (ScalarMatchFound)
     276             :     return false;
     277          31 :   ScalarMatchFound = true;
     278          31 :   return true;
     279             : }
     280             : 
     281       19810 : void Input::endEnumScalar() {
     282       19810 :   if (!ScalarMatchFound) {
     283           2 :     setError(CurrentNode, "unknown enumerated scalar");
     284             :   }
     285       19810 : }
     286             : 
     287        3390 : bool Input::beginBitSetScalar(bool &DoClear) {
     288        3390 :   BitValuesUsed.clear();
     289        3390 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     290        6780 :     BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
     291             :   } else {
     292           0 :     setError(CurrentNode, "expected sequence of bit values");
     293             :   }
     294        3390 :   DoClear = true;
     295        3390 :   return true;
     296             : }
     297             : 
     298       37734 : bool Input::bitSetMatch(const char *Str, bool) {
     299       37734 :   if (EC)
     300             :     return false;
     301       37734 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     302             :     unsigned Index = 0;
     303      107202 :     for (auto &N : SQ->Entries) {
     304             :       if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
     305             :         if (SN->value().equals(Str)) {
     306        6019 :           BitValuesUsed[Index] = true;
     307             :           return true;
     308             :         }
     309             :       } else {
     310           0 :         setError(CurrentNode, "unexpected scalar in sequence of bit values");
     311             :       }
     312       69468 :       ++Index;
     313             :     }
     314             :   } else {
     315           0 :     setError(CurrentNode, "expected sequence of bit values");
     316             :   }
     317             :   return false;
     318             : }
     319             : 
     320        3390 : void Input::endBitSetScalar() {
     321        3390 :   if (EC)
     322             :     return;
     323        3390 :   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
     324             :     assert(BitValuesUsed.size() == SQ->Entries.size());
     325       12799 :     for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
     326       12040 :       if (!BitValuesUsed[i]) {
     327           1 :         setError(SQ->Entries[i].get(), "unknown bit value");
     328           1 :         return;
     329             :       }
     330             :     }
     331             :   }
     332             : }
     333             : 
     334      135609 : void Input::scalarString(StringRef &S, QuotingType) {
     335      135609 :   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
     336      135609 :     S = SN->value();
     337             :   } else {
     338           0 :     setError(CurrentNode, "unexpected scalar");
     339             :   }
     340      135609 : }
     341             : 
     342        4575 : void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
     343             : 
     344          78 : void Input::setError(HNode *hnode, const Twine &message) {
     345             :   assert(hnode && "HNode must not be NULL");
     346          78 :   setError(hnode->_node, message);
     347          78 : }
     348             : 
     349          80 : void Input::setError(Node *node, const Twine &message) {
     350          80 :   Strm->printError(node, message);
     351          80 :   EC = make_error_code(errc::invalid_argument);
     352          80 : }
     353             : 
     354      224190 : std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
     355             :   SmallString<128> StringStorage;
     356             :   if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
     357      156530 :     StringRef KeyStr = SN->getValue(StringStorage);
     358      156530 :     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        5479 :     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       61662 :     for (Node &SN : *SQ) {
     369       49015 :       auto Entry = createHNodes(&SN);
     370       49015 :       if (EC)
     371             :         break;
     372       49015 :       SQHNode->Entries.push_back(std::move(Entry));
     373             :     }
     374             :     return std::move(SQHNode);
     375             :   } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
     376       46976 :     auto mapHNode = llvm::make_unique<MapHNode>(N);
     377      214300 :     for (KeyValueNode &KVN : *Map) {
     378      167326 :       Node *KeyNode = KVN.getKey();
     379             :       ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode);
     380      167326 :       Node *Value = KVN.getValue();
     381      167326 :       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      167324 :       StringRef KeyStr = Key->getValue(StringStorage);
     390      167324 :       if (!StringStorage.empty()) {
     391             :         // Copy string to permanent storage
     392           0 :         KeyStr = StringStorage.str().copy(StringAllocator);
     393             :       }
     394      167324 :       auto ValueHNode = createHNodes(Value);
     395      167324 :       if (EC)
     396             :         break;
     397      167324 :       mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
     398             :     }
     399             :     return std::move(mapHNode);
     400        2558 :   } 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 :   setError(CurrentNode, Message);
     410          36 : }
     411             : 
     412       12122 : bool Input::canElideEmptySequence() {
     413       12122 :   return false;
     414             : }
     415             : 
     416             : //===----------------------------------------------------------------------===//
     417             : //  Output
     418             : //===----------------------------------------------------------------------===//
     419             : 
     420        7229 : Output::Output(raw_ostream &yout, void *context, int WrapColumn)
     421        7229 :     : IO(context), Out(yout), WrapColumn(WrapColumn) {}
     422             : 
     423             : Output::~Output() = default;
     424             : 
     425     1926080 : bool Output::outputting() {
     426     1926080 :   return true;
     427             : }
     428             : 
     429       55221 : void Output::beginMapping() {
     430       55221 :   StateStack.push_back(inMapFirstKey);
     431       55221 :   NeedsNewLine = true;
     432       55221 : }
     433             : 
     434        1431 : bool Output::mapTag(StringRef Tag, bool Use) {
     435        1431 :   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        1484 :         StateStack.size() > 1 && (StateStack[StateStack.size() - 2] == inSeq ||
     441             :           StateStack[StateStack.size() - 2] == inFlowSeq);
     442          57 :     if (SequenceElement && StateStack.back() == inMapFirstKey) {
     443          57 :       newLineCheck();
     444             :     } else {
     445         685 :       output(" ");
     446             :     }
     447         742 :     output(Tag);
     448         742 :     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          57 :       if (StateStack.back() == inMapFirstKey) {
     452          57 :         StateStack.pop_back();
     453          57 :         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          57 :       NeedsNewLine = true;
     458             :     }
     459             :   }
     460        1431 :   return Use;
     461             : }
     462             : 
     463       55221 : void Output::endMapping() {
     464             :   StateStack.pop_back();
     465       55221 : }
     466             : 
     467           0 : std::vector<StringRef> Output::keys() {
     468           0 :   report_fatal_error("invalid call");
     469             : }
     470             : 
     471      589434 : bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
     472             :                           bool &UseDefault, void *&) {
     473      589434 :   UseDefault = false;
     474      589434 :   if (Required || !SameAsDefault || WriteDefaultValues) {
     475      438899 :     auto State = StateStack.back();
     476      438899 :     if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
     477       84611 :       flowKey(Key);
     478             :     } else {
     479      354288 :       newLineCheck();
     480      354288 :       paddedKey(Key);
     481             :     }
     482      438899 :     return true;
     483             :   }
     484             :   return false;
     485             : }
     486             : 
     487      438899 : void Output::postflightKey(void *) {
     488      438899 :   if (StateStack.back() == inMapFirstKey) {
     489       55003 :     StateStack.pop_back();
     490       55003 :     StateStack.push_back(inMapOtherKey);
     491      383896 :   } else if (StateStack.back() == inFlowMapFirstKey) {
     492       25797 :     StateStack.pop_back();
     493       25797 :     StateStack.push_back(inFlowMapOtherKey);
     494             :   }
     495      438899 : }
     496             : 
     497       25797 : void Output::beginFlowMapping() {
     498       25797 :   StateStack.push_back(inFlowMapFirstKey);
     499       25797 :   newLineCheck();
     500       25797 :   ColumnAtMapFlowStart = Column;
     501       25797 :   output("{ ");
     502       25797 : }
     503             : 
     504       25797 : void Output::endFlowMapping() {
     505             :   StateStack.pop_back();
     506       25797 :   outputUpToEndOfLine(" }");
     507       25797 : }
     508             : 
     509        7396 : void Output::beginDocuments() {
     510        7396 :   outputUpToEndOfLine("---");
     511        7396 : }
     512             : 
     513        7397 : bool Output::preflightDocument(unsigned index) {
     514        7397 :   if (index > 0)
     515           2 :     outputUpToEndOfLine("\n---");
     516        7397 :   return true;
     517             : }
     518             : 
     519        7397 : void Output::postflightDocument() {
     520        7397 : }
     521             : 
     522        7396 : void Output::endDocuments() {
     523        7396 :   output("\n...\n");
     524        7396 : }
     525             : 
     526       31395 : unsigned Output::beginSequence() {
     527       31395 :   StateStack.push_back(inSeq);
     528       31395 :   NeedsNewLine = true;
     529       31395 :   return 0;
     530             : }
     531             : 
     532       31395 : void Output::endSequence() {
     533             :   StateStack.pop_back();
     534       31395 : }
     535             : 
     536       70516 : bool Output::preflightElement(unsigned, void *&) {
     537       70516 :   return true;
     538             : }
     539             : 
     540       70516 : void Output::postflightElement(void *) {
     541       70516 : }
     542             : 
     543        1951 : unsigned Output::beginFlowSequence() {
     544        1951 :   StateStack.push_back(inFlowSeq);
     545        1951 :   newLineCheck();
     546        1951 :   ColumnAtFlowStart = Column;
     547        1951 :   output("[ ");
     548        1951 :   NeedFlowSequenceComma = false;
     549        1951 :   return 0;
     550             : }
     551             : 
     552        1951 : void Output::endFlowSequence() {
     553             :   StateStack.pop_back();
     554        1951 :   outputUpToEndOfLine(" ]");
     555        1951 : }
     556             : 
     557        8514 : bool Output::preflightFlowElement(unsigned, void *&) {
     558        8514 :   if (NeedFlowSequenceComma)
     559        6588 :     output(", ");
     560        8514 :   if (WrapColumn && Column > WrapColumn) {
     561         337 :     output("\n");
     562        7457 :     for (int i = 0; i < ColumnAtFlowStart; ++i)
     563        7120 :       output(" ");
     564         337 :     Column = ColumnAtFlowStart;
     565         337 :     output("  ");
     566             :   }
     567        8514 :   return true;
     568             : }
     569             : 
     570        8514 : void Output::postflightFlowElement(void *) {
     571        8514 :   NeedFlowSequenceComma = true;
     572        8514 : }
     573             : 
     574       49297 : void Output::beginEnumScalar() {
     575       49297 :   EnumerationMatchFound = false;
     576       49297 : }
     577             : 
     578     1108154 : bool Output::matchEnumScalar(const char *Str, bool Match) {
     579     1108154 :   if (Match && !EnumerationMatchFound) {
     580       49274 :     newLineCheck();
     581       49274 :     outputUpToEndOfLine(Str);
     582       49274 :     EnumerationMatchFound = true;
     583             :   }
     584     1108154 :   return false;
     585             : }
     586             : 
     587        6799 : bool Output::matchEnumFallback() {
     588        6799 :   if (EnumerationMatchFound)
     589             :     return false;
     590          23 :   EnumerationMatchFound = true;
     591          23 :   return true;
     592             : }
     593             : 
     594       49297 : void Output::endEnumScalar() {
     595       49297 :   if (!EnumerationMatchFound)
     596           0 :     llvm_unreachable("bad runtime enum value");
     597       49297 : }
     598             : 
     599        1449 : bool Output::beginBitSetScalar(bool &DoClear) {
     600        1449 :   newLineCheck();
     601        1449 :   output("[ ");
     602        1449 :   NeedBitValueComma = false;
     603        1449 :   DoClear = false;
     604        1449 :   return true;
     605             : }
     606             : 
     607       12380 : bool Output::bitSetMatch(const char *Str, bool Matches) {
     608       12380 :   if (Matches) {
     609        2629 :     if (NeedBitValueComma)
     610        1463 :       output(", ");
     611        2629 :     output(Str);
     612        2629 :     NeedBitValueComma = true;
     613             :   }
     614       12380 :   return false;
     615             : }
     616             : 
     617        1449 : void Output::endBitSetScalar() {
     618        1449 :   outputUpToEndOfLine(" ]");
     619        1449 : }
     620             : 
     621      354511 : void Output::scalarString(StringRef &S, QuotingType MustQuote) {
     622      354511 :   newLineCheck();
     623      354511 :   if (S.empty()) {
     624             :     // Print '' for the empty string because leaving the field empty is not
     625             :     // allowed.
     626       56328 :     outputUpToEndOfLine("''");
     627       56328 :     return;
     628             :   }
     629      298183 :   if (MustQuote == QuotingType::None) {
     630             :     // Only quote if we must.
     631      285280 :     outputUpToEndOfLine(S);
     632      285280 :     return;
     633             :   }
     634             : 
     635             :   unsigned i = 0;
     636             :   unsigned j = 0;
     637       12903 :   unsigned End = S.size();
     638             :   const char *Base = S.data();
     639             : 
     640       12903 :   const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
     641       12903 :   output(Quote); // Starting quote.
     642             : 
     643             :   // When using double-quoted strings (and only in that case), non-printable characters may be
     644             :   // present, and will be escaped using a variety of unicode-scalar and special short-form
     645             :   // escapes. This is handled in yaml::escape.
     646       12903 :   if (MustQuote == QuotingType::Double) {
     647          10 :     output(yaml::escape(Base, /* EscapePrintable= */ false));
     648           7 :     outputUpToEndOfLine(Quote);
     649           7 :     return;
     650             :   }
     651             : 
     652             :   // When using single-quoted strings, any single quote ' must be doubled to be escaped.
     653      290208 :   while (j < End) {
     654      554624 :     if (S[j] == '\'') {                    // Escape quotes.
     655          26 :       output(StringRef(&Base[i], j - i));  // "flush".
     656          13 :       output(StringLiteral("''"));         // Print it as ''
     657          13 :       i = j + 1;
     658             :     }
     659      277312 :     ++j;
     660             :   }
     661       25792 :   output(StringRef(&Base[i], j - i));
     662       12896 :   outputUpToEndOfLine(Quote); // Ending quote.
     663             : }
     664             : 
     665        5891 : void Output::blockScalarString(StringRef &S) {
     666        5891 :   if (!StateStack.empty())
     667        4770 :     newLineCheck();
     668        5891 :   output(" |");
     669        5891 :   outputNewLine();
     670             : 
     671        5891 :   unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
     672             : 
     673        5891 :   auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
     674      105639 :   for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
     675      199496 :     for (unsigned I = 0; I < Indent; ++I) {
     676       99748 :       output("  ");
     677             :     }
     678       99748 :     output(*Lines);
     679       99748 :     outputNewLine();
     680             :   }
     681        5891 : }
     682             : 
     683           0 : void Output::setError(const Twine &message) {
     684           0 : }
     685             : 
     686       21115 : bool Output::canElideEmptySequence() {
     687             :   // Normally, with an optional key/value where the value is an empty sequence,
     688             :   // the whole key/value can be not written.  But, that produces wrong yaml
     689             :   // if the key/value is the only thing in the map and the map is used in
     690             :   // a sequence.  This detects if the this sequence is the first key/value
     691             :   // in map that itself is embedded in a sequnce.
     692       42230 :   if (StateStack.size() < 2)
     693             :     return true;
     694       19499 :   if (StateStack.back() != inMapFirstKey)
     695             :     return true;
     696         770 :   return (StateStack[StateStack.size()-2] != inSeq);
     697             : }
     698             : 
     699     2882292 : void Output::output(StringRef s) {
     700     2882292 :   Column += s.size();
     701     2882292 :   Out << s;
     702     2882292 : }
     703             : 
     704      440380 : void Output::outputUpToEndOfLine(StringRef s) {
     705      440380 :   output(s);
     706      440380 :   if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
     707      398655 :                              StateStack.back() != inFlowMapFirstKey &&
     708             :                              StateStack.back() != inFlowMapOtherKey))
     709      347255 :     NeedsNewLine = true;
     710      440380 : }
     711             : 
     712      495681 : void Output::outputNewLine() {
     713      495681 :   Out << "\n";
     714      495681 :   Column = 0;
     715      495681 : }
     716             : 
     717             : // if seq at top, indent as if map, then add "- "
     718             : // if seq in middle, use "- " if firstKey, else use "  "
     719             : //
     720             : 
     721      792097 : void Output::newLineCheck() {
     722      792097 :   if (!NeedsNewLine)
     723             :     return;
     724      390042 :   NeedsNewLine = false;
     725             : 
     726      390042 :   outputNewLine();
     727             : 
     728             :   assert(StateStack.size() > 0);
     729      780084 :   unsigned Indent = StateStack.size() - 1;
     730             :   bool OutputDash = false;
     731             : 
     732      390042 :   if (StateStack.back() == inSeq) {
     733             :     OutputDash = true;
     734      304029 :   } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
     735      255382 :              (StateStack.back() == inFlowSeq) ||
     736      379965 :              (StateStack.back() == inFlowMapFirstKey)) &&
     737      148528 :              (StateStack[StateStack.size() - 2] == inSeq)) {
     738       60439 :     --Indent;
     739             :     OutputDash = true;
     740             :   }
     741             : 
     742     1169362 :   for (unsigned i = 0; i < Indent; ++i) {
     743      779320 :     output("  ");
     744             :   }
     745      390042 :   if (OutputDash) {
     746       70516 :     output("- ");
     747             :   }
     748             : 
     749             : }
     750             : 
     751      354288 : void Output::paddedKey(StringRef key) {
     752      354288 :   output(key);
     753      354288 :   output(":");
     754             :   const char *spaces = "                ";
     755      354288 :   if (key.size() < strlen(spaces))
     756      571762 :     output(&spaces[key.size()]);
     757             :   else
     758       68407 :     output(" ");
     759      354288 : }
     760             : 
     761       84611 : void Output::flowKey(StringRef Key) {
     762       84611 :   if (StateStack.back() == inFlowMapOtherKey)
     763       58814 :     output(", ");
     764       84611 :   if (WrapColumn && Column > WrapColumn) {
     765        2059 :     output("\n");
     766       11404 :     for (int I = 0; I < ColumnAtMapFlowStart; ++I)
     767        9345 :       output(" ");
     768        2059 :     Column = ColumnAtMapFlowStart;
     769        2059 :     output("  ");
     770             :   }
     771       84611 :   output(Key);
     772       84611 :   output(": ");
     773       84611 : }
     774             : 
     775             : //===----------------------------------------------------------------------===//
     776             : //  traits for built-in types
     777             : //===----------------------------------------------------------------------===//
     778             : 
     779       72464 : void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
     780      134559 :   Out << (Val ? "true" : "false");
     781       72464 : }
     782             : 
     783       18105 : StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
     784             :   if (Scalar.equals("true")) {
     785        7086 :     Val = true;
     786        7086 :     return StringRef();
     787             :   } else if (Scalar.equals("false")) {
     788       11019 :     Val = false;
     789       11019 :     return StringRef();
     790             :   }
     791           0 :   return "invalid boolean";
     792             : }
     793             : 
     794       27232 : void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
     795             :                                      raw_ostream &Out) {
     796       27232 :   Out << Val;
     797       27232 : }
     798             : 
     799       13947 : StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
     800             :                                          StringRef &Val) {
     801       13947 :   Val = Scalar;
     802       13947 :   return StringRef();
     803             : }
     804             : 
     805       23703 : void ScalarTraits<std::string>::output(const std::string &Val, void *,
     806             :                                      raw_ostream &Out) {
     807             :   Out << Val;
     808       23703 : }
     809             : 
     810        8375 : StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
     811             :                                          std::string &Val) {
     812       16750 :   Val = Scalar.str();
     813        8375 :   return StringRef();
     814             : }
     815             : 
     816        7402 : void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
     817             :                                    raw_ostream &Out) {
     818             :   // use temp uin32_t because ostream thinks uint8_t is a character
     819        7402 :   uint32_t Num = Val;
     820             :   Out << Num;
     821        7402 : }
     822             : 
     823        1303 : StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
     824             :   unsigned long long n;
     825        1303 :   if (getAsUnsignedInteger(Scalar, 0, n))
     826           0 :     return "invalid number";
     827        1303 :   if (n > 0xFF)
     828           1 :     return "out of range number";
     829        1302 :   Val = n;
     830        1302 :   return StringRef();
     831             : }
     832             : 
     833       11848 : void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
     834             :                                     raw_ostream &Out) {
     835       11848 :   Out << Val;
     836       11848 : }
     837             : 
     838        5451 : StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
     839             :                                         uint16_t &Val) {
     840             :   unsigned long long n;
     841        5451 :   if (getAsUnsignedInteger(Scalar, 0, n))
     842           0 :     return "invalid number";
     843        5451 :   if (n > 0xFFFF)
     844           1 :     return "out of range number";
     845        5450 :   Val = n;
     846        5450 :   return StringRef();
     847             : }
     848             : 
     849      109929 : void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
     850             :                                     raw_ostream &Out) {
     851      109929 :   Out << Val;
     852      109929 : }
     853             : 
     854       36469 : StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
     855             :                                         uint32_t &Val) {
     856             :   unsigned long long n;
     857       36469 :   if (getAsUnsignedInteger(Scalar, 0, n))
     858           1 :     return "invalid number";
     859       36468 :   if (n > 0xFFFFFFFFUL)
     860           1 :     return "out of range number";
     861       36467 :   Val = n;
     862       36467 :   return StringRef();
     863             : }
     864             : 
     865       12775 : void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
     866             :                                     raw_ostream &Out) {
     867       12775 :   Out << Val;
     868       12775 : }
     869             : 
     870        3773 : StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
     871             :                                         uint64_t &Val) {
     872             :   unsigned long long N;
     873        3773 :   if (getAsUnsignedInteger(Scalar, 0, N))
     874           1 :     return "invalid number";
     875        3772 :   Val = N;
     876        3772 :   return StringRef();
     877             : }
     878             : 
     879           1 : void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
     880             :   // use temp in32_t because ostream thinks int8_t is a character
     881           1 :   int32_t Num = Val;
     882             :   Out << Num;
     883           1 : }
     884             : 
     885          10 : StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
     886             :   long long N;
     887          10 :   if (getAsSignedInteger(Scalar, 0, N))
     888           0 :     return "invalid number";
     889          10 :   if ((N > 127) || (N < -128))
     890           2 :     return "out of range number";
     891           8 :   Val = N;
     892           8 :   return StringRef();
     893             : }
     894             : 
     895           2 : void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
     896             :                                    raw_ostream &Out) {
     897           2 :   Out << Val;
     898           2 : }
     899             : 
     900          12 : StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
     901             :   long long N;
     902          12 :   if (getAsSignedInteger(Scalar, 0, N))
     903           0 :     return "invalid number";
     904          12 :   if ((N > INT16_MAX) || (N < INT16_MIN))
     905           2 :     return "out of range number";
     906          10 :   Val = N;
     907          10 :   return StringRef();
     908             : }
     909             : 
     910        5714 : void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
     911             :                                    raw_ostream &Out) {
     912        5714 :   Out << Val;
     913        5714 : }
     914             : 
     915        3983 : StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
     916             :   long long N;
     917        3983 :   if (getAsSignedInteger(Scalar, 0, N))
     918           0 :     return "invalid number";
     919        3983 :   if ((N > INT32_MAX) || (N < INT32_MIN))
     920           2 :     return "out of range number";
     921        3981 :   Val = N;
     922        3981 :   return StringRef();
     923             : }
     924             : 
     925        1238 : void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
     926             :                                    raw_ostream &Out) {
     927        1238 :   Out << Val;
     928        1238 : }
     929             : 
     930         518 : StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
     931             :   long long N;
     932         518 :   if (getAsSignedInteger(Scalar, 0, N))
     933           2 :     return "invalid number";
     934         516 :   Val = N;
     935         516 :   return StringRef();
     936             : }
     937             : 
     938           8 : void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
     939          16 :   Out << format("%g", Val);
     940           8 : }
     941             : 
     942          23 : StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
     943          23 :   if (to_float(Scalar, Val))
     944          22 :     return StringRef();
     945           1 :   return "invalid floating point number";
     946             : }
     947             : 
     948           2 : void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
     949           4 :   Out << format("%g", Val);
     950           2 : }
     951             : 
     952           8 : StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
     953           8 :   if (to_float(Scalar, Val))
     954           7 :     return StringRef();
     955           1 :   return "invalid floating point number";
     956             : }
     957             : 
     958         399 : void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
     959         399 :   uint8_t Num = Val;
     960         399 :   Out << format("0x%02X", Num);
     961         399 : }
     962             : 
     963        6248 : StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
     964             :   unsigned long long n;
     965        6248 :   if (getAsUnsignedInteger(Scalar, 0, n))
     966           0 :     return "invalid hex8 number";
     967        6248 :   if (n > 0xFF)
     968           1 :     return "out of range hex8 number";
     969        6247 :   Val = n;
     970        6247 :   return StringRef();
     971             : }
     972             : 
     973          12 : void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
     974          12 :   uint16_t Num = Val;
     975          12 :   Out << format("0x%04X", Num);
     976          12 : }
     977             : 
     978          41 : StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
     979             :   unsigned long long n;
     980          41 :   if (getAsUnsignedInteger(Scalar, 0, n))
     981           0 :     return "invalid hex16 number";
     982          41 :   if (n > 0xFFFF)
     983           1 :     return "out of range hex16 number";
     984          40 :   Val = n;
     985          40 :   return StringRef();
     986             : }
     987             : 
     988        2587 : void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
     989        2587 :   uint32_t Num = Val;
     990        2587 :   Out << format("0x%08X", Num);
     991        2587 : }
     992             : 
     993        2399 : StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
     994             :   unsigned long long n;
     995        2399 :   if (getAsUnsignedInteger(Scalar, 0, n))
     996           0 :     return "invalid hex32 number";
     997        2399 :   if (n > 0xFFFFFFFFUL)
     998           1 :     return "out of range hex32 number";
     999        2398 :   Val = n;
    1000        2398 :   return StringRef();
    1001             : }
    1002             : 
    1003         934 : void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
    1004         934 :   uint64_t Num = Val;
    1005         934 :   Out << format("0x%016llX", Num);
    1006         934 : }
    1007             : 
    1008        3896 : StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
    1009             :   unsigned long long Num;
    1010        3896 :   if (getAsUnsignedInteger(Scalar, 0, Num))
    1011           1 :     return "invalid hex64 number";
    1012        3895 :   Val = Num;
    1013        3895 :   return StringRef();
    1014             : }

Generated by: LCOV version 1.13