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