YAMLTraits.cpp revision 309124
1139749Simp//===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
2113584Ssimokawa//
3103285Sikob//                             The LLVM Linker
4103285Sikob//
5103285Sikob// This file is distributed under the University of Illinois Open Source
6103285Sikob// License. See LICENSE.TXT for details.
7103285Sikob//
8103285Sikob//===----------------------------------------------------------------------===//
9103285Sikob
10103285Sikob#include "llvm/Support/YAMLTraits.h"
11103285Sikob#include "llvm/ADT/SmallString.h"
12103285Sikob#include "llvm/ADT/Twine.h"
13103285Sikob#include "llvm/Support/Casting.h"
14103285Sikob#include "llvm/Support/Errc.h"
15103285Sikob#include "llvm/Support/ErrorHandling.h"
16103285Sikob#include "llvm/Support/Format.h"
17103285Sikob#include "llvm/Support/LineIterator.h"
18103285Sikob#include "llvm/Support/YAMLParser.h"
19103285Sikob#include "llvm/Support/raw_ostream.h"
20103285Sikob#include <cctype>
21103285Sikob#include <cstring>
22103285Sikobusing namespace llvm;
23103285Sikobusing namespace yaml;
24103285Sikob
25103285Sikob//===----------------------------------------------------------------------===//
26103285Sikob//  IO
27103285Sikob//===----------------------------------------------------------------------===//
28103285Sikob
29103285SikobIO::IO(void *Context) : Ctxt(Context) {
30103285Sikob}
31103285Sikob
32103285SikobIO::~IO() {
33103285Sikob}
34103285Sikob
35103285Sikobvoid *IO::getContext() {
36103285Sikob  return Ctxt;
37103285Sikob}
38103285Sikob
39103285Sikobvoid IO::setContext(void *Context) {
40103285Sikob  Ctxt = Context;
41103285Sikob}
42103285Sikob
43129879Sphk//===----------------------------------------------------------------------===//
44103285Sikob//  Input
45103285Sikob//===----------------------------------------------------------------------===//
46103285Sikob
47169806SsimokawaInput::Input(StringRef InputContent,
48103285Sikob             void *Ctxt,
49170374Ssimokawa             SourceMgr::DiagHandlerTy DiagHandler,
50170374Ssimokawa             void *DiagHandlerCtxt)
51127468Ssimokawa  : IO(Ctxt),
52117067Ssimokawa    Strm(new Stream(InputContent, SrcMgr)),
53117067Ssimokawa    CurrentNode(nullptr) {
54103285Sikob  if (DiagHandler)
55103285Sikob    SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
56113584Ssimokawa  DocIterator = Strm->begin();
57103285Sikob}
58127468Ssimokawa
59127468SsimokawaInput::~Input() {
60127468Ssimokawa}
61127468Ssimokawa
62127468Ssimokawastd::error_code Input::error() { return EC; }
63127468Ssimokawa
64127468Ssimokawa// Pin the vtables to this file.
65103285Sikobvoid Input::HNode::anchor() {}
66103285Sikobvoid Input::EmptyHNode::anchor() {}
67110072Ssimokawavoid Input::ScalarHNode::anchor() {}
68103285Sikobvoid Input::MapHNode::anchor() {}
69103285Sikobvoid Input::SequenceHNode::anchor() {}
70127468Ssimokawa
71103285Sikobbool Input::outputting() {
72116376Ssimokawa  return false;
73116376Ssimokawa}
74116376Ssimokawa
75116376Ssimokawabool Input::setCurrentDocument() {
76116376Ssimokawa  if (DocIterator != Strm->end()) {
77116376Ssimokawa    Node *N = DocIterator->getRoot();
78116376Ssimokawa    if (!N) {
79120850Ssimokawa      assert(Strm->failed() && "Root is NULL iff parsing failed");
80103285Sikob      EC = make_error_code(errc::invalid_argument);
81108281Ssimokawa      return false;
82109736Ssimokawa    }
83109736Ssimokawa
84109736Ssimokawa    if (isa<NullNode>(N)) {
85120850Ssimokawa      // Empty files are allowed and ignored
86120850Ssimokawa      ++DocIterator;
87103285Sikob      return setCurrentDocument();
88110195Ssimokawa    }
89110269Ssimokawa    TopNode = this->createHNodes(N);
90110195Ssimokawa    CurrentNode = TopNode.get();
91103285Sikob    return true;
92103285Sikob  }
93103285Sikob  return false;
94103285Sikob}
95125238Ssimokawa
96125238Ssimokawabool Input::nextDocument() {
97124169Ssimokawa  return ++DocIterator != Strm->end();
98124169Ssimokawa}
99124169Ssimokawa
100170374Ssimokawaconst Node *Input::getCurrentNode() const {
101103285Sikob  return CurrentNode ? CurrentNode->_node : nullptr;
102124169Ssimokawa}
103103285Sikob
104124169Ssimokawabool Input::mapTag(StringRef Tag, bool Default) {
105124169Ssimokawa  std::string foundTag = CurrentNode->_node->getVerbatimTag();
106124169Ssimokawa  if (foundTag.empty()) {
107124169Ssimokawa    // If no tag found and 'Tag' is the default, say it was found.
108124169Ssimokawa    return Default;
109124169Ssimokawa  }
110124169Ssimokawa  // Return true iff found tag matches supplied tag.
111169806Ssimokawa  return Tag.equals(foundTag);
112106543Ssimokawa}
113124169Ssimokawa
114106543Ssimokawavoid Input::beginMapping() {
115124169Ssimokawa  if (EC)
116170374Ssimokawa    return;
117103285Sikob  // CurrentNode can be null if the document is empty.
118103285Sikob  MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
119103285Sikob  if (MN) {
120125238Ssimokawa    MN->ValidKeys.clear();
121125238Ssimokawa  }
122103285Sikob}
123103285Sikob
124108642Ssimokawabool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
125116978Ssimokawa                         void *&SaveInfo) {
126103285Sikob  UseDefault = false;
127103285Sikob  if (EC)
128103285Sikob    return false;
129103285Sikob
130103285Sikob  // CurrentNode is null for empty documents, which is an error in case required
131103285Sikob  // nodes are present.
132103285Sikob  if (!CurrentNode) {
133103285Sikob    if (Required)
134124251Ssimokawa      EC = make_error_code(errc::invalid_argument);
135124251Ssimokawa    return false;
136124251Ssimokawa  }
137124251Ssimokawa
138103285Sikob  MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
139124251Ssimokawa  if (!MN) {
140124251Ssimokawa    setError(CurrentNode, "not a mapping");
141124251Ssimokawa    return false;
142124251Ssimokawa  }
143124251Ssimokawa  MN->ValidKeys.push_back(Key);
144124251Ssimokawa  HNode *Value = MN->Mapping[Key].get();
145124251Ssimokawa  if (!Value) {
146114909Ssimokawa    if (Required)
147114909Ssimokawa      setError(CurrentNode, Twine("missing required key '") + Key + "'");
148114909Ssimokawa    else
149114909Ssimokawa      UseDefault = true;
150106813Ssimokawa    return false;
151103285Sikob  }
152103285Sikob  SaveInfo = CurrentNode;
153103285Sikob  CurrentNode = Value;
154103285Sikob  return true;
155103285Sikob}
156103285Sikob
157103285Sikobvoid Input::postflightKey(void *saveInfo) {
158110072Ssimokawa  CurrentNode = reinterpret_cast<HNode *>(saveInfo);
159103285Sikob}
160106810Ssimokawa
161110072Ssimokawavoid Input::endMapping() {
162103285Sikob  if (EC)
163103285Sikob    return;
164110072Ssimokawa  // CurrentNode can be null if the document is empty.
165110072Ssimokawa  MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
166110072Ssimokawa  if (!MN)
167110193Ssimokawa    return;
168120660Ssimokawa  for (const auto &NN : MN->Mapping) {
169103285Sikob    if (!MN->isValidKey(NN.first())) {
170110072Ssimokawa      setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
171110072Ssimokawa      break;
172106810Ssimokawa    }
173103285Sikob  }
174106813Ssimokawa}
175103285Sikob
176110072Ssimokawavoid Input::beginFlowMapping() { beginMapping(); }
177110072Ssimokawa
178110072Ssimokawavoid Input::endFlowMapping() { endMapping(); }
179110582Ssimokawa
180110072Ssimokawaunsigned Input::beginSequence() {
181110072Ssimokawa  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
182110072Ssimokawa    return SQ->Entries.size();
183110072Ssimokawa  if (isa<EmptyHNode>(CurrentNode))
184110072Ssimokawa    return 0;
185170374Ssimokawa  // Treat case where there's a scalar "null" value as an empty sequence.
186110193Ssimokawa  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
187110582Ssimokawa    if (isNull(SN->value()))
188110072Ssimokawa      return 0;
189170374Ssimokawa  }
190110072Ssimokawa  // Any other type of HNode is an error.
191110072Ssimokawa  setError(CurrentNode, "not a sequence");
192110072Ssimokawa  return 0;
193110072Ssimokawa}
194110072Ssimokawa
195110072Ssimokawavoid Input::endSequence() {
196110072Ssimokawa}
197110072Ssimokawa
198103285Sikobbool Input::preflightElement(unsigned Index, void *&SaveInfo) {
199103285Sikob  if (EC)
200103285Sikob    return false;
201103285Sikob  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
202103285Sikob    SaveInfo = CurrentNode;
203103285Sikob    CurrentNode = SQ->Entries[Index].get();
204103285Sikob    return true;
205170374Ssimokawa  }
206103285Sikob  return false;
207103285Sikob}
208103285Sikob
209103285Sikobvoid Input::postflightElement(void *SaveInfo) {
210103285Sikob  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
211167632Ssimokawa}
212167632Ssimokawa
213103285Sikobunsigned Input::beginFlowSequence() { return beginSequence(); }
214103285Sikob
215120660Ssimokawabool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
216103285Sikob  if (EC)
217103285Sikob    return false;
218103285Sikob  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
219103285Sikob    SaveInfo = CurrentNode;
220124251Ssimokawa    CurrentNode = SQ->Entries[index].get();
221103285Sikob    return true;
222103285Sikob  }
223170425Ssimokawa  return false;
224170425Ssimokawa}
225170425Ssimokawa
226170425Ssimokawavoid Input::postflightFlowElement(void *SaveInfo) {
227170425Ssimokawa  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
228170425Ssimokawa}
229170425Ssimokawa
230170425Ssimokawavoid Input::endFlowSequence() {
231170425Ssimokawa}
232170425Ssimokawa
233170425Ssimokawavoid Input::beginEnumScalar() {
234103285Sikob  ScalarMatchFound = false;
235103285Sikob}
236103285Sikob
237103285Sikobbool Input::matchEnumScalar(const char *Str, bool) {
238103285Sikob  if (ScalarMatchFound)
239120660Ssimokawa    return false;
240120660Ssimokawa  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
241120660Ssimokawa    if (SN->value().equals(Str)) {
242120660Ssimokawa      ScalarMatchFound = true;
243103285Sikob      return true;
244120660Ssimokawa    }
245103285Sikob  }
246120660Ssimokawa  return false;
247120660Ssimokawa}
248120660Ssimokawa
249120660Ssimokawabool Input::matchEnumFallback() {
250124251Ssimokawa  if (ScalarMatchFound)
251124251Ssimokawa    return false;
252103285Sikob  ScalarMatchFound = true;
253103285Sikob  return true;
254106790Ssimokawa}
255103285Sikob
256103285Sikobvoid Input::endEnumScalar() {
257103285Sikob  if (!ScalarMatchFound) {
258103285Sikob    setError(CurrentNode, "unknown enumerated scalar");
259103285Sikob  }
260108655Ssimokawa}
261108655Ssimokawa
262170374Ssimokawabool Input::beginBitSetScalar(bool &DoClear) {
263103285Sikob  BitValuesUsed.clear();
264103285Sikob  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
265170374Ssimokawa    BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
266103285Sikob  } else {
267170374Ssimokawa    setError(CurrentNode, "expected sequence of bit values");
268130460Sdfr  }
269103285Sikob  DoClear = true;
270103285Sikob  return true;
271103285Sikob}
272103285Sikob
273103285Sikobbool Input::bitSetMatch(const char *Str, bool) {
274103285Sikob  if (EC)
275103285Sikob    return false;
276103285Sikob  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
277103285Sikob    unsigned Index = 0;
278103285Sikob    for (auto &N : SQ->Entries) {
279103285Sikob      if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
280103285Sikob        if (SN->value().equals(Str)) {
281103285Sikob          BitValuesUsed[Index] = true;
282170374Ssimokawa          return true;
283170374Ssimokawa        }
284170374Ssimokawa      } else {
285170374Ssimokawa        setError(CurrentNode, "unexpected scalar in sequence of bit values");
286170374Ssimokawa      }
287170374Ssimokawa      ++Index;
288170374Ssimokawa    }
289170374Ssimokawa  } else {
290103285Sikob    setError(CurrentNode, "expected sequence of bit values");
291103285Sikob  }
292103285Sikob  return false;
293103285Sikob}
294170374Ssimokawa
295170374Ssimokawavoid Input::endBitSetScalar() {
296170374Ssimokawa  if (EC)
297170374Ssimokawa    return;
298170374Ssimokawa  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
299170374Ssimokawa    assert(BitValuesUsed.size() == SQ->Entries.size());
300170374Ssimokawa    for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
301170374Ssimokawa      if (!BitValuesUsed[i]) {
302170374Ssimokawa        setError(SQ->Entries[i].get(), "unknown bit value");
303170374Ssimokawa        return;
304170374Ssimokawa      }
305170374Ssimokawa    }
306170374Ssimokawa  }
307170374Ssimokawa}
308103285Sikob
309103285Sikobvoid Input::scalarString(StringRef &S, bool) {
310103285Sikob  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
311106790Ssimokawa    S = SN->value();
312106790Ssimokawa  } else {
313106790Ssimokawa    setError(CurrentNode, "unexpected scalar");
314103285Sikob  }
315103285Sikob}
316170374Ssimokawa
317170374Ssimokawavoid Input::blockScalarString(StringRef &S) { scalarString(S, false); }
318170374Ssimokawa
319170374Ssimokawavoid Input::setError(HNode *hnode, const Twine &message) {
320103285Sikob  assert(hnode && "HNode must not be NULL");
321170374Ssimokawa  this->setError(hnode->_node, message);
322103285Sikob}
323170374Ssimokawa
324170374Ssimokawavoid Input::setError(Node *node, const Twine &message) {
325103285Sikob  Strm->printError(node, message);
326103285Sikob  EC = make_error_code(errc::invalid_argument);
327103285Sikob}
328103285Sikob
329103285Sikobstd::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
330103285Sikob  SmallString<128> StringStorage;
331106790Ssimokawa  if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
332125238Ssimokawa    StringRef KeyStr = SN->getValue(StringStorage);
333125238Ssimokawa    if (!StringStorage.empty()) {
334125238Ssimokawa      // Copy string to permanent storage
335125238Ssimokawa      KeyStr = StringStorage.str().copy(StringAllocator);
336125238Ssimokawa    }
337125238Ssimokawa    return llvm::make_unique<ScalarHNode>(N, KeyStr);
338103285Sikob  } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
339125238Ssimokawa    StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
340103285Sikob    return llvm::make_unique<ScalarHNode>(N, ValueCopy);
341108281Ssimokawa  } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
342125238Ssimokawa    auto SQHNode = llvm::make_unique<SequenceHNode>(N);
343103285Sikob    for (Node &SN : *SQ) {
344106790Ssimokawa      auto Entry = this->createHNodes(&SN);
345110577Ssimokawa      if (EC)
346170374Ssimokawa        break;
347110577Ssimokawa      SQHNode->Entries.push_back(std::move(Entry));
348170374Ssimokawa    }
349170374Ssimokawa    return std::move(SQHNode);
350110577Ssimokawa  } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
351110577Ssimokawa    auto mapHNode = llvm::make_unique<MapHNode>(N);
352170374Ssimokawa    for (KeyValueNode &KVN : *Map) {
353111040Ssimokawa      Node *KeyNode = KVN.getKey();
354110577Ssimokawa      ScalarNode *KeyScalar = dyn_cast<ScalarNode>(KeyNode);
355120660Ssimokawa      if (!KeyScalar) {
356120660Ssimokawa        setError(KeyNode, "Map key must be a scalar");
357110577Ssimokawa        break;
358110577Ssimokawa      }
359110577Ssimokawa      StringStorage.clear();
360170374Ssimokawa      StringRef KeyStr = KeyScalar->getValue(StringStorage);
361110577Ssimokawa      if (!StringStorage.empty()) {
362111040Ssimokawa        // Copy string to permanent storage
363171513Ssimokawa        KeyStr = StringStorage.str().copy(StringAllocator);
364110577Ssimokawa      }
365169119Ssimokawa      auto ValueHNode = this->createHNodes(KVN.getValue());
366170427Ssimokawa      if (EC)
367170427Ssimokawa        break;
368170427Ssimokawa      mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
369110577Ssimokawa    }
370110577Ssimokawa    return std::move(mapHNode);
371110577Ssimokawa  } else if (isa<NullNode>(N)) {
372110577Ssimokawa    return llvm::make_unique<EmptyHNode>(N);
373170374Ssimokawa  } else {
374170374Ssimokawa    setError(N, "unknown node kind");
375170374Ssimokawa    return nullptr;
376110577Ssimokawa  }
377170374Ssimokawa}
378170374Ssimokawa
379110577Ssimokawabool Input::MapHNode::isValidKey(StringRef Key) {
380110577Ssimokawa  for (const char *K : ValidKeys) {
381171513Ssimokawa    if (Key.equals(K))
382111040Ssimokawa      return true;
383170374Ssimokawa  }
384170374Ssimokawa  return false;
385170374Ssimokawa}
386170374Ssimokawa
387110577Ssimokawavoid Input::setError(const Twine &Message) {
388110577Ssimokawa  this->setError(CurrentNode, Message);
389170374Ssimokawa}
390110577Ssimokawa
391110577Ssimokawabool Input::canElideEmptySequence() {
392110577Ssimokawa  return false;
393110577Ssimokawa}
394170374Ssimokawa
395110577Ssimokawa//===----------------------------------------------------------------------===//
396110577Ssimokawa//  Output
397121463Ssimokawa//===----------------------------------------------------------------------===//
398121463Ssimokawa
399121463SsimokawaOutput::Output(raw_ostream &yout, void *context, int WrapColumn)
400121463Ssimokawa    : IO(context),
401121463Ssimokawa      Out(yout),
402121463Ssimokawa      WrapColumn(WrapColumn),
403170374Ssimokawa      Column(0),
404170374Ssimokawa      ColumnAtFlowStart(0),
405170374Ssimokawa      ColumnAtMapFlowStart(0),
406170374Ssimokawa      NeedBitValueComma(false),
407121463Ssimokawa      NeedFlowSequenceComma(false),
408170374Ssimokawa      EnumerationMatchFound(false),
409110577Ssimokawa      NeedsNewLine(false) {
410110577Ssimokawa}
411110577Ssimokawa
412103285SikobOutput::~Output() {
413103285Sikob}
414103285Sikob
415103285Sikobbool Output::outputting() {
416118455Ssimokawa  return true;
417103285Sikob}
418118455Ssimokawa
419103285Sikobvoid Output::beginMapping() {
420103285Sikob  StateStack.push_back(inMapFirstKey);
421103285Sikob  NeedsNewLine = true;
422103285Sikob}
423103285Sikob
424103285Sikobbool Output::mapTag(StringRef Tag, bool Use) {
425116978Ssimokawa  if (Use) {
426103285Sikob    // If this tag is being written inside a sequence we should write the start
427118455Ssimokawa    // of the sequence before writing the tag, otherwise the tag won't be
428118455Ssimokawa    // attached to the element in the sequence, but rather the sequence itself.
429103285Sikob    bool SequenceElement =
430118455Ssimokawa        StateStack.size() > 1 && (StateStack[StateStack.size() - 2] == inSeq ||
431118455Ssimokawa          StateStack[StateStack.size() - 2] == inFlowSeq);
432170374Ssimokawa    if (SequenceElement && StateStack.back() == inMapFirstKey) {
433171513Ssimokawa      this->newLineCheck();
434170374Ssimokawa    } else {
435170374Ssimokawa      this->output(" ");
436170374Ssimokawa    }
437170374Ssimokawa    this->output(Tag);
438108853Ssimokawa    if (SequenceElement) {
439110577Ssimokawa      // If we're writing the tag during the first element of a map, the tag
440110577Ssimokawa      // takes the place of the first element in the sequence.
441110193Ssimokawa      if (StateStack.back() == inMapFirstKey) {
442169806Ssimokawa        StateStack.pop_back();
443172836Sjulian        StateStack.push_back(inMapOtherKey);
444169806Ssimokawa      }
445169806Ssimokawa      // Tags inside maps in sequences should act as keys in the map from a
446103285Sikob      // formatting perspective, so we always want a newline in a sequence.
447103285Sikob      NeedsNewLine = true;
448103285Sikob    }
449103285Sikob  }
450103285Sikob  return Use;
451103285Sikob}
452103285Sikob
453169117Ssimokawavoid Output::endMapping() {
454103285Sikob  StateStack.pop_back();
455103285Sikob}
456103285Sikob
457103285Sikobbool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
458103285Sikob                          bool &UseDefault, void *&) {
459103285Sikob  UseDefault = false;
460103285Sikob  if (Required || !SameAsDefault) {
461103285Sikob    auto State = StateStack.back();
462103285Sikob    if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
463103285Sikob      flowKey(Key);
464103285Sikob    } else {
465103285Sikob      this->newLineCheck();
466103285Sikob      this->paddedKey(Key);
467103285Sikob    }
468103285Sikob    return true;
469103285Sikob  }
470103285Sikob  return false;
471103285Sikob}
472103285Sikob
473103285Sikobvoid Output::postflightKey(void *) {
474103285Sikob  if (StateStack.back() == inMapFirstKey) {
475103285Sikob    StateStack.pop_back();
476103285Sikob    StateStack.push_back(inMapOtherKey);
477106790Ssimokawa  } else if (StateStack.back() == inFlowMapFirstKey) {
478116978Ssimokawa    StateStack.pop_back();
479116978Ssimokawa    StateStack.push_back(inFlowMapOtherKey);
480116978Ssimokawa  }
481116978Ssimokawa}
482116978Ssimokawa
483116978Ssimokawavoid Output::beginFlowMapping() {
484116978Ssimokawa  StateStack.push_back(inFlowMapFirstKey);
485116978Ssimokawa  this->newLineCheck();
486116978Ssimokawa  ColumnAtMapFlowStart = Column;
487116978Ssimokawa  output("{ ");
488116978Ssimokawa}
489116978Ssimokawa
490116978Ssimokawavoid Output::endFlowMapping() {
491103285Sikob  StateStack.pop_back();
492103285Sikob  this->outputUpToEndOfLine(" }");
493103285Sikob}
494103285Sikob
495118455Ssimokawavoid Output::beginDocuments() {
496103285Sikob  this->outputUpToEndOfLine("---");
497103285Sikob}
498169806Ssimokawa
499111078Ssimokawabool Output::preflightDocument(unsigned index) {
500118455Ssimokawa  if (index > 0)
501103285Sikob    this->outputUpToEndOfLine("\n---");
502103285Sikob  return true;
503169806Ssimokawa}
504170374Ssimokawa
505169806Ssimokawavoid Output::postflightDocument() {
506170374Ssimokawa}
507170374Ssimokawa
508170374Ssimokawavoid Output::endDocuments() {
509170374Ssimokawa  output("\n...\n");
510169806Ssimokawa}
511178915Ssimokawa
512178915Ssimokawaunsigned Output::beginSequence() {
513178915Ssimokawa  StateStack.push_back(inSeq);
514118455Ssimokawa  NeedsNewLine = true;
515118455Ssimokawa  return 0;
516106790Ssimokawa}
517118455Ssimokawa
518118455Ssimokawavoid Output::endSequence() {
519111078Ssimokawa  StateStack.pop_back();
520169806Ssimokawa}
521169806Ssimokawa
522169806Ssimokawabool Output::preflightElement(unsigned, void *&) {
523111078Ssimokawa  return true;
524178915Ssimokawa}
525169806Ssimokawa
526111078Ssimokawavoid Output::postflightElement(void *) {
527111078Ssimokawa}
528111078Ssimokawa
529111078Ssimokawaunsigned Output::beginFlowSequence() {
530169806Ssimokawa  StateStack.push_back(inFlowSeq);
531169806Ssimokawa  this->newLineCheck();
532169806Ssimokawa  ColumnAtFlowStart = Column;
533169806Ssimokawa  output("[ ");
534171513Ssimokawa  NeedFlowSequenceComma = false;
535170374Ssimokawa  return 0;
536103285Sikob}
537103285Sikob
538103285Sikobvoid Output::endFlowSequence() {
539103285Sikob  StateStack.pop_back();
540103285Sikob  this->outputUpToEndOfLine(" ]");
541103285Sikob}
542103285Sikob
543103285Sikobbool Output::preflightFlowElement(unsigned, void *&) {
544103285Sikob  if (NeedFlowSequenceComma)
545106790Ssimokawa    output(", ");
546110577Ssimokawa  if (WrapColumn && Column > WrapColumn) {
547110577Ssimokawa    output("\n");
548110798Ssimokawa    for (int i = 0; i < ColumnAtFlowStart; ++i)
549110577Ssimokawa      output(" ");
550110577Ssimokawa    Column = ColumnAtFlowStart;
551110577Ssimokawa    output("  ");
552110577Ssimokawa  }
553110577Ssimokawa  return true;
554170374Ssimokawa}
555111942Ssimokawa
556170374Ssimokawavoid Output::postflightFlowElement(void *) {
557110577Ssimokawa  NeedFlowSequenceComma = true;
558170374Ssimokawa}
559113584Ssimokawa
560110577Ssimokawavoid Output::beginEnumScalar() {
561110577Ssimokawa  EnumerationMatchFound = false;
562110577Ssimokawa}
563110798Ssimokawa
564110798Ssimokawabool Output::matchEnumScalar(const char *Str, bool Match) {
565110798Ssimokawa  if (Match && !EnumerationMatchFound) {
566170374Ssimokawa    this->newLineCheck();
567170374Ssimokawa    this->outputUpToEndOfLine(Str);
568110798Ssimokawa    EnumerationMatchFound = true;
569110798Ssimokawa  }
570170374Ssimokawa  return false;
571170374Ssimokawa}
572170374Ssimokawa
573110798Ssimokawabool Output::matchEnumFallback() {
574110798Ssimokawa  if (EnumerationMatchFound)
575110798Ssimokawa    return false;
576110798Ssimokawa  EnumerationMatchFound = true;
577171513Ssimokawa  return true;
578170374Ssimokawa}
579171513Ssimokawa
580170374Ssimokawavoid Output::endEnumScalar() {
581170374Ssimokawa  if (!EnumerationMatchFound)
582170374Ssimokawa    llvm_unreachable("bad runtime enum value");
583170374Ssimokawa}
584170374Ssimokawa
585170374Ssimokawabool Output::beginBitSetScalar(bool &DoClear) {
586170374Ssimokawa  this->newLineCheck();
587170374Ssimokawa  output("[ ");
588171513Ssimokawa  NeedBitValueComma = false;
589170374Ssimokawa  DoClear = false;
590170374Ssimokawa  return true;
591170374Ssimokawa}
592110798Ssimokawa
593110798Ssimokawabool Output::bitSetMatch(const char *Str, bool Matches) {
594116376Ssimokawa  if (Matches) {
595116376Ssimokawa    if (NeedBitValueComma)
596103285Sikob      output(", ");
597103285Sikob    this->output(Str);
598103285Sikob    NeedBitValueComma = true;
599103285Sikob  }
600103285Sikob  return false;
601103285Sikob}
602103285Sikob
603103285Sikobvoid Output::endBitSetScalar() {
604103285Sikob  this->outputUpToEndOfLine(" ]");
605103285Sikob}
606103285Sikob
607103285Sikobvoid Output::scalarString(StringRef &S, bool MustQuote) {
608103285Sikob  this->newLineCheck();
609103285Sikob  if (S.empty()) {
610103285Sikob    // Print '' for the empty string because leaving the field empty is not
611103285Sikob    // allowed.
612103285Sikob    this->outputUpToEndOfLine("''");
613103285Sikob    return;
614103285Sikob  }
615103285Sikob  if (!MustQuote) {
616103285Sikob    // Only quote if we must.
617103285Sikob    this->outputUpToEndOfLine(S);
618103285Sikob    return;
619103285Sikob  }
620103285Sikob  unsigned i = 0;
621103285Sikob  unsigned j = 0;
622103285Sikob  unsigned End = S.size();
623103285Sikob  output("'"); // Starting single quote.
624103285Sikob  const char *Base = S.data();
625103285Sikob  while (j < End) {
626103285Sikob    // Escape a single quote by doubling it.
627103285Sikob    if (S[j] == '\'') {
628103285Sikob      output(StringRef(&Base[i], j - i + 1));
629103285Sikob      output("'");
630103285Sikob      i = j + 1;
631103285Sikob    }
632103285Sikob    ++j;
633103285Sikob  }
634103285Sikob  output(StringRef(&Base[i], j - i));
635103285Sikob  this->outputUpToEndOfLine("'"); // Ending single quote.
636103285Sikob}
637116376Ssimokawa
638113584Ssimokawavoid Output::blockScalarString(StringRef &S) {
639116376Ssimokawa  if (!StateStack.empty())
640116376Ssimokawa    newLineCheck();
641116376Ssimokawa  output(" |");
642116376Ssimokawa  outputNewLine();
643116376Ssimokawa
644116376Ssimokawa  unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
645116376Ssimokawa
646116376Ssimokawa  auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
647116376Ssimokawa  for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
648116376Ssimokawa    for (unsigned I = 0; I < Indent; ++I) {
649116376Ssimokawa      output("  ");
650116376Ssimokawa    }
651116376Ssimokawa    output(*Lines);
652116376Ssimokawa    outputNewLine();
653116376Ssimokawa  }
654116376Ssimokawa}
655116376Ssimokawa
656116376Ssimokawavoid Output::setError(const Twine &message) {
657116376Ssimokawa}
658116376Ssimokawa
659116376Ssimokawabool Output::canElideEmptySequence() {
660116376Ssimokawa  // Normally, with an optional key/value where the value is an empty sequence,
661116376Ssimokawa  // the whole key/value can be not written.  But, that produces wrong yaml
662116376Ssimokawa  // if the key/value is the only thing in the map and the map is used in
663116376Ssimokawa  // a sequence.  This detects if the this sequence is the first key/value
664116376Ssimokawa  // in map that itself is embedded in a sequnce.
665117350Ssimokawa  if (StateStack.size() < 2)
666116376Ssimokawa    return true;
667116376Ssimokawa  if (StateStack.back() != inMapFirstKey)
668116376Ssimokawa    return true;
669116376Ssimokawa  return (StateStack[StateStack.size()-2] != inSeq);
670116376Ssimokawa}
671116376Ssimokawa
672116376Ssimokawavoid Output::output(StringRef s) {
673116376Ssimokawa  Column += s.size();
674116376Ssimokawa  Out << s;
675116376Ssimokawa}
676116376Ssimokawa
677116376Ssimokawavoid Output::outputUpToEndOfLine(StringRef s) {
678116376Ssimokawa  this->output(s);
679116376Ssimokawa  if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
680116376Ssimokawa                             StateStack.back() != inFlowMapFirstKey &&
681116376Ssimokawa                             StateStack.back() != inFlowMapOtherKey))
682116376Ssimokawa    NeedsNewLine = true;
683116376Ssimokawa}
684116376Ssimokawa
685116376Ssimokawavoid Output::outputNewLine() {
686116376Ssimokawa  Out << "\n";
687116376Ssimokawa  Column = 0;
688116376Ssimokawa}
689116376Ssimokawa
690116376Ssimokawa// if seq at top, indent as if map, then add "- "
691116376Ssimokawa// if seq in middle, use "- " if firstKey, else use "  "
692116376Ssimokawa//
693116376Ssimokawa
694116376Ssimokawavoid Output::newLineCheck() {
695116376Ssimokawa  if (!NeedsNewLine)
696116376Ssimokawa    return;
697116376Ssimokawa  NeedsNewLine = false;
698127468Ssimokawa
699127468Ssimokawa  this->outputNewLine();
700127468Ssimokawa
701127468Ssimokawa  assert(StateStack.size() > 0);
702116376Ssimokawa  unsigned Indent = StateStack.size() - 1;
703116376Ssimokawa  bool OutputDash = false;
704127468Ssimokawa
705116376Ssimokawa  if (StateStack.back() == inSeq) {
706116376Ssimokawa    OutputDash = true;
707116376Ssimokawa  } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
708116376Ssimokawa             (StateStack.back() == inFlowSeq) ||
709116376Ssimokawa             (StateStack.back() == inFlowMapFirstKey)) &&
710116376Ssimokawa             (StateStack[StateStack.size() - 2] == inSeq)) {
711116376Ssimokawa    --Indent;
712169117Ssimokawa    OutputDash = true;
713116376Ssimokawa  }
714116376Ssimokawa
715117350Ssimokawa  for (unsigned i = 0; i < Indent; ++i) {
716116376Ssimokawa    output("  ");
717117350Ssimokawa  }
718116376Ssimokawa  if (OutputDash) {
719116376Ssimokawa    output("- ");
720116376Ssimokawa  }
721116376Ssimokawa
722116376Ssimokawa}
723116376Ssimokawa
724116376Ssimokawavoid Output::paddedKey(StringRef key) {
725116376Ssimokawa  output(key);
726116376Ssimokawa  output(":");
727169117Ssimokawa  const char *spaces = "                ";
728116376Ssimokawa  if (key.size() < strlen(spaces))
729116376Ssimokawa    output(&spaces[key.size()]);
730116376Ssimokawa  else
731113584Ssimokawa    output(" ");
732113584Ssimokawa}
733113584Ssimokawa
734113584Ssimokawavoid Output::flowKey(StringRef Key) {
735113584Ssimokawa  if (StateStack.back() == inFlowMapOtherKey)
736113584Ssimokawa    output(", ");
737113584Ssimokawa  if (WrapColumn && Column > WrapColumn) {
738113584Ssimokawa    output("\n");
739113584Ssimokawa    for (int I = 0; I < ColumnAtMapFlowStart; ++I)
740116376Ssimokawa      output(" ");
741117350Ssimokawa    Column = ColumnAtMapFlowStart;
742117350Ssimokawa    output("  ");
743129585Sdfr  }
744117350Ssimokawa  output(Key);
745117350Ssimokawa  output(": ");
746117350Ssimokawa}
747117350Ssimokawa
748117350Ssimokawa//===----------------------------------------------------------------------===//
749117350Ssimokawa//  traits for built-in types
750129585Sdfr//===----------------------------------------------------------------------===//
751117350Ssimokawa
752117350Ssimokawavoid ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
753117350Ssimokawa  Out << (Val ? "true" : "false");
754103285Sikob}
755106790Ssimokawa
756103285SikobStringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
757106790Ssimokawa  if (Scalar.equals("true")) {
758103285Sikob    Val = true;
759103285Sikob    return StringRef();
760106543Ssimokawa  } else if (Scalar.equals("false")) {
761103285Sikob    Val = false;
762103285Sikob    return StringRef();
763106543Ssimokawa  }
764103285Sikob  return "invalid boolean";
765103285Sikob}
766103285Sikob
767103285Sikobvoid ScalarTraits<StringRef>::output(const StringRef &Val, void *,
768103285Sikob                                     raw_ostream &Out) {
769103285Sikob  Out << Val;
770103285Sikob}
771103285Sikob
772103285SikobStringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
773103285Sikob                                         StringRef &Val) {
774103285Sikob  Val = Scalar;
775113584Ssimokawa  return StringRef();
776113584Ssimokawa}
777113584Ssimokawa
778113584Ssimokawavoid ScalarTraits<std::string>::output(const std::string &Val, void *,
779103285Sikob                                     raw_ostream &Out) {
780103285Sikob  Out << Val;
781103285Sikob}
782103285Sikob
783103285SikobStringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
784103285Sikob                                         std::string &Val) {
785103285Sikob  Val = Scalar.str();
786103285Sikob  return StringRef();
787103285Sikob}
788103285Sikob
789103285Sikobvoid ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
790103285Sikob                                   raw_ostream &Out) {
791103285Sikob  // use temp uin32_t because ostream thinks uint8_t is a character
792103285Sikob  uint32_t Num = Val;
793103285Sikob  Out << Num;
794103285Sikob}
795103285Sikob
796103285SikobStringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
797103285Sikob  unsigned long long n;
798103285Sikob  if (getAsUnsignedInteger(Scalar, 0, n))
799103285Sikob    return "invalid number";
800103285Sikob  if (n > 0xFF)
801103285Sikob    return "out of range number";
802103285Sikob  Val = n;
803103285Sikob  return StringRef();
804103285Sikob}
805103285Sikob
806103285Sikobvoid ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
807103285Sikob                                    raw_ostream &Out) {
808103285Sikob  Out << Val;
809103285Sikob}
810103285Sikob
811103285SikobStringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
812110195Ssimokawa                                        uint16_t &Val) {
813103285Sikob  unsigned long long n;
814103285Sikob  if (getAsUnsignedInteger(Scalar, 0, n))
815110195Ssimokawa    return "invalid number";
816103285Sikob  if (n > 0xFFFF)
817103285Sikob    return "out of range number";
818103285Sikob  Val = n;
819103285Sikob  return StringRef();
820103285Sikob}
821110193Ssimokawa
822103285Sikobvoid ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
823103285Sikob                                    raw_ostream &Out) {
824103285Sikob  Out << Val;
825103285Sikob}
826103285Sikob
827103285SikobStringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
828103285Sikob                                        uint32_t &Val) {
829103285Sikob  unsigned long long n;
830103285Sikob  if (getAsUnsignedInteger(Scalar, 0, n))
831103285Sikob    return "invalid number";
832103285Sikob  if (n > 0xFFFFFFFFUL)
833103285Sikob    return "out of range number";
834103285Sikob  Val = n;
835103285Sikob  return StringRef();
836103285Sikob}
837103285Sikob
838103285Sikobvoid ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
839103285Sikob                                    raw_ostream &Out) {
840103285Sikob  Out << Val;
841103285Sikob}
842103285Sikob
843103285SikobStringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
844116376Ssimokawa                                        uint64_t &Val) {
845103285Sikob  unsigned long long N;
846106543Ssimokawa  if (getAsUnsignedInteger(Scalar, 0, N))
847103285Sikob    return "invalid number";
848103285Sikob  Val = N;
849103285Sikob  return StringRef();
850110195Ssimokawa}
851103285Sikob
852103285Sikobvoid ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
853139680Sjmg  // use temp in32_t because ostream thinks int8_t is a character
854103285Sikob  int32_t Num = Val;
855167632Ssimokawa  Out << Num;
856103285Sikob}
857103285Sikob
858103285SikobStringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
859103285Sikob  long long N;
860103285Sikob  if (getAsSignedInteger(Scalar, 0, N))
861103285Sikob    return "invalid number";
862103285Sikob  if ((N > 127) || (N < -128))
863103285Sikob    return "out of range number";
864106543Ssimokawa  Val = N;
865103285Sikob  return StringRef();
866106790Ssimokawa}
867120660Ssimokawa
868120660Ssimokawavoid ScalarTraits<int16_t>::output(const int16_t &Val, void *,
869120660Ssimokawa                                   raw_ostream &Out) {
870103285Sikob  Out << Val;
871129541Sdfr}
872103285Sikob
873106813SsimokawaStringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
874129585Sdfr  long long N;
875103285Sikob  if (getAsSignedInteger(Scalar, 0, N))
876120660Ssimokawa    return "invalid number";
877170374Ssimokawa  if ((N > INT16_MAX) || (N < INT16_MIN))
878120660Ssimokawa    return "out of range number";
879120660Ssimokawa  Val = N;
880170374Ssimokawa  return StringRef();
881120660Ssimokawa}
882170374Ssimokawa
883170374Ssimokawavoid ScalarTraits<int32_t>::output(const int32_t &Val, void *,
884170374Ssimokawa                                   raw_ostream &Out) {
885170374Ssimokawa  Out << Val;
886170374Ssimokawa}
887170374Ssimokawa
888103285SikobStringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
889106790Ssimokawa  long long N;
890103285Sikob  if (getAsSignedInteger(Scalar, 0, N))
891103285Sikob    return "invalid number";
892103285Sikob  if ((N > INT32_MAX) || (N < INT32_MIN))
893106790Ssimokawa    return "out of range number";
894106790Ssimokawa  Val = N;
895103285Sikob  return StringRef();
896120660Ssimokawa}
897170374Ssimokawa
898120660Ssimokawavoid ScalarTraits<int64_t>::output(const int64_t &Val, void *,
899120660Ssimokawa                                   raw_ostream &Out) {
900127468Ssimokawa  Out << Val;
901120660Ssimokawa}
902120660Ssimokawa
903120660SsimokawaStringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
904170374Ssimokawa  long long N;
905120660Ssimokawa  if (getAsSignedInteger(Scalar, 0, N))
906120660Ssimokawa    return "invalid number";
907120660Ssimokawa  Val = N;
908120660Ssimokawa  return StringRef();
909120660Ssimokawa}
910170374Ssimokawa
911103285Sikobvoid ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
912170374Ssimokawa  Out << format("%g", Val);
913120660Ssimokawa}
914170374Ssimokawa
915170374SsimokawaStringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
916170374Ssimokawa  SmallString<32> buff(Scalar.begin(), Scalar.end());
917103285Sikob  char *end;
918170374Ssimokawa  Val = strtod(buff.c_str(), &end);
919170374Ssimokawa  if (*end != '\0')
920103285Sikob    return "invalid floating point number";
921103285Sikob  return StringRef();
922103285Sikob}
923103285Sikob
924103285Sikobvoid ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
925106790Ssimokawa  Out << format("%g", Val);
926106790Ssimokawa}
927103285Sikob
928120660SsimokawaStringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
929120660Ssimokawa  SmallString<32> buff(Scalar.begin(), Scalar.end());
930120660Ssimokawa  char *end;
931120660Ssimokawa  Val = strtod(buff.c_str(), &end);
932103285Sikob  if (*end != '\0')
933103285Sikob    return "invalid floating point number";
934103285Sikob  return StringRef();
935170374Ssimokawa}
936120660Ssimokawa
937120660Ssimokawavoid ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
938120660Ssimokawa  uint8_t Num = Val;
939120660Ssimokawa  Out << format("0x%02X", Num);
940120660Ssimokawa}
941120660Ssimokawa
942129541SdfrStringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
943170374Ssimokawa  unsigned long long n;
944120660Ssimokawa  if (getAsUnsignedInteger(Scalar, 0, n))
945120660Ssimokawa    return "invalid hex8 number";
946120660Ssimokawa  if (n > 0xFF)
947120660Ssimokawa    return "out of range hex8 number";
948113584Ssimokawa  Val = n;
949113584Ssimokawa  return StringRef();
950113584Ssimokawa}
951113584Ssimokawa
952113584Ssimokawavoid ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
953113584Ssimokawa  uint16_t Num = Val;
954120660Ssimokawa  Out << format("0x%04X", Num);
955170374Ssimokawa}
956113584Ssimokawa
957103285SikobStringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
958103285Sikob  unsigned long long n;
959103285Sikob  if (getAsUnsignedInteger(Scalar, 0, n))
960103285Sikob    return "invalid hex16 number";
961169130Ssimokawa  if (n > 0xFFFF)
962169130Ssimokawa    return "out of range hex16 number";
963169130Ssimokawa  Val = n;
964169130Ssimokawa  return StringRef();
965169130Ssimokawa}
966169130Ssimokawa
967169130Ssimokawavoid ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
968169130Ssimokawa  uint32_t Num = Val;
969169130Ssimokawa  Out << format("0x%08X", Num);
970169130Ssimokawa}
971169130Ssimokawa
972169130SsimokawaStringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
973169130Ssimokawa  unsigned long long n;
974169130Ssimokawa  if (getAsUnsignedInteger(Scalar, 0, n))
975169130Ssimokawa    return "invalid hex32 number";
976169130Ssimokawa  if (n > 0xFFFFFFFFUL)
977169130Ssimokawa    return "out of range hex32 number";
978169130Ssimokawa  Val = n;
979169130Ssimokawa  return StringRef();
980169130Ssimokawa}
981169130Ssimokawa
982169130Ssimokawavoid ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
983169130Ssimokawa  uint64_t Num = Val;
984169130Ssimokawa  Out << format("0x%016llX", Num);
985169130Ssimokawa}
986169130Ssimokawa
987169130SsimokawaStringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
988169130Ssimokawa  unsigned long long Num;
989169130Ssimokawa  if (getAsUnsignedInteger(Scalar, 0, Num))
990169130Ssimokawa    return "invalid hex64 number";
991169130Ssimokawa  Val = Num;
992169130Ssimokawa  return StringRef();
993169130Ssimokawa}
994170374Ssimokawa