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