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