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