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