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