168217381907fd851992c72d4585153bdee8f01c
[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.back() == inFlowSeq)) &&
638              (StateStack[StateStack.size() - 2] == inSeq)) {
639     --Indent;
640     OutputDash = true;
641   }
642
643   for (unsigned i = 0; i < Indent; ++i) {
644     output("  ");
645   }
646   if (OutputDash) {
647     output("- ");
648   }
649
650 }
651
652 void Output::paddedKey(StringRef key) {
653   output(key);
654   output(":");
655   const char *spaces = "                ";
656   if (key.size() < strlen(spaces))
657     output(&spaces[key.size()]);
658   else
659     output(" ");
660 }
661
662 //===----------------------------------------------------------------------===//
663 //  traits for built-in types
664 //===----------------------------------------------------------------------===//
665
666 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
667   Out << (Val ? "true" : "false");
668 }
669
670 StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
671   if (Scalar.equals("true")) {
672     Val = true;
673     return StringRef();
674   } else if (Scalar.equals("false")) {
675     Val = false;
676     return StringRef();
677   }
678   return "invalid boolean";
679 }
680
681 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
682                                      raw_ostream &Out) {
683   Out << Val;
684 }
685
686 StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
687                                          StringRef &Val) {
688   Val = Scalar;
689   return StringRef();
690 }
691
692 void ScalarTraits<std::string>::output(const std::string &Val, void *,
693                                      raw_ostream &Out) {
694   Out << Val;
695 }
696
697 StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
698                                          std::string &Val) {
699   Val = Scalar.str();
700   return StringRef();
701 }
702
703 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
704                                    raw_ostream &Out) {
705   // use temp uin32_t because ostream thinks uint8_t is a character
706   uint32_t Num = Val;
707   Out << Num;
708 }
709
710 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
711   unsigned long long n;
712   if (getAsUnsignedInteger(Scalar, 0, n))
713     return "invalid number";
714   if (n > 0xFF)
715     return "out of range number";
716   Val = n;
717   return StringRef();
718 }
719
720 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
721                                     raw_ostream &Out) {
722   Out << Val;
723 }
724
725 StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
726                                         uint16_t &Val) {
727   unsigned long long n;
728   if (getAsUnsignedInteger(Scalar, 0, n))
729     return "invalid number";
730   if (n > 0xFFFF)
731     return "out of range number";
732   Val = n;
733   return StringRef();
734 }
735
736 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
737                                     raw_ostream &Out) {
738   Out << Val;
739 }
740
741 StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
742                                         uint32_t &Val) {
743   unsigned long long n;
744   if (getAsUnsignedInteger(Scalar, 0, n))
745     return "invalid number";
746   if (n > 0xFFFFFFFFUL)
747     return "out of range number";
748   Val = n;
749   return StringRef();
750 }
751
752 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
753                                     raw_ostream &Out) {
754   Out << Val;
755 }
756
757 StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
758                                         uint64_t &Val) {
759   unsigned long long N;
760   if (getAsUnsignedInteger(Scalar, 0, N))
761     return "invalid number";
762   Val = N;
763   return StringRef();
764 }
765
766 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
767   // use temp in32_t because ostream thinks int8_t is a character
768   int32_t Num = Val;
769   Out << Num;
770 }
771
772 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
773   long long N;
774   if (getAsSignedInteger(Scalar, 0, N))
775     return "invalid number";
776   if ((N > 127) || (N < -128))
777     return "out of range number";
778   Val = N;
779   return StringRef();
780 }
781
782 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
783                                    raw_ostream &Out) {
784   Out << Val;
785 }
786
787 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
788   long long N;
789   if (getAsSignedInteger(Scalar, 0, N))
790     return "invalid number";
791   if ((N > INT16_MAX) || (N < INT16_MIN))
792     return "out of range number";
793   Val = N;
794   return StringRef();
795 }
796
797 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
798                                    raw_ostream &Out) {
799   Out << Val;
800 }
801
802 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
803   long long N;
804   if (getAsSignedInteger(Scalar, 0, N))
805     return "invalid number";
806   if ((N > INT32_MAX) || (N < INT32_MIN))
807     return "out of range number";
808   Val = N;
809   return StringRef();
810 }
811
812 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
813                                    raw_ostream &Out) {
814   Out << Val;
815 }
816
817 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
818   long long N;
819   if (getAsSignedInteger(Scalar, 0, N))
820     return "invalid number";
821   Val = N;
822   return StringRef();
823 }
824
825 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
826   Out << format("%g", Val);
827 }
828
829 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &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<float>::output(const float &Val, void *, raw_ostream &Out) {
839   Out << format("%g", Val);
840 }
841
842 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
843   SmallString<32> buff(Scalar.begin(), Scalar.end());
844   char *end;
845   Val = strtod(buff.c_str(), &end);
846   if (*end != '\0')
847     return "invalid floating point number";
848   return StringRef();
849 }
850
851 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
852   uint8_t Num = Val;
853   Out << format("0x%02X", Num);
854 }
855
856 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
857   unsigned long long n;
858   if (getAsUnsignedInteger(Scalar, 0, n))
859     return "invalid hex8 number";
860   if (n > 0xFF)
861     return "out of range hex8 number";
862   Val = n;
863   return StringRef();
864 }
865
866 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
867   uint16_t Num = Val;
868   Out << format("0x%04X", Num);
869 }
870
871 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
872   unsigned long long n;
873   if (getAsUnsignedInteger(Scalar, 0, n))
874     return "invalid hex16 number";
875   if (n > 0xFFFF)
876     return "out of range hex16 number";
877   Val = n;
878   return StringRef();
879 }
880
881 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
882   uint32_t Num = Val;
883   Out << format("0x%08X", Num);
884 }
885
886 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
887   unsigned long long n;
888   if (getAsUnsignedInteger(Scalar, 0, n))
889     return "invalid hex32 number";
890   if (n > 0xFFFFFFFFUL)
891     return "out of range hex32 number";
892   Val = n;
893   return StringRef();
894 }
895
896 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
897   uint64_t Num = Val;
898   Out << format("0x%016llX", Num);
899 }
900
901 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
902   unsigned long long Num;
903   if (getAsUnsignedInteger(Scalar, 0, Num))
904     return "invalid hex64 number";
905   Val = Num;
906   return StringRef();
907 }