f46f140abd882cb5bea79efea6a667b935bd4a06
[oota-llvm.git] / lib / Support / YAMLTraits.cpp
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/Twine.h"
12 #include "llvm/Support/Casting.h"
13 #include "llvm/Support/ErrorHandling.h"
14 #include "llvm/Support/Format.h"
15 #include "llvm/Support/YAMLParser.h"
16 #include "llvm/Support/raw_ostream.h"
17 #include <cctype>
18 #include <cstring>
19 using namespace llvm;
20 using namespace yaml;
21
22 //===----------------------------------------------------------------------===//
23 //  IO
24 //===----------------------------------------------------------------------===//
25
26 IO::IO(void *Context) : Ctxt(Context) {
27 }
28
29 IO::~IO() {
30 }
31
32 void *IO::getContext() {
33   return Ctxt;
34 }
35
36 void IO::setContext(void *Context) {
37   Ctxt = Context;
38 }
39
40 //===----------------------------------------------------------------------===//
41 //  Input
42 //===----------------------------------------------------------------------===//
43
44 Input::Input(StringRef InputContent,
45              void *Ctxt,
46              SourceMgr::DiagHandlerTy DiagHandler,
47              void *DiagHandlerCtxt)
48   : IO(Ctxt),
49     Strm(new Stream(InputContent, SrcMgr)),
50     CurrentNode(nullptr) {
51   if (DiagHandler)
52     SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
53   DocIterator = Strm->begin();
54 }
55
56 Input::~Input() {
57 }
58
59 error_code Input::error() {
60   return EC;
61 }
62
63 // Pin the vtables to this file.
64 void Input::HNode::anchor() {}
65 void Input::EmptyHNode::anchor() {}
66 void Input::ScalarHNode::anchor() {}
67
68 bool Input::outputting() {
69   return false;
70 }
71
72 bool Input::setCurrentDocument() {
73   if (DocIterator != Strm->end()) {
74     Node *N = DocIterator->getRoot();
75     if (!N) {
76       assert(Strm->failed() && "Root is NULL iff parsing failed");
77       EC = make_error_code(errc::invalid_argument);
78       return false;
79     }
80
81     if (isa<NullNode>(N)) {
82       // Empty files are allowed and ignored
83       ++DocIterator;
84       return setCurrentDocument();
85     }
86     TopNode.reset(this->createHNodes(N));
87     CurrentNode = TopNode.get();
88     return true;
89   }
90   return false;
91 }
92
93 void Input::nextDocument() {
94   ++DocIterator;
95 }
96
97 bool Input::mapTag(StringRef Tag, bool Default) {
98   std::string foundTag = CurrentNode->_node->getVerbatimTag();
99   if (foundTag.empty()) {
100     // If no tag found and 'Tag' is the default, say it was found.
101     return Default;
102   }
103   // Return true iff found tag matches supplied tag.
104   return Tag.equals(foundTag);
105 }
106
107 void Input::beginMapping() {
108   if (EC)
109     return;
110   // CurrentNode can be null if the document is empty.
111   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
112   if (MN) {
113     MN->ValidKeys.clear();
114   }
115 }
116
117 bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
118                          void *&SaveInfo) {
119   UseDefault = false;
120   if (EC)
121     return false;
122
123   // CurrentNode is null for empty documents, which is an error in case required
124   // nodes are present.
125   if (!CurrentNode) {
126     if (Required)
127       EC = make_error_code(errc::invalid_argument);
128     return false;
129   }
130
131   MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
132   if (!MN) {
133     setError(CurrentNode, "not a mapping");
134     return false;
135   }
136   MN->ValidKeys.push_back(Key);
137   HNode *Value = MN->Mapping[Key];
138   if (!Value) {
139     if (Required)
140       setError(CurrentNode, Twine("missing required key '") + Key + "'");
141     else
142       UseDefault = true;
143     return false;
144   }
145   SaveInfo = CurrentNode;
146   CurrentNode = Value;
147   return true;
148 }
149
150 void Input::postflightKey(void *saveInfo) {
151   CurrentNode = reinterpret_cast<HNode *>(saveInfo);
152 }
153
154 void Input::endMapping() {
155   if (EC)
156     return;
157   // CurrentNode can be null if the document is empty.
158   MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
159   if (!MN)
160     return;
161   for (const auto &NN : MN->Mapping) {
162     if (!MN->isValidKey(NN.first())) {
163       setError(NN.second, Twine("unknown key '") + NN.first() + "'");
164       break;
165     }
166   }
167 }
168
169 unsigned Input::beginSequence() {
170   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
171     return SQ->Entries.size();
172   }
173   return 0;
174 }
175
176 void Input::endSequence() {
177 }
178
179 bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
180   if (EC)
181     return false;
182   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
183     SaveInfo = CurrentNode;
184     CurrentNode = SQ->Entries[Index];
185     return true;
186   }
187   return false;
188 }
189
190 void Input::postflightElement(void *SaveInfo) {
191   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
192 }
193
194 unsigned Input::beginFlowSequence() {
195   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
196     return SQ->Entries.size();
197   }
198   return 0;
199 }
200
201 bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
202   if (EC)
203     return false;
204   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
205     SaveInfo = CurrentNode;
206     CurrentNode = SQ->Entries[index];
207     return true;
208   }
209   return false;
210 }
211
212 void Input::postflightFlowElement(void *SaveInfo) {
213   CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
214 }
215
216 void Input::endFlowSequence() {
217 }
218
219 void Input::beginEnumScalar() {
220   ScalarMatchFound = false;
221 }
222
223 bool Input::matchEnumScalar(const char *Str, bool) {
224   if (ScalarMatchFound)
225     return false;
226   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
227     if (SN->value().equals(Str)) {
228       ScalarMatchFound = true;
229       return true;
230     }
231   }
232   return false;
233 }
234
235 void Input::endEnumScalar() {
236   if (!ScalarMatchFound) {
237     setError(CurrentNode, "unknown enumerated scalar");
238   }
239 }
240
241 bool Input::beginBitSetScalar(bool &DoClear) {
242   BitValuesUsed.clear();
243   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
244     BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
245   } else {
246     setError(CurrentNode, "expected sequence of bit values");
247   }
248   DoClear = true;
249   return true;
250 }
251
252 bool Input::bitSetMatch(const char *Str, bool) {
253   if (EC)
254     return false;
255   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
256     unsigned Index = 0;
257     for (HNode *N : SQ->Entries) {
258       if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N)) {
259         if (SN->value().equals(Str)) {
260           BitValuesUsed[Index] = true;
261           return true;
262         }
263       } else {
264         setError(CurrentNode, "unexpected scalar in sequence of bit values");
265       }
266       ++Index;
267     }
268   } else {
269     setError(CurrentNode, "expected sequence of bit values");
270   }
271   return false;
272 }
273
274 void Input::endBitSetScalar() {
275   if (EC)
276     return;
277   if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
278     assert(BitValuesUsed.size() == SQ->Entries.size());
279     for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
280       if (!BitValuesUsed[i]) {
281         setError(SQ->Entries[i], "unknown bit value");
282         return;
283       }
284     }
285   }
286 }
287
288 void Input::scalarString(StringRef &S) {
289   if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
290     S = SN->value();
291   } else {
292     setError(CurrentNode, "unexpected scalar");
293   }
294 }
295
296 void Input::setError(HNode *hnode, const Twine &message) {
297   assert(hnode && "HNode must not be NULL");
298   this->setError(hnode->_node, message);
299 }
300
301 void Input::setError(Node *node, const Twine &message) {
302   Strm->printError(node, message);
303   EC = make_error_code(errc::invalid_argument);
304 }
305
306 Input::HNode *Input::createHNodes(Node *N) {
307   SmallString<128> StringStorage;
308   if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
309     StringRef KeyStr = SN->getValue(StringStorage);
310     if (!StringStorage.empty()) {
311       // Copy string to permanent storage
312       unsigned Len = StringStorage.size();
313       char *Buf = StringAllocator.Allocate<char>(Len);
314       memcpy(Buf, &StringStorage[0], Len);
315       KeyStr = StringRef(Buf, Len);
316     }
317     return new ScalarHNode(N, KeyStr);
318   } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
319     SequenceHNode *SQHNode = new SequenceHNode(N);
320     for (Node &SN : *SQ) {
321       HNode *Entry = this->createHNodes(&SN);
322       if (EC)
323         break;
324       SQHNode->Entries.push_back(Entry);
325     }
326     return SQHNode;
327   } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
328     MapHNode *mapHNode = new MapHNode(N);
329     for (KeyValueNode &KVN : *Map) {
330       ScalarNode *KeyScalar = dyn_cast<ScalarNode>(KVN.getKey());
331       StringStorage.clear();
332       StringRef KeyStr = KeyScalar->getValue(StringStorage);
333       if (!StringStorage.empty()) {
334         // Copy string to permanent storage
335         unsigned Len = StringStorage.size();
336         char *Buf = StringAllocator.Allocate<char>(Len);
337         memcpy(Buf, &StringStorage[0], Len);
338         KeyStr = StringRef(Buf, Len);
339       }
340       HNode *ValueHNode = this->createHNodes(KVN.getValue());
341       if (EC)
342         break;
343       mapHNode->Mapping[KeyStr] = ValueHNode;
344     }
345     return mapHNode;
346   } else if (isa<NullNode>(N)) {
347     return new EmptyHNode(N);
348   } else {
349     setError(N, "unknown node kind");
350     return nullptr;
351   }
352 }
353
354 bool Input::MapHNode::isValidKey(StringRef Key) {
355   for (const char *K : ValidKeys) {
356     if (Key.equals(K))
357       return true;
358   }
359   return false;
360 }
361
362 void Input::setError(const Twine &Message) {
363   this->setError(CurrentNode, Message);
364 }
365
366 bool Input::canElideEmptySequence() {
367   return false;
368 }
369
370 Input::MapHNode::~MapHNode() {
371   for (auto &N : Mapping)
372     delete N.second;
373 }
374
375 Input::SequenceHNode::~SequenceHNode() {
376   for (HNode *N : Entries)
377     delete N;
378 }
379
380
381
382 //===----------------------------------------------------------------------===//
383 //  Output
384 //===----------------------------------------------------------------------===//
385
386 Output::Output(raw_ostream &yout, void *context)
387     : IO(context),
388       Out(yout),
389       Column(0),
390       ColumnAtFlowStart(0),
391       NeedBitValueComma(false),
392       NeedFlowSequenceComma(false),
393       EnumerationMatchFound(false),
394       NeedsNewLine(false) {
395 }
396
397 Output::~Output() {
398 }
399
400 bool Output::outputting() {
401   return true;
402 }
403
404 void Output::beginMapping() {
405   StateStack.push_back(inMapFirstKey);
406   NeedsNewLine = true;
407 }
408
409 bool Output::mapTag(StringRef Tag, bool Use) {
410   if (Use) {
411     this->output(" ");
412     this->output(Tag);
413   }
414   return Use;
415 }
416
417 void Output::endMapping() {
418   StateStack.pop_back();
419 }
420
421 bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
422                           bool &UseDefault, void *&) {
423   UseDefault = false;
424   if (Required || !SameAsDefault) {
425     this->newLineCheck();
426     this->paddedKey(Key);
427     return true;
428   }
429   return false;
430 }
431
432 void Output::postflightKey(void *) {
433   if (StateStack.back() == inMapFirstKey) {
434     StateStack.pop_back();
435     StateStack.push_back(inMapOtherKey);
436   }
437 }
438
439 void Output::beginDocuments() {
440   this->outputUpToEndOfLine("---");
441 }
442
443 bool Output::preflightDocument(unsigned index) {
444   if (index > 0)
445     this->outputUpToEndOfLine("\n---");
446   return true;
447 }
448
449 void Output::postflightDocument() {
450 }
451
452 void Output::endDocuments() {
453   output("\n...\n");
454 }
455
456 unsigned Output::beginSequence() {
457   StateStack.push_back(inSeq);
458   NeedsNewLine = true;
459   return 0;
460 }
461
462 void Output::endSequence() {
463   StateStack.pop_back();
464 }
465
466 bool Output::preflightElement(unsigned, void *&) {
467   return true;
468 }
469
470 void Output::postflightElement(void *) {
471 }
472
473 unsigned Output::beginFlowSequence() {
474   StateStack.push_back(inFlowSeq);
475   this->newLineCheck();
476   ColumnAtFlowStart = Column;
477   output("[ ");
478   NeedFlowSequenceComma = false;
479   return 0;
480 }
481
482 void Output::endFlowSequence() {
483   StateStack.pop_back();
484   this->outputUpToEndOfLine(" ]");
485 }
486
487 bool Output::preflightFlowElement(unsigned, void *&) {
488   if (NeedFlowSequenceComma)
489     output(", ");
490   if (Column > 70) {
491     output("\n");
492     for (int i = 0; i < ColumnAtFlowStart; ++i)
493       output(" ");
494     Column = ColumnAtFlowStart;
495     output("  ");
496   }
497   return true;
498 }
499
500 void Output::postflightFlowElement(void *) {
501   NeedFlowSequenceComma = true;
502 }
503
504 void Output::beginEnumScalar() {
505   EnumerationMatchFound = false;
506 }
507
508 bool Output::matchEnumScalar(const char *Str, bool Match) {
509   if (Match && !EnumerationMatchFound) {
510     this->newLineCheck();
511     this->outputUpToEndOfLine(Str);
512     EnumerationMatchFound = true;
513   }
514   return false;
515 }
516
517 void Output::endEnumScalar() {
518   if (!EnumerationMatchFound)
519     llvm_unreachable("bad runtime enum value");
520 }
521
522 bool Output::beginBitSetScalar(bool &DoClear) {
523   this->newLineCheck();
524   output("[ ");
525   NeedBitValueComma = false;
526   DoClear = false;
527   return true;
528 }
529
530 bool Output::bitSetMatch(const char *Str, bool Matches) {
531   if (Matches) {
532     if (NeedBitValueComma)
533       output(", ");
534     this->output(Str);
535     NeedBitValueComma = true;
536   }
537   return false;
538 }
539
540 void Output::endBitSetScalar() {
541   this->outputUpToEndOfLine(" ]");
542 }
543
544 void Output::scalarString(StringRef &S) {
545   const char ScalarSafeChars[] = "abcdefghijklmnopqrstuvwxyz"
546       "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
547
548   this->newLineCheck();
549   if (S.empty()) {
550     // Print '' for the empty string because leaving the field empty is not
551     // allowed.
552     this->outputUpToEndOfLine("''");
553     return;
554   }
555   bool isOctalString = S.front() == '0' && S.size() > 2 && !S.startswith("0x");
556   if (S.find_first_not_of(ScalarSafeChars) == StringRef::npos &&
557       !isspace(S.front()) && !isspace(S.back()) && !isOctalString) {
558     // If the string consists only of safe characters, print it out without
559     // quotes.
560     this->outputUpToEndOfLine(S);
561     return;
562   }
563   unsigned i = 0;
564   unsigned j = 0;
565   unsigned End = S.size();
566   output("'"); // Starting single quote.
567   const char *Base = S.data();
568   while (j < End) {
569     // Escape a single quote by doubling it.
570     if (S[j] == '\'') {
571       output(StringRef(&Base[i], j - i + 1));
572       output("'");
573       i = j + 1;
574     }
575     ++j;
576   }
577   output(StringRef(&Base[i], j - i));
578   this->outputUpToEndOfLine("'"); // Ending single quote.
579 }
580
581 void Output::setError(const Twine &message) {
582 }
583
584 bool Output::canElideEmptySequence() {
585   // Normally, with an optional key/value where the value is an empty sequence,
586   // the whole key/value can be not written.  But, that produces wrong yaml
587   // if the key/value is the only thing in the map and the map is used in
588   // a sequence.  This detects if the this sequence is the first key/value
589   // in map that itself is embedded in a sequnce.
590   if (StateStack.size() < 2)
591     return true;
592   if (StateStack.back() != inMapFirstKey)
593     return true;
594   return (StateStack[StateStack.size()-2] != inSeq);
595 }
596
597 void Output::output(StringRef s) {
598   Column += s.size();
599   Out << s;
600 }
601
602 void Output::outputUpToEndOfLine(StringRef s) {
603   this->output(s);
604   if (StateStack.empty() || StateStack.back() != inFlowSeq)
605     NeedsNewLine = true;
606 }
607
608 void Output::outputNewLine() {
609   Out << "\n";
610   Column = 0;
611 }
612
613 // if seq at top, indent as if map, then add "- "
614 // if seq in middle, use "- " if firstKey, else use "  "
615 //
616
617 void Output::newLineCheck() {
618   if (!NeedsNewLine)
619     return;
620   NeedsNewLine = false;
621
622   this->outputNewLine();
623
624   assert(StateStack.size() > 0);
625   unsigned Indent = StateStack.size() - 1;
626   bool OutputDash = false;
627
628   if (StateStack.back() == inSeq) {
629     OutputDash = true;
630   } else if ((StateStack.size() > 1) && (StateStack.back() == inMapFirstKey) &&
631              (StateStack[StateStack.size() - 2] == inSeq)) {
632     --Indent;
633     OutputDash = true;
634   }
635
636   for (unsigned i = 0; i < Indent; ++i) {
637     output("  ");
638   }
639   if (OutputDash) {
640     output("- ");
641   }
642
643 }
644
645 void Output::paddedKey(StringRef key) {
646   output(key);
647   output(":");
648   const char *spaces = "                ";
649   if (key.size() < strlen(spaces))
650     output(&spaces[key.size()]);
651   else
652     output(" ");
653 }
654
655 //===----------------------------------------------------------------------===//
656 //  traits for built-in types
657 //===----------------------------------------------------------------------===//
658
659 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
660   Out << (Val ? "true" : "false");
661 }
662
663 StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
664   if (Scalar.equals("true")) {
665     Val = true;
666     return StringRef();
667   } else if (Scalar.equals("false")) {
668     Val = false;
669     return StringRef();
670   }
671   return "invalid boolean";
672 }
673
674 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
675                                      raw_ostream &Out) {
676   Out << Val;
677 }
678
679 StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
680                                          StringRef &Val) {
681   Val = Scalar;
682   return StringRef();
683 }
684  
685 void ScalarTraits<std::string>::output(const std::string &Val, void *,
686                                      raw_ostream &Out) {
687   Out << Val;
688 }
689
690 StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
691                                          std::string &Val) {
692   Val = Scalar.str();
693   return StringRef();
694 }
695
696 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
697                                    raw_ostream &Out) {
698   // use temp uin32_t because ostream thinks uint8_t is a character
699   uint32_t Num = Val;
700   Out << Num;
701 }
702
703 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
704   unsigned long long n;
705   if (getAsUnsignedInteger(Scalar, 0, n))
706     return "invalid number";
707   if (n > 0xFF)
708     return "out of range number";
709   Val = n;
710   return StringRef();
711 }
712
713 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
714                                     raw_ostream &Out) {
715   Out << Val;
716 }
717
718 StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
719                                         uint16_t &Val) {
720   unsigned long long n;
721   if (getAsUnsignedInteger(Scalar, 0, n))
722     return "invalid number";
723   if (n > 0xFFFF)
724     return "out of range number";
725   Val = n;
726   return StringRef();
727 }
728
729 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
730                                     raw_ostream &Out) {
731   Out << Val;
732 }
733
734 StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
735                                         uint32_t &Val) {
736   unsigned long long n;
737   if (getAsUnsignedInteger(Scalar, 0, n))
738     return "invalid number";
739   if (n > 0xFFFFFFFFUL)
740     return "out of range number";
741   Val = n;
742   return StringRef();
743 }
744
745 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
746                                     raw_ostream &Out) {
747   Out << Val;
748 }
749
750 StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
751                                         uint64_t &Val) {
752   unsigned long long N;
753   if (getAsUnsignedInteger(Scalar, 0, N))
754     return "invalid number";
755   Val = N;
756   return StringRef();
757 }
758
759 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
760   // use temp in32_t because ostream thinks int8_t is a character
761   int32_t Num = Val;
762   Out << Num;
763 }
764
765 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
766   long long N;
767   if (getAsSignedInteger(Scalar, 0, N))
768     return "invalid number";
769   if ((N > 127) || (N < -128))
770     return "out of range number";
771   Val = N;
772   return StringRef();
773 }
774
775 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
776                                    raw_ostream &Out) {
777   Out << Val;
778 }
779
780 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
781   long long N;
782   if (getAsSignedInteger(Scalar, 0, N))
783     return "invalid number";
784   if ((N > INT16_MAX) || (N < INT16_MIN))
785     return "out of range number";
786   Val = N;
787   return StringRef();
788 }
789
790 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
791                                    raw_ostream &Out) {
792   Out << Val;
793 }
794
795 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
796   long long N;
797   if (getAsSignedInteger(Scalar, 0, N))
798     return "invalid number";
799   if ((N > INT32_MAX) || (N < INT32_MIN))
800     return "out of range number";
801   Val = N;
802   return StringRef();
803 }
804
805 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
806                                    raw_ostream &Out) {
807   Out << Val;
808 }
809
810 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
811   long long N;
812   if (getAsSignedInteger(Scalar, 0, N))
813     return "invalid number";
814   Val = N;
815   return StringRef();
816 }
817
818 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
819   Out << format("%g", Val);
820 }
821
822 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
823   SmallString<32> buff(Scalar.begin(), Scalar.end());
824   char *end;
825   Val = strtod(buff.c_str(), &end);
826   if (*end != '\0')
827     return "invalid floating point number";
828   return StringRef();
829 }
830
831 void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
832   Out << format("%g", Val);
833 }
834
835 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
836   SmallString<32> buff(Scalar.begin(), Scalar.end());
837   char *end;
838   Val = strtod(buff.c_str(), &end);
839   if (*end != '\0')
840     return "invalid floating point number";
841   return StringRef();
842 }
843
844 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
845   uint8_t Num = Val;
846   Out << format("0x%02X", Num);
847 }
848
849 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
850   unsigned long long n;
851   if (getAsUnsignedInteger(Scalar, 0, n))
852     return "invalid hex8 number";
853   if (n > 0xFF)
854     return "out of range hex8 number";
855   Val = n;
856   return StringRef();
857 }
858
859 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
860   uint16_t Num = Val;
861   Out << format("0x%04X", Num);
862 }
863
864 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
865   unsigned long long n;
866   if (getAsUnsignedInteger(Scalar, 0, n))
867     return "invalid hex16 number";
868   if (n > 0xFFFF)
869     return "out of range hex16 number";
870   Val = n;
871   return StringRef();
872 }
873
874 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
875   uint32_t Num = Val;
876   Out << format("0x%08X", Num);
877 }
878
879 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
880   unsigned long long n;
881   if (getAsUnsignedInteger(Scalar, 0, n))
882     return "invalid hex32 number";
883   if (n > 0xFFFFFFFFUL)
884     return "out of range hex32 number";
885   Val = n;
886   return StringRef();
887 }
888
889 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
890   uint64_t Num = Val;
891   Out << format("0x%016llX", Num);
892 }
893
894 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
895   unsigned long long Num;
896   if (getAsUnsignedInteger(Scalar, 0, Num))
897     return "invalid hex64 number";
898   Val = Num;
899   return StringRef();
900 }