[stack protector] Make the StackProtector pass respect ssp-buffer-size.
[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, bool) {
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, bool MustQuote) {
545   this->newLineCheck();
546   if (S.empty()) {
547     // Print '' for the empty string because leaving the field empty is not
548     // allowed.
549     this->outputUpToEndOfLine("''");
550     return;
551   }
552   if (!MustQuote) {
553     // Only quote if we must.
554     this->outputUpToEndOfLine(S);
555     return;
556   }
557   unsigned i = 0;
558   unsigned j = 0;
559   unsigned End = S.size();
560   output("'"); // Starting single quote.
561   const char *Base = S.data();
562   while (j < End) {
563     // Escape a single quote by doubling it.
564     if (S[j] == '\'') {
565       output(StringRef(&Base[i], j - i + 1));
566       output("'");
567       i = j + 1;
568     }
569     ++j;
570   }
571   output(StringRef(&Base[i], j - i));
572   this->outputUpToEndOfLine("'"); // Ending single quote.
573 }
574
575 void Output::setError(const Twine &message) {
576 }
577
578 bool Output::canElideEmptySequence() {
579   // Normally, with an optional key/value where the value is an empty sequence,
580   // the whole key/value can be not written.  But, that produces wrong yaml
581   // if the key/value is the only thing in the map and the map is used in
582   // a sequence.  This detects if the this sequence is the first key/value
583   // in map that itself is embedded in a sequnce.
584   if (StateStack.size() < 2)
585     return true;
586   if (StateStack.back() != inMapFirstKey)
587     return true;
588   return (StateStack[StateStack.size()-2] != inSeq);
589 }
590
591 void Output::output(StringRef s) {
592   Column += s.size();
593   Out << s;
594 }
595
596 void Output::outputUpToEndOfLine(StringRef s) {
597   this->output(s);
598   if (StateStack.empty() || StateStack.back() != inFlowSeq)
599     NeedsNewLine = true;
600 }
601
602 void Output::outputNewLine() {
603   Out << "\n";
604   Column = 0;
605 }
606
607 // if seq at top, indent as if map, then add "- "
608 // if seq in middle, use "- " if firstKey, else use "  "
609 //
610
611 void Output::newLineCheck() {
612   if (!NeedsNewLine)
613     return;
614   NeedsNewLine = false;
615
616   this->outputNewLine();
617
618   assert(StateStack.size() > 0);
619   unsigned Indent = StateStack.size() - 1;
620   bool OutputDash = false;
621
622   if (StateStack.back() == inSeq) {
623     OutputDash = true;
624   } else if ((StateStack.size() > 1) && (StateStack.back() == inMapFirstKey) &&
625              (StateStack[StateStack.size() - 2] == inSeq)) {
626     --Indent;
627     OutputDash = true;
628   }
629
630   for (unsigned i = 0; i < Indent; ++i) {
631     output("  ");
632   }
633   if (OutputDash) {
634     output("- ");
635   }
636
637 }
638
639 void Output::paddedKey(StringRef key) {
640   output(key);
641   output(":");
642   const char *spaces = "                ";
643   if (key.size() < strlen(spaces))
644     output(&spaces[key.size()]);
645   else
646     output(" ");
647 }
648
649 //===----------------------------------------------------------------------===//
650 //  traits for built-in types
651 //===----------------------------------------------------------------------===//
652
653 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
654   Out << (Val ? "true" : "false");
655 }
656
657 StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
658   if (Scalar.equals("true")) {
659     Val = true;
660     return StringRef();
661   } else if (Scalar.equals("false")) {
662     Val = false;
663     return StringRef();
664   }
665   return "invalid boolean";
666 }
667
668 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
669                                      raw_ostream &Out) {
670   Out << Val;
671 }
672
673 StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
674                                          StringRef &Val) {
675   Val = Scalar;
676   return StringRef();
677 }
678  
679 void ScalarTraits<std::string>::output(const std::string &Val, void *,
680                                      raw_ostream &Out) {
681   Out << Val;
682 }
683
684 StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
685                                          std::string &Val) {
686   Val = Scalar.str();
687   return StringRef();
688 }
689
690 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
691                                    raw_ostream &Out) {
692   // use temp uin32_t because ostream thinks uint8_t is a character
693   uint32_t Num = Val;
694   Out << Num;
695 }
696
697 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
698   unsigned long long n;
699   if (getAsUnsignedInteger(Scalar, 0, n))
700     return "invalid number";
701   if (n > 0xFF)
702     return "out of range number";
703   Val = n;
704   return StringRef();
705 }
706
707 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
708                                     raw_ostream &Out) {
709   Out << Val;
710 }
711
712 StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
713                                         uint16_t &Val) {
714   unsigned long long n;
715   if (getAsUnsignedInteger(Scalar, 0, n))
716     return "invalid number";
717   if (n > 0xFFFF)
718     return "out of range number";
719   Val = n;
720   return StringRef();
721 }
722
723 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
724                                     raw_ostream &Out) {
725   Out << Val;
726 }
727
728 StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
729                                         uint32_t &Val) {
730   unsigned long long n;
731   if (getAsUnsignedInteger(Scalar, 0, n))
732     return "invalid number";
733   if (n > 0xFFFFFFFFUL)
734     return "out of range number";
735   Val = n;
736   return StringRef();
737 }
738
739 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
740                                     raw_ostream &Out) {
741   Out << Val;
742 }
743
744 StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
745                                         uint64_t &Val) {
746   unsigned long long N;
747   if (getAsUnsignedInteger(Scalar, 0, N))
748     return "invalid number";
749   Val = N;
750   return StringRef();
751 }
752
753 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
754   // use temp in32_t because ostream thinks int8_t is a character
755   int32_t Num = Val;
756   Out << Num;
757 }
758
759 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
760   long long N;
761   if (getAsSignedInteger(Scalar, 0, N))
762     return "invalid number";
763   if ((N > 127) || (N < -128))
764     return "out of range number";
765   Val = N;
766   return StringRef();
767 }
768
769 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
770                                    raw_ostream &Out) {
771   Out << Val;
772 }
773
774 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
775   long long N;
776   if (getAsSignedInteger(Scalar, 0, N))
777     return "invalid number";
778   if ((N > INT16_MAX) || (N < INT16_MIN))
779     return "out of range number";
780   Val = N;
781   return StringRef();
782 }
783
784 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
785                                    raw_ostream &Out) {
786   Out << Val;
787 }
788
789 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
790   long long N;
791   if (getAsSignedInteger(Scalar, 0, N))
792     return "invalid number";
793   if ((N > INT32_MAX) || (N < INT32_MIN))
794     return "out of range number";
795   Val = N;
796   return StringRef();
797 }
798
799 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
800                                    raw_ostream &Out) {
801   Out << Val;
802 }
803
804 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
805   long long N;
806   if (getAsSignedInteger(Scalar, 0, N))
807     return "invalid number";
808   Val = N;
809   return StringRef();
810 }
811
812 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
813   Out << format("%g", Val);
814 }
815
816 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
817   SmallString<32> buff(Scalar.begin(), Scalar.end());
818   char *end;
819   Val = strtod(buff.c_str(), &end);
820   if (*end != '\0')
821     return "invalid floating point number";
822   return StringRef();
823 }
824
825 void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
826   Out << format("%g", Val);
827 }
828
829 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
830   SmallString<32> buff(Scalar.begin(), Scalar.end());
831   char *end;
832   Val = strtod(buff.c_str(), &end);
833   if (*end != '\0')
834     return "invalid floating point number";
835   return StringRef();
836 }
837
838 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
839   uint8_t Num = Val;
840   Out << format("0x%02X", Num);
841 }
842
843 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
844   unsigned long long n;
845   if (getAsUnsignedInteger(Scalar, 0, n))
846     return "invalid hex8 number";
847   if (n > 0xFF)
848     return "out of range hex8 number";
849   Val = n;
850   return StringRef();
851 }
852
853 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
854   uint16_t Num = Val;
855   Out << format("0x%04X", Num);
856 }
857
858 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
859   unsigned long long n;
860   if (getAsUnsignedInteger(Scalar, 0, n))
861     return "invalid hex16 number";
862   if (n > 0xFFFF)
863     return "out of range hex16 number";
864   Val = n;
865   return StringRef();
866 }
867
868 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
869   uint32_t Num = Val;
870   Out << format("0x%08X", Num);
871 }
872
873 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
874   unsigned long long n;
875   if (getAsUnsignedInteger(Scalar, 0, n))
876     return "invalid hex32 number";
877   if (n > 0xFFFFFFFFUL)
878     return "out of range hex32 number";
879   Val = n;
880   return StringRef();
881 }
882
883 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
884   uint64_t Num = Val;
885   Out << format("0x%016llX", Num);
886 }
887
888 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
889   unsigned long long Num;
890   if (getAsUnsignedInteger(Scalar, 0, Num))
891     return "invalid hex64 number";
892   Val = Num;
893   return StringRef();
894 }