YAMLTraits.cpp revision 344779
1249259Sdim//===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
2249259Sdim//
3249259Sdim//                             The LLVM Linker
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim
10288943Sdim#include "llvm/Support/YAMLTraits.h"
11321369Sdim#include "llvm/ADT/STLExtras.h"
12288943Sdim#include "llvm/ADT/SmallString.h"
13321369Sdim#include "llvm/ADT/StringExtras.h"
14321369Sdim#include "llvm/ADT/StringRef.h"
15249259Sdim#include "llvm/ADT/Twine.h"
16249259Sdim#include "llvm/Support/Casting.h"
17288943Sdim#include "llvm/Support/Errc.h"
18249259Sdim#include "llvm/Support/ErrorHandling.h"
19249259Sdim#include "llvm/Support/Format.h"
20288943Sdim#include "llvm/Support/LineIterator.h"
21321369Sdim#include "llvm/Support/MemoryBuffer.h"
22327952Sdim#include "llvm/Support/Unicode.h"
23249259Sdim#include "llvm/Support/YAMLParser.h"
24249259Sdim#include "llvm/Support/raw_ostream.h"
25321369Sdim#include <algorithm>
26321369Sdim#include <cassert>
27321369Sdim#include <cstdint>
28321369Sdim#include <cstdlib>
29249259Sdim#include <cstring>
30321369Sdim#include <string>
31321369Sdim#include <vector>
32321369Sdim
33249259Sdimusing namespace llvm;
34249259Sdimusing namespace yaml;
35249259Sdim
36249259Sdim//===----------------------------------------------------------------------===//
37249259Sdim//  IO
38249259Sdim//===----------------------------------------------------------------------===//
39249259Sdim
40321369SdimIO::IO(void *Context) : Ctxt(Context) {}
41249259Sdim
42321369SdimIO::~IO() = default;
43249259Sdim
44249259Sdimvoid *IO::getContext() {
45249259Sdim  return Ctxt;
46249259Sdim}
47249259Sdim
48249259Sdimvoid IO::setContext(void *Context) {
49249259Sdim  Ctxt = Context;
50249259Sdim}
51249259Sdim
52249259Sdim//===----------------------------------------------------------------------===//
53249259Sdim//  Input
54249259Sdim//===----------------------------------------------------------------------===//
55249259Sdim
56314564SdimInput::Input(StringRef InputContent, void *Ctxt,
57314564Sdim             SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
58321369Sdim    : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
59261991Sdim  if (DiagHandler)
60261991Sdim    SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
61249259Sdim  DocIterator = Strm->begin();
62249259Sdim}
63249259Sdim
64321369SdimInput::Input(MemoryBufferRef Input, void *Ctxt,
65321369Sdim             SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
66321369Sdim    : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
67321369Sdim  if (DiagHandler)
68321369Sdim    SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
69321369Sdim  DocIterator = Strm->begin();
70249259Sdim}
71249259Sdim
72321369SdimInput::~Input() = default;
73321369Sdim
74276479Sdimstd::error_code Input::error() { return EC; }
75249259Sdim
76261991Sdim// Pin the vtables to this file.
77261991Sdimvoid Input::HNode::anchor() {}
78261991Sdimvoid Input::EmptyHNode::anchor() {}
79261991Sdimvoid Input::ScalarHNode::anchor() {}
80280031Sdimvoid Input::MapHNode::anchor() {}
81280031Sdimvoid Input::SequenceHNode::anchor() {}
82249259Sdim
83276479Sdimbool Input::outputting() {
84249259Sdim  return false;
85249259Sdim}
86249259Sdim
87249259Sdimbool Input::setCurrentDocument() {
88249259Sdim  if (DocIterator != Strm->end()) {
89249259Sdim    Node *N = DocIterator->getRoot();
90261991Sdim    if (!N) {
91261991Sdim      assert(Strm->failed() && "Root is NULL iff parsing failed");
92261991Sdim      EC = make_error_code(errc::invalid_argument);
93261991Sdim      return false;
94261991Sdim    }
95261991Sdim
96249259Sdim    if (isa<NullNode>(N)) {
97249259Sdim      // Empty files are allowed and ignored
98249259Sdim      ++DocIterator;
99249259Sdim      return setCurrentDocument();
100249259Sdim    }
101344779Sdim    TopNode = createHNodes(N);
102249259Sdim    CurrentNode = TopNode.get();
103249259Sdim    return true;
104249259Sdim  }
105249259Sdim  return false;
106249259Sdim}
107249259Sdim
108276479Sdimbool Input::nextDocument() {
109276479Sdim  return ++DocIterator != Strm->end();
110249259Sdim}
111249259Sdim
112288943Sdimconst Node *Input::getCurrentNode() const {
113288943Sdim  return CurrentNode ? CurrentNode->_node : nullptr;
114288943Sdim}
115288943Sdim
116261991Sdimbool Input::mapTag(StringRef Tag, bool Default) {
117261991Sdim  std::string foundTag = CurrentNode->_node->getVerbatimTag();
118261991Sdim  if (foundTag.empty()) {
119261991Sdim    // If no tag found and 'Tag' is the default, say it was found.
120261991Sdim    return Default;
121261991Sdim  }
122261991Sdim  // Return true iff found tag matches supplied tag.
123261991Sdim  return Tag.equals(foundTag);
124261991Sdim}
125261991Sdim
126249259Sdimvoid Input::beginMapping() {
127249259Sdim  if (EC)
128249259Sdim    return;
129261991Sdim  // CurrentNode can be null if the document is empty.
130261991Sdim  MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
131249259Sdim  if (MN) {
132249259Sdim    MN->ValidKeys.clear();
133249259Sdim  }
134249259Sdim}
135249259Sdim
136314564Sdimstd::vector<StringRef> Input::keys() {
137314564Sdim  MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
138314564Sdim  std::vector<StringRef> Ret;
139314564Sdim  if (!MN) {
140314564Sdim    setError(CurrentNode, "not a mapping");
141314564Sdim    return Ret;
142314564Sdim  }
143314564Sdim  for (auto &P : MN->Mapping)
144314564Sdim    Ret.push_back(P.first());
145314564Sdim  return Ret;
146314564Sdim}
147314564Sdim
148249259Sdimbool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
149249259Sdim                         void *&SaveInfo) {
150249259Sdim  UseDefault = false;
151249259Sdim  if (EC)
152249259Sdim    return false;
153261991Sdim
154261991Sdim  // CurrentNode is null for empty documents, which is an error in case required
155261991Sdim  // nodes are present.
156261991Sdim  if (!CurrentNode) {
157261991Sdim    if (Required)
158261991Sdim      EC = make_error_code(errc::invalid_argument);
159261991Sdim    return false;
160261991Sdim  }
161261991Sdim
162249259Sdim  MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
163249259Sdim  if (!MN) {
164327952Sdim    if (Required || !isa<EmptyHNode>(CurrentNode))
165327952Sdim      setError(CurrentNode, "not a mapping");
166249259Sdim    return false;
167249259Sdim  }
168249259Sdim  MN->ValidKeys.push_back(Key);
169280031Sdim  HNode *Value = MN->Mapping[Key].get();
170249259Sdim  if (!Value) {
171249259Sdim    if (Required)
172249259Sdim      setError(CurrentNode, Twine("missing required key '") + Key + "'");
173249259Sdim    else
174249259Sdim      UseDefault = true;
175249259Sdim    return false;
176249259Sdim  }
177249259Sdim  SaveInfo = CurrentNode;
178249259Sdim  CurrentNode = Value;
179249259Sdim  return true;
180249259Sdim}
181249259Sdim
182249259Sdimvoid Input::postflightKey(void *saveInfo) {
183249259Sdim  CurrentNode = reinterpret_cast<HNode *>(saveInfo);
184249259Sdim}
185249259Sdim
186249259Sdimvoid Input::endMapping() {
187249259Sdim  if (EC)
188249259Sdim    return;
189261991Sdim  // CurrentNode can be null if the document is empty.
190261991Sdim  MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
191249259Sdim  if (!MN)
192249259Sdim    return;
193276479Sdim  for (const auto &NN : MN->Mapping) {
194314564Sdim    if (!is_contained(MN->ValidKeys, NN.first())) {
195280031Sdim      setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
196249259Sdim      break;
197249259Sdim    }
198249259Sdim  }
199249259Sdim}
200249259Sdim
201288943Sdimvoid Input::beginFlowMapping() { beginMapping(); }
202288943Sdim
203288943Sdimvoid Input::endFlowMapping() { endMapping(); }
204288943Sdim
205249259Sdimunsigned Input::beginSequence() {
206288943Sdim  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
207249259Sdim    return SQ->Entries.size();
208288943Sdim  if (isa<EmptyHNode>(CurrentNode))
209288943Sdim    return 0;
210288943Sdim  // Treat case where there's a scalar "null" value as an empty sequence.
211288943Sdim  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
212288943Sdim    if (isNull(SN->value()))
213288943Sdim      return 0;
214249259Sdim  }
215288943Sdim  // Any other type of HNode is an error.
216288943Sdim  setError(CurrentNode, "not a sequence");
217249259Sdim  return 0;
218249259Sdim}
219249259Sdim
220249259Sdimvoid Input::endSequence() {
221249259Sdim}
222249259Sdim
223249259Sdimbool Input::preflightElement(unsigned Index, void *&SaveInfo) {
224249259Sdim  if (EC)
225249259Sdim    return false;
226249259Sdim  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
227249259Sdim    SaveInfo = CurrentNode;
228280031Sdim    CurrentNode = SQ->Entries[Index].get();
229249259Sdim    return true;
230249259Sdim  }
231249259Sdim  return false;
232249259Sdim}
233249259Sdim
234249259Sdimvoid Input::postflightElement(void *SaveInfo) {
235249259Sdim  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
236249259Sdim}
237249259Sdim
238288943Sdimunsigned Input::beginFlowSequence() { return beginSequence(); }
239249259Sdim
240249259Sdimbool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
241249259Sdim  if (EC)
242249259Sdim    return false;
243249259Sdim  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
244249259Sdim    SaveInfo = CurrentNode;
245280031Sdim    CurrentNode = SQ->Entries[index].get();
246249259Sdim    return true;
247249259Sdim  }
248249259Sdim  return false;
249249259Sdim}
250249259Sdim
251249259Sdimvoid Input::postflightFlowElement(void *SaveInfo) {
252249259Sdim  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
253249259Sdim}
254249259Sdim
255249259Sdimvoid Input::endFlowSequence() {
256249259Sdim}
257249259Sdim
258249259Sdimvoid Input::beginEnumScalar() {
259249259Sdim  ScalarMatchFound = false;
260249259Sdim}
261249259Sdim
262249259Sdimbool Input::matchEnumScalar(const char *Str, bool) {
263249259Sdim  if (ScalarMatchFound)
264249259Sdim    return false;
265249259Sdim  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
266249259Sdim    if (SN->value().equals(Str)) {
267249259Sdim      ScalarMatchFound = true;
268249259Sdim      return true;
269249259Sdim    }
270249259Sdim  }
271249259Sdim  return false;
272249259Sdim}
273249259Sdim
274288943Sdimbool Input::matchEnumFallback() {
275288943Sdim  if (ScalarMatchFound)
276288943Sdim    return false;
277288943Sdim  ScalarMatchFound = true;
278288943Sdim  return true;
279288943Sdim}
280288943Sdim
281249259Sdimvoid Input::endEnumScalar() {
282249259Sdim  if (!ScalarMatchFound) {
283249259Sdim    setError(CurrentNode, "unknown enumerated scalar");
284249259Sdim  }
285249259Sdim}
286249259Sdim
287249259Sdimbool Input::beginBitSetScalar(bool &DoClear) {
288249259Sdim  BitValuesUsed.clear();
289249259Sdim  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
290249259Sdim    BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
291249259Sdim  } else {
292249259Sdim    setError(CurrentNode, "expected sequence of bit values");
293249259Sdim  }
294249259Sdim  DoClear = true;
295249259Sdim  return true;
296249259Sdim}
297249259Sdim
298249259Sdimbool Input::bitSetMatch(const char *Str, bool) {
299249259Sdim  if (EC)
300249259Sdim    return false;
301249259Sdim  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
302249259Sdim    unsigned Index = 0;
303280031Sdim    for (auto &N : SQ->Entries) {
304280031Sdim      if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
305249259Sdim        if (SN->value().equals(Str)) {
306249259Sdim          BitValuesUsed[Index] = true;
307249259Sdim          return true;
308249259Sdim        }
309249259Sdim      } else {
310249259Sdim        setError(CurrentNode, "unexpected scalar in sequence of bit values");
311249259Sdim      }
312249259Sdim      ++Index;
313249259Sdim    }
314249259Sdim  } else {
315249259Sdim    setError(CurrentNode, "expected sequence of bit values");
316249259Sdim  }
317249259Sdim  return false;
318249259Sdim}
319249259Sdim
320249259Sdimvoid Input::endBitSetScalar() {
321249259Sdim  if (EC)
322249259Sdim    return;
323249259Sdim  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
324249259Sdim    assert(BitValuesUsed.size() == SQ->Entries.size());
325249259Sdim    for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
326249259Sdim      if (!BitValuesUsed[i]) {
327280031Sdim        setError(SQ->Entries[i].get(), "unknown bit value");
328249259Sdim        return;
329249259Sdim      }
330249259Sdim    }
331249259Sdim  }
332249259Sdim}
333249259Sdim
334327952Sdimvoid Input::scalarString(StringRef &S, QuotingType) {
335249259Sdim  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
336249259Sdim    S = SN->value();
337249259Sdim  } else {
338249259Sdim    setError(CurrentNode, "unexpected scalar");
339249259Sdim  }
340249259Sdim}
341249259Sdim
342327952Sdimvoid Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
343288943Sdim
344344779Sdimvoid Input::scalarTag(std::string &Tag) {
345344779Sdim  Tag = CurrentNode->_node->getVerbatimTag();
346344779Sdim}
347344779Sdim
348249259Sdimvoid Input::setError(HNode *hnode, const Twine &message) {
349261991Sdim  assert(hnode && "HNode must not be NULL");
350344779Sdim  setError(hnode->_node, message);
351249259Sdim}
352249259Sdim
353344779SdimNodeKind Input::getNodeKind() {
354344779Sdim  if (isa<ScalarHNode>(CurrentNode))
355344779Sdim    return NodeKind::Scalar;
356344779Sdim  else if (isa<MapHNode>(CurrentNode))
357344779Sdim    return NodeKind::Map;
358344779Sdim  else if (isa<SequenceHNode>(CurrentNode))
359344779Sdim    return NodeKind::Sequence;
360344779Sdim  llvm_unreachable("Unsupported node kind");
361344779Sdim}
362344779Sdim
363249259Sdimvoid Input::setError(Node *node, const Twine &message) {
364249259Sdim  Strm->printError(node, message);
365249259Sdim  EC = make_error_code(errc::invalid_argument);
366249259Sdim}
367249259Sdim
368280031Sdimstd::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
369249259Sdim  SmallString<128> StringStorage;
370249259Sdim  if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
371249259Sdim    StringRef KeyStr = SN->getValue(StringStorage);
372249259Sdim    if (!StringStorage.empty()) {
373249259Sdim      // Copy string to permanent storage
374296417Sdim      KeyStr = StringStorage.str().copy(StringAllocator);
375249259Sdim    }
376280031Sdim    return llvm::make_unique<ScalarHNode>(N, KeyStr);
377288943Sdim  } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
378296417Sdim    StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
379296417Sdim    return llvm::make_unique<ScalarHNode>(N, ValueCopy);
380249259Sdim  } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
381280031Sdim    auto SQHNode = llvm::make_unique<SequenceHNode>(N);
382276479Sdim    for (Node &SN : *SQ) {
383344779Sdim      auto Entry = createHNodes(&SN);
384249259Sdim      if (EC)
385249259Sdim        break;
386280031Sdim      SQHNode->Entries.push_back(std::move(Entry));
387249259Sdim    }
388280031Sdim    return std::move(SQHNode);
389249259Sdim  } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
390280031Sdim    auto mapHNode = llvm::make_unique<MapHNode>(N);
391276479Sdim    for (KeyValueNode &KVN : *Map) {
392280031Sdim      Node *KeyNode = KVN.getKey();
393327952Sdim      ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode);
394327952Sdim      Node *Value = KVN.getValue();
395327952Sdim      if (!Key || !Value) {
396327952Sdim        if (!Key)
397327952Sdim          setError(KeyNode, "Map key must be a scalar");
398327952Sdim        if (!Value)
399327952Sdim          setError(KeyNode, "Map value must not be empty");
400280031Sdim        break;
401280031Sdim      }
402249259Sdim      StringStorage.clear();
403327952Sdim      StringRef KeyStr = Key->getValue(StringStorage);
404249259Sdim      if (!StringStorage.empty()) {
405249259Sdim        // Copy string to permanent storage
406296417Sdim        KeyStr = StringStorage.str().copy(StringAllocator);
407249259Sdim      }
408344779Sdim      auto ValueHNode = createHNodes(Value);
409249259Sdim      if (EC)
410249259Sdim        break;
411280031Sdim      mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
412249259Sdim    }
413280031Sdim    return std::move(mapHNode);
414249259Sdim  } else if (isa<NullNode>(N)) {
415280031Sdim    return llvm::make_unique<EmptyHNode>(N);
416249259Sdim  } else {
417249259Sdim    setError(N, "unknown node kind");
418276479Sdim    return nullptr;
419249259Sdim  }
420249259Sdim}
421249259Sdim
422249259Sdimvoid Input::setError(const Twine &Message) {
423344779Sdim  setError(CurrentNode, Message);
424249259Sdim}
425249259Sdim
426261991Sdimbool Input::canElideEmptySequence() {
427261991Sdim  return false;
428261991Sdim}
429261991Sdim
430249259Sdim//===----------------------------------------------------------------------===//
431249259Sdim//  Output
432249259Sdim//===----------------------------------------------------------------------===//
433249259Sdim
434288943SdimOutput::Output(raw_ostream &yout, void *context, int WrapColumn)
435321369Sdim    : IO(context), Out(yout), WrapColumn(WrapColumn) {}
436249259Sdim
437321369SdimOutput::~Output() = default;
438249259Sdim
439276479Sdimbool Output::outputting() {
440249259Sdim  return true;
441249259Sdim}
442249259Sdim
443249259Sdimvoid Output::beginMapping() {
444249259Sdim  StateStack.push_back(inMapFirstKey);
445249259Sdim  NeedsNewLine = true;
446249259Sdim}
447249259Sdim
448261991Sdimbool Output::mapTag(StringRef Tag, bool Use) {
449261991Sdim  if (Use) {
450309124Sdim    // If this tag is being written inside a sequence we should write the start
451309124Sdim    // of the sequence before writing the tag, otherwise the tag won't be
452309124Sdim    // attached to the element in the sequence, but rather the sequence itself.
453344779Sdim    bool SequenceElement = false;
454344779Sdim    if (StateStack.size() > 1) {
455344779Sdim      auto &E = StateStack[StateStack.size() - 2];
456344779Sdim      SequenceElement = inSeqAnyElement(E) || inFlowSeqAnyElement(E);
457344779Sdim    }
458309124Sdim    if (SequenceElement && StateStack.back() == inMapFirstKey) {
459344779Sdim      newLineCheck();
460309124Sdim    } else {
461344779Sdim      output(" ");
462309124Sdim    }
463344779Sdim    output(Tag);
464309124Sdim    if (SequenceElement) {
465309124Sdim      // If we're writing the tag during the first element of a map, the tag
466309124Sdim      // takes the place of the first element in the sequence.
467309124Sdim      if (StateStack.back() == inMapFirstKey) {
468309124Sdim        StateStack.pop_back();
469309124Sdim        StateStack.push_back(inMapOtherKey);
470309124Sdim      }
471309124Sdim      // Tags inside maps in sequences should act as keys in the map from a
472309124Sdim      // formatting perspective, so we always want a newline in a sequence.
473309124Sdim      NeedsNewLine = true;
474309124Sdim    }
475261991Sdim  }
476261991Sdim  return Use;
477261991Sdim}
478261991Sdim
479249259Sdimvoid Output::endMapping() {
480344779Sdim  // If we did not map anything, we should explicitly emit an empty map
481344779Sdim  if (StateStack.back() == inMapFirstKey)
482344779Sdim    output("{}");
483249259Sdim  StateStack.pop_back();
484249259Sdim}
485249259Sdim
486314564Sdimstd::vector<StringRef> Output::keys() {
487314564Sdim  report_fatal_error("invalid call");
488314564Sdim}
489314564Sdim
490249259Sdimbool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
491249259Sdim                          bool &UseDefault, void *&) {
492249259Sdim  UseDefault = false;
493321369Sdim  if (Required || !SameAsDefault || WriteDefaultValues) {
494288943Sdim    auto State = StateStack.back();
495288943Sdim    if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
496288943Sdim      flowKey(Key);
497288943Sdim    } else {
498344779Sdim      newLineCheck();
499344779Sdim      paddedKey(Key);
500288943Sdim    }
501249259Sdim    return true;
502249259Sdim  }
503249259Sdim  return false;
504249259Sdim}
505249259Sdim
506249259Sdimvoid Output::postflightKey(void *) {
507249259Sdim  if (StateStack.back() == inMapFirstKey) {
508249259Sdim    StateStack.pop_back();
509249259Sdim    StateStack.push_back(inMapOtherKey);
510288943Sdim  } else if (StateStack.back() == inFlowMapFirstKey) {
511288943Sdim    StateStack.pop_back();
512288943Sdim    StateStack.push_back(inFlowMapOtherKey);
513249259Sdim  }
514249259Sdim}
515249259Sdim
516288943Sdimvoid Output::beginFlowMapping() {
517288943Sdim  StateStack.push_back(inFlowMapFirstKey);
518344779Sdim  newLineCheck();
519288943Sdim  ColumnAtMapFlowStart = Column;
520288943Sdim  output("{ ");
521288943Sdim}
522288943Sdim
523288943Sdimvoid Output::endFlowMapping() {
524288943Sdim  StateStack.pop_back();
525344779Sdim  outputUpToEndOfLine(" }");
526288943Sdim}
527288943Sdim
528249259Sdimvoid Output::beginDocuments() {
529344779Sdim  outputUpToEndOfLine("---");
530249259Sdim}
531249259Sdim
532249259Sdimbool Output::preflightDocument(unsigned index) {
533249259Sdim  if (index > 0)
534344779Sdim    outputUpToEndOfLine("\n---");
535249259Sdim  return true;
536249259Sdim}
537249259Sdim
538249259Sdimvoid Output::postflightDocument() {
539249259Sdim}
540249259Sdim
541249259Sdimvoid Output::endDocuments() {
542249259Sdim  output("\n...\n");
543249259Sdim}
544249259Sdim
545249259Sdimunsigned Output::beginSequence() {
546344779Sdim  StateStack.push_back(inSeqFirstElement);
547249259Sdim  NeedsNewLine = true;
548249259Sdim  return 0;
549249259Sdim}
550249259Sdim
551249259Sdimvoid Output::endSequence() {
552344779Sdim  // If we did not emit anything, we should explicitly emit an empty sequence
553344779Sdim  if (StateStack.back() == inSeqFirstElement)
554344779Sdim    output("[]");
555249259Sdim  StateStack.pop_back();
556249259Sdim}
557249259Sdim
558249259Sdimbool Output::preflightElement(unsigned, void *&) {
559249259Sdim  return true;
560249259Sdim}
561249259Sdim
562249259Sdimvoid Output::postflightElement(void *) {
563344779Sdim  if (StateStack.back() == inSeqFirstElement) {
564344779Sdim    StateStack.pop_back();
565344779Sdim    StateStack.push_back(inSeqOtherElement);
566344779Sdim  } else if (StateStack.back() == inFlowSeqFirstElement) {
567344779Sdim    StateStack.pop_back();
568344779Sdim    StateStack.push_back(inFlowSeqOtherElement);
569344779Sdim  }
570249259Sdim}
571249259Sdim
572249259Sdimunsigned Output::beginFlowSequence() {
573344779Sdim  StateStack.push_back(inFlowSeqFirstElement);
574344779Sdim  newLineCheck();
575249259Sdim  ColumnAtFlowStart = Column;
576249259Sdim  output("[ ");
577249259Sdim  NeedFlowSequenceComma = false;
578249259Sdim  return 0;
579249259Sdim}
580249259Sdim
581249259Sdimvoid Output::endFlowSequence() {
582249259Sdim  StateStack.pop_back();
583344779Sdim  outputUpToEndOfLine(" ]");
584249259Sdim}
585249259Sdim
586249259Sdimbool Output::preflightFlowElement(unsigned, void *&) {
587249259Sdim  if (NeedFlowSequenceComma)
588249259Sdim    output(", ");
589288943Sdim  if (WrapColumn && Column > WrapColumn) {
590249259Sdim    output("\n");
591249259Sdim    for (int i = 0; i < ColumnAtFlowStart; ++i)
592249259Sdim      output(" ");
593249259Sdim    Column = ColumnAtFlowStart;
594249259Sdim    output("  ");
595249259Sdim  }
596249259Sdim  return true;
597249259Sdim}
598249259Sdim
599249259Sdimvoid Output::postflightFlowElement(void *) {
600249259Sdim  NeedFlowSequenceComma = true;
601249259Sdim}
602249259Sdim
603249259Sdimvoid Output::beginEnumScalar() {
604249259Sdim  EnumerationMatchFound = false;
605249259Sdim}
606249259Sdim
607249259Sdimbool Output::matchEnumScalar(const char *Str, bool Match) {
608249259Sdim  if (Match && !EnumerationMatchFound) {
609344779Sdim    newLineCheck();
610344779Sdim    outputUpToEndOfLine(Str);
611249259Sdim    EnumerationMatchFound = true;
612249259Sdim  }
613249259Sdim  return false;
614249259Sdim}
615249259Sdim
616288943Sdimbool Output::matchEnumFallback() {
617288943Sdim  if (EnumerationMatchFound)
618288943Sdim    return false;
619288943Sdim  EnumerationMatchFound = true;
620288943Sdim  return true;
621288943Sdim}
622288943Sdim
623249259Sdimvoid Output::endEnumScalar() {
624249259Sdim  if (!EnumerationMatchFound)
625249259Sdim    llvm_unreachable("bad runtime enum value");
626249259Sdim}
627249259Sdim
628249259Sdimbool Output::beginBitSetScalar(bool &DoClear) {
629344779Sdim  newLineCheck();
630249259Sdim  output("[ ");
631249259Sdim  NeedBitValueComma = false;
632249259Sdim  DoClear = false;
633249259Sdim  return true;
634249259Sdim}
635249259Sdim
636249259Sdimbool Output::bitSetMatch(const char *Str, bool Matches) {
637249259Sdim  if (Matches) {
638249259Sdim    if (NeedBitValueComma)
639249259Sdim      output(", ");
640344779Sdim    output(Str);
641249259Sdim    NeedBitValueComma = true;
642249259Sdim  }
643249259Sdim  return false;
644249259Sdim}
645249259Sdim
646249259Sdimvoid Output::endBitSetScalar() {
647344779Sdim  outputUpToEndOfLine(" ]");
648249259Sdim}
649249259Sdim
650327952Sdimvoid Output::scalarString(StringRef &S, QuotingType MustQuote) {
651344779Sdim  newLineCheck();
652261991Sdim  if (S.empty()) {
653261991Sdim    // Print '' for the empty string because leaving the field empty is not
654261991Sdim    // allowed.
655344779Sdim    outputUpToEndOfLine("''");
656261991Sdim    return;
657261991Sdim  }
658327952Sdim  if (MustQuote == QuotingType::None) {
659276479Sdim    // Only quote if we must.
660344779Sdim    outputUpToEndOfLine(S);
661249259Sdim    return;
662249259Sdim  }
663327952Sdim
664249259Sdim  unsigned i = 0;
665249259Sdim  unsigned j = 0;
666249259Sdim  unsigned End = S.size();
667249259Sdim  const char *Base = S.data();
668327952Sdim
669327952Sdim  const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
670327952Sdim  output(Quote); // Starting quote.
671327952Sdim
672341825Sdim  // When using double-quoted strings (and only in that case), non-printable characters may be
673341825Sdim  // present, and will be escaped using a variety of unicode-scalar and special short-form
674341825Sdim  // escapes. This is handled in yaml::escape.
675341825Sdim  if (MustQuote == QuotingType::Double) {
676341825Sdim    output(yaml::escape(Base, /* EscapePrintable= */ false));
677344779Sdim    outputUpToEndOfLine(Quote);
678341825Sdim    return;
679341825Sdim  }
680341825Sdim
681341825Sdim  // When using single-quoted strings, any single quote ' must be doubled to be escaped.
682249259Sdim  while (j < End) {
683341825Sdim    if (S[j] == '\'') {                    // Escape quotes.
684341825Sdim      output(StringRef(&Base[i], j - i));  // "flush".
685341825Sdim      output(StringLiteral("''"));         // Print it as ''
686249259Sdim      i = j + 1;
687249259Sdim    }
688249259Sdim    ++j;
689249259Sdim  }
690249259Sdim  output(StringRef(&Base[i], j - i));
691344779Sdim  outputUpToEndOfLine(Quote); // Ending quote.
692249259Sdim}
693249259Sdim
694288943Sdimvoid Output::blockScalarString(StringRef &S) {
695288943Sdim  if (!StateStack.empty())
696288943Sdim    newLineCheck();
697288943Sdim  output(" |");
698288943Sdim  outputNewLine();
699288943Sdim
700288943Sdim  unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
701288943Sdim
702288943Sdim  auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
703288943Sdim  for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
704288943Sdim    for (unsigned I = 0; I < Indent; ++I) {
705288943Sdim      output("  ");
706288943Sdim    }
707288943Sdim    output(*Lines);
708288943Sdim    outputNewLine();
709288943Sdim  }
710288943Sdim}
711288943Sdim
712344779Sdimvoid Output::scalarTag(std::string &Tag) {
713344779Sdim  if (Tag.empty())
714344779Sdim    return;
715344779Sdim  newLineCheck();
716344779Sdim  output(Tag);
717344779Sdim  output(" ");
718344779Sdim}
719344779Sdim
720249259Sdimvoid Output::setError(const Twine &message) {
721249259Sdim}
722249259Sdim
723261991Sdimbool Output::canElideEmptySequence() {
724261991Sdim  // Normally, with an optional key/value where the value is an empty sequence,
725261991Sdim  // the whole key/value can be not written.  But, that produces wrong yaml
726261991Sdim  // if the key/value is the only thing in the map and the map is used in
727261991Sdim  // a sequence.  This detects if the this sequence is the first key/value
728261991Sdim  // in map that itself is embedded in a sequnce.
729261991Sdim  if (StateStack.size() < 2)
730261991Sdim    return true;
731261991Sdim  if (StateStack.back() != inMapFirstKey)
732261991Sdim    return true;
733344779Sdim  return !inSeqAnyElement(StateStack[StateStack.size() - 2]);
734261991Sdim}
735261991Sdim
736249259Sdimvoid Output::output(StringRef s) {
737249259Sdim  Column += s.size();
738249259Sdim  Out << s;
739249259Sdim}
740249259Sdim
741249259Sdimvoid Output::outputUpToEndOfLine(StringRef s) {
742344779Sdim  output(s);
743344779Sdim  if (StateStack.empty() || (!inFlowSeqAnyElement(StateStack.back()) &&
744344779Sdim                             !inFlowMapAnyKey(StateStack.back())))
745249259Sdim    NeedsNewLine = true;
746249259Sdim}
747249259Sdim
748249259Sdimvoid Output::outputNewLine() {
749249259Sdim  Out << "\n";
750249259Sdim  Column = 0;
751249259Sdim}
752249259Sdim
753249259Sdim// if seq at top, indent as if map, then add "- "
754249259Sdim// if seq in middle, use "- " if firstKey, else use "  "
755249259Sdim//
756249259Sdim
757249259Sdimvoid Output::newLineCheck() {
758249259Sdim  if (!NeedsNewLine)
759249259Sdim    return;
760249259Sdim  NeedsNewLine = false;
761249259Sdim
762344779Sdim  outputNewLine();
763249259Sdim
764344779Sdim  if (StateStack.size() == 0)
765344779Sdim    return;
766344779Sdim
767249259Sdim  unsigned Indent = StateStack.size() - 1;
768249259Sdim  bool OutputDash = false;
769249259Sdim
770344779Sdim  if (StateStack.back() == inSeqFirstElement ||
771344779Sdim      StateStack.back() == inSeqOtherElement) {
772249259Sdim    OutputDash = true;
773344779Sdim  } else if ((StateStack.size() > 1) &&
774344779Sdim             ((StateStack.back() == inMapFirstKey) ||
775344779Sdim              inFlowSeqAnyElement(StateStack.back()) ||
776344779Sdim              (StateStack.back() == inFlowMapFirstKey)) &&
777344779Sdim             inSeqAnyElement(StateStack[StateStack.size() - 2])) {
778249259Sdim    --Indent;
779249259Sdim    OutputDash = true;
780249259Sdim  }
781249259Sdim
782249259Sdim  for (unsigned i = 0; i < Indent; ++i) {
783249259Sdim    output("  ");
784249259Sdim  }
785249259Sdim  if (OutputDash) {
786249259Sdim    output("- ");
787249259Sdim  }
788249259Sdim
789249259Sdim}
790249259Sdim
791249259Sdimvoid Output::paddedKey(StringRef key) {
792249259Sdim  output(key);
793249259Sdim  output(":");
794249259Sdim  const char *spaces = "                ";
795249259Sdim  if (key.size() < strlen(spaces))
796249259Sdim    output(&spaces[key.size()]);
797249259Sdim  else
798249259Sdim    output(" ");
799249259Sdim}
800249259Sdim
801288943Sdimvoid Output::flowKey(StringRef Key) {
802288943Sdim  if (StateStack.back() == inFlowMapOtherKey)
803288943Sdim    output(", ");
804288943Sdim  if (WrapColumn && Column > WrapColumn) {
805288943Sdim    output("\n");
806288943Sdim    for (int I = 0; I < ColumnAtMapFlowStart; ++I)
807288943Sdim      output(" ");
808288943Sdim    Column = ColumnAtMapFlowStart;
809288943Sdim    output("  ");
810288943Sdim  }
811288943Sdim  output(Key);
812288943Sdim  output(": ");
813288943Sdim}
814288943Sdim
815344779SdimNodeKind Output::getNodeKind() { report_fatal_error("invalid call"); }
816344779Sdim
817344779Sdimbool Output::inSeqAnyElement(InState State) {
818344779Sdim  return State == inSeqFirstElement || State == inSeqOtherElement;
819344779Sdim}
820344779Sdim
821344779Sdimbool Output::inFlowSeqAnyElement(InState State) {
822344779Sdim  return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement;
823344779Sdim}
824344779Sdim
825344779Sdimbool Output::inMapAnyKey(InState State) {
826344779Sdim  return State == inMapFirstKey || State == inMapOtherKey;
827344779Sdim}
828344779Sdim
829344779Sdimbool Output::inFlowMapAnyKey(InState State) {
830344779Sdim  return State == inFlowMapFirstKey || State == inFlowMapOtherKey;
831344779Sdim}
832344779Sdim
833249259Sdim//===----------------------------------------------------------------------===//
834249259Sdim//  traits for built-in types
835249259Sdim//===----------------------------------------------------------------------===//
836249259Sdim
837249259Sdimvoid ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
838249259Sdim  Out << (Val ? "true" : "false");
839249259Sdim}
840249259Sdim
841249259SdimStringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
842249259Sdim  if (Scalar.equals("true")) {
843249259Sdim    Val = true;
844249259Sdim    return StringRef();
845249259Sdim  } else if (Scalar.equals("false")) {
846249259Sdim    Val = false;
847249259Sdim    return StringRef();
848249259Sdim  }
849249259Sdim  return "invalid boolean";
850249259Sdim}
851249259Sdim
852249259Sdimvoid ScalarTraits<StringRef>::output(const StringRef &Val, void *,
853249259Sdim                                     raw_ostream &Out) {
854249259Sdim  Out << Val;
855249259Sdim}
856249259Sdim
857249259SdimStringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
858249259Sdim                                         StringRef &Val) {
859249259Sdim  Val = Scalar;
860249259Sdim  return StringRef();
861249259Sdim}
862288943Sdim
863276479Sdimvoid ScalarTraits<std::string>::output(const std::string &Val, void *,
864276479Sdim                                     raw_ostream &Out) {
865276479Sdim  Out << Val;
866276479Sdim}
867249259Sdim
868276479SdimStringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
869276479Sdim                                         std::string &Val) {
870276479Sdim  Val = Scalar.str();
871276479Sdim  return StringRef();
872276479Sdim}
873276479Sdim
874249259Sdimvoid ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
875249259Sdim                                   raw_ostream &Out) {
876249259Sdim  // use temp uin32_t because ostream thinks uint8_t is a character
877249259Sdim  uint32_t Num = Val;
878249259Sdim  Out << Num;
879249259Sdim}
880249259Sdim
881249259SdimStringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
882249259Sdim  unsigned long long n;
883249259Sdim  if (getAsUnsignedInteger(Scalar, 0, n))
884249259Sdim    return "invalid number";
885249259Sdim  if (n > 0xFF)
886249259Sdim    return "out of range number";
887249259Sdim  Val = n;
888249259Sdim  return StringRef();
889249259Sdim}
890249259Sdim
891249259Sdimvoid ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
892249259Sdim                                    raw_ostream &Out) {
893249259Sdim  Out << Val;
894249259Sdim}
895249259Sdim
896249259SdimStringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
897249259Sdim                                        uint16_t &Val) {
898249259Sdim  unsigned long long n;
899249259Sdim  if (getAsUnsignedInteger(Scalar, 0, n))
900249259Sdim    return "invalid number";
901249259Sdim  if (n > 0xFFFF)
902249259Sdim    return "out of range number";
903249259Sdim  Val = n;
904249259Sdim  return StringRef();
905249259Sdim}
906249259Sdim
907249259Sdimvoid ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
908249259Sdim                                    raw_ostream &Out) {
909249259Sdim  Out << Val;
910249259Sdim}
911249259Sdim
912249259SdimStringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
913249259Sdim                                        uint32_t &Val) {
914249259Sdim  unsigned long long n;
915249259Sdim  if (getAsUnsignedInteger(Scalar, 0, n))
916249259Sdim    return "invalid number";
917249259Sdim  if (n > 0xFFFFFFFFUL)
918249259Sdim    return "out of range number";
919249259Sdim  Val = n;
920249259Sdim  return StringRef();
921249259Sdim}
922249259Sdim
923249259Sdimvoid ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
924249259Sdim                                    raw_ostream &Out) {
925249259Sdim  Out << Val;
926249259Sdim}
927249259Sdim
928249259SdimStringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
929249259Sdim                                        uint64_t &Val) {
930249259Sdim  unsigned long long N;
931249259Sdim  if (getAsUnsignedInteger(Scalar, 0, N))
932249259Sdim    return "invalid number";
933249259Sdim  Val = N;
934249259Sdim  return StringRef();
935249259Sdim}
936249259Sdim
937249259Sdimvoid ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
938249259Sdim  // use temp in32_t because ostream thinks int8_t is a character
939249259Sdim  int32_t Num = Val;
940249259Sdim  Out << Num;
941249259Sdim}
942249259Sdim
943249259SdimStringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
944249259Sdim  long long N;
945249259Sdim  if (getAsSignedInteger(Scalar, 0, N))
946249259Sdim    return "invalid number";
947249259Sdim  if ((N > 127) || (N < -128))
948249259Sdim    return "out of range number";
949249259Sdim  Val = N;
950249259Sdim  return StringRef();
951249259Sdim}
952249259Sdim
953249259Sdimvoid ScalarTraits<int16_t>::output(const int16_t &Val, void *,
954249259Sdim                                   raw_ostream &Out) {
955249259Sdim  Out << Val;
956249259Sdim}
957249259Sdim
958249259SdimStringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
959249259Sdim  long long N;
960249259Sdim  if (getAsSignedInteger(Scalar, 0, N))
961249259Sdim    return "invalid number";
962249259Sdim  if ((N > INT16_MAX) || (N < INT16_MIN))
963249259Sdim    return "out of range number";
964249259Sdim  Val = N;
965249259Sdim  return StringRef();
966249259Sdim}
967249259Sdim
968249259Sdimvoid ScalarTraits<int32_t>::output(const int32_t &Val, void *,
969249259Sdim                                   raw_ostream &Out) {
970249259Sdim  Out << Val;
971249259Sdim}
972249259Sdim
973249259SdimStringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
974249259Sdim  long long N;
975249259Sdim  if (getAsSignedInteger(Scalar, 0, N))
976249259Sdim    return "invalid number";
977249259Sdim  if ((N > INT32_MAX) || (N < INT32_MIN))
978249259Sdim    return "out of range number";
979249259Sdim  Val = N;
980249259Sdim  return StringRef();
981249259Sdim}
982249259Sdim
983249259Sdimvoid ScalarTraits<int64_t>::output(const int64_t &Val, void *,
984249259Sdim                                   raw_ostream &Out) {
985249259Sdim  Out << Val;
986249259Sdim}
987249259Sdim
988249259SdimStringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
989249259Sdim  long long N;
990249259Sdim  if (getAsSignedInteger(Scalar, 0, N))
991249259Sdim    return "invalid number";
992249259Sdim  Val = N;
993249259Sdim  return StringRef();
994249259Sdim}
995249259Sdim
996249259Sdimvoid ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
997249259Sdim  Out << format("%g", Val);
998249259Sdim}
999249259Sdim
1000249259SdimStringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
1001321369Sdim  if (to_float(Scalar, Val))
1002321369Sdim    return StringRef();
1003321369Sdim  return "invalid floating point number";
1004249259Sdim}
1005249259Sdim
1006249259Sdimvoid ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
1007249259Sdim  Out << format("%g", Val);
1008249259Sdim}
1009249259Sdim
1010249259SdimStringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
1011321369Sdim  if (to_float(Scalar, Val))
1012321369Sdim    return StringRef();
1013321369Sdim  return "invalid floating point number";
1014249259Sdim}
1015249259Sdim
1016249259Sdimvoid ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
1017249259Sdim  uint8_t Num = Val;
1018249259Sdim  Out << format("0x%02X", Num);
1019249259Sdim}
1020249259Sdim
1021249259SdimStringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
1022249259Sdim  unsigned long long n;
1023249259Sdim  if (getAsUnsignedInteger(Scalar, 0, n))
1024249259Sdim    return "invalid hex8 number";
1025249259Sdim  if (n > 0xFF)
1026249259Sdim    return "out of range hex8 number";
1027249259Sdim  Val = n;
1028249259Sdim  return StringRef();
1029249259Sdim}
1030249259Sdim
1031249259Sdimvoid ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
1032249259Sdim  uint16_t Num = Val;
1033249259Sdim  Out << format("0x%04X", Num);
1034249259Sdim}
1035249259Sdim
1036249259SdimStringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
1037249259Sdim  unsigned long long n;
1038249259Sdim  if (getAsUnsignedInteger(Scalar, 0, n))
1039249259Sdim    return "invalid hex16 number";
1040249259Sdim  if (n > 0xFFFF)
1041249259Sdim    return "out of range hex16 number";
1042249259Sdim  Val = n;
1043249259Sdim  return StringRef();
1044249259Sdim}
1045249259Sdim
1046249259Sdimvoid ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
1047249259Sdim  uint32_t Num = Val;
1048249259Sdim  Out << format("0x%08X", Num);
1049249259Sdim}
1050249259Sdim
1051249259SdimStringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
1052249259Sdim  unsigned long long n;
1053249259Sdim  if (getAsUnsignedInteger(Scalar, 0, n))
1054249259Sdim    return "invalid hex32 number";
1055249259Sdim  if (n > 0xFFFFFFFFUL)
1056249259Sdim    return "out of range hex32 number";
1057249259Sdim  Val = n;
1058249259Sdim  return StringRef();
1059249259Sdim}
1060249259Sdim
1061249259Sdimvoid ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
1062249259Sdim  uint64_t Num = Val;
1063249259Sdim  Out << format("0x%016llX", Num);
1064249259Sdim}
1065249259Sdim
1066249259SdimStringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
1067249259Sdim  unsigned long long Num;
1068249259Sdim  if (getAsUnsignedInteger(Scalar, 0, Num))
1069249259Sdim    return "invalid hex64 number";
1070249259Sdim  Val = Num;
1071249259Sdim  return StringRef();
1072249259Sdim}
1073