[llvm-exegesis] [NFC] Fixing typo.
[llvm-complete.git] / lib / Support / YAMLTraits.cpp
blob4b5bf6ad30d36c68d65ebfd5a0317b3978126daa
1 //===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/YAMLTraits.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/Support/Casting.h"
16 #include "llvm/Support/Errc.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/LineIterator.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/Unicode.h"
22 #include "llvm/Support/YAMLParser.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include <algorithm>
25 #include <cassert>
26 #include <cstdint>
27 #include <cstdlib>
28 #include <cstring>
29 #include <string>
30 #include <vector>
32 using namespace llvm;
33 using namespace yaml;
35 //===----------------------------------------------------------------------===//
36 // IO
37 //===----------------------------------------------------------------------===//
39 IO::IO(void *Context) : Ctxt(Context) {}
41 IO::~IO() = default;
43 void *IO::getContext() {
44 return Ctxt;
47 void IO::setContext(void *Context) {
48 Ctxt = Context;
51 //===----------------------------------------------------------------------===//
52 // Input
53 //===----------------------------------------------------------------------===//
55 Input::Input(StringRef InputContent, void *Ctxt,
56 SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
57 : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
58 if (DiagHandler)
59 SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
60 DocIterator = Strm->begin();
63 Input::Input(MemoryBufferRef Input, void *Ctxt,
64 SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
65 : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
66 if (DiagHandler)
67 SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
68 DocIterator = Strm->begin();
71 Input::~Input() = default;
73 std::error_code Input::error() { return EC; }
75 // Pin the vtables to this file.
76 void Input::HNode::anchor() {}
77 void Input::EmptyHNode::anchor() {}
78 void Input::ScalarHNode::anchor() {}
79 void Input::MapHNode::anchor() {}
80 void Input::SequenceHNode::anchor() {}
82 bool Input::outputting() {
83 return false;
86 bool Input::setCurrentDocument() {
87 if (DocIterator != Strm->end()) {
88 Node *N = DocIterator->getRoot();
89 if (!N) {
90 assert(Strm->failed() && "Root is NULL iff parsing failed");
91 EC = make_error_code(errc::invalid_argument);
92 return false;
95 if (isa<NullNode>(N)) {
96 // Empty files are allowed and ignored
97 ++DocIterator;
98 return setCurrentDocument();
100 TopNode = createHNodes(N);
101 CurrentNode = TopNode.get();
102 return true;
104 return false;
107 bool Input::nextDocument() {
108 return ++DocIterator != Strm->end();
111 const Node *Input::getCurrentNode() const {
112 return CurrentNode ? CurrentNode->_node : nullptr;
115 bool Input::mapTag(StringRef Tag, bool Default) {
116 std::string foundTag = CurrentNode->_node->getVerbatimTag();
117 if (foundTag.empty()) {
118 // If no tag found and 'Tag' is the default, say it was found.
119 return Default;
121 // Return true iff found tag matches supplied tag.
122 return Tag.equals(foundTag);
125 void Input::beginMapping() {
126 if (EC)
127 return;
128 // CurrentNode can be null if the document is empty.
129 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
130 if (MN) {
131 MN->ValidKeys.clear();
135 std::vector<StringRef> Input::keys() {
136 MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
137 std::vector<StringRef> Ret;
138 if (!MN) {
139 setError(CurrentNode, "not a mapping");
140 return Ret;
142 for (auto &P : MN->Mapping)
143 Ret.push_back(P.first());
144 return Ret;
147 bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
148 void *&SaveInfo) {
149 UseDefault = false;
150 if (EC)
151 return false;
153 // CurrentNode is null for empty documents, which is an error in case required
154 // nodes are present.
155 if (!CurrentNode) {
156 if (Required)
157 EC = make_error_code(errc::invalid_argument);
158 return false;
161 MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
162 if (!MN) {
163 if (Required || !isa<EmptyHNode>(CurrentNode))
164 setError(CurrentNode, "not a mapping");
165 return false;
167 MN->ValidKeys.push_back(Key);
168 HNode *Value = MN->Mapping[Key].get();
169 if (!Value) {
170 if (Required)
171 setError(CurrentNode, Twine("missing required key '") + Key + "'");
172 else
173 UseDefault = true;
174 return false;
176 SaveInfo = CurrentNode;
177 CurrentNode = Value;
178 return true;
181 void Input::postflightKey(void *saveInfo) {
182 CurrentNode = reinterpret_cast<HNode *>(saveInfo);
185 void Input::endMapping() {
186 if (EC)
187 return;
188 // CurrentNode can be null if the document is empty.
189 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
190 if (!MN)
191 return;
192 for (const auto &NN : MN->Mapping) {
193 if (!is_contained(MN->ValidKeys, NN.first())) {
194 setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
195 break;
200 void Input::beginFlowMapping() { beginMapping(); }
202 void Input::endFlowMapping() { endMapping(); }
204 unsigned Input::beginSequence() {
205 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
206 return SQ->Entries.size();
207 if (isa<EmptyHNode>(CurrentNode))
208 return 0;
209 // Treat case where there's a scalar "null" value as an empty sequence.
210 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
211 if (isNull(SN->value()))
212 return 0;
214 // Any other type of HNode is an error.
215 setError(CurrentNode, "not a sequence");
216 return 0;
219 void Input::endSequence() {
222 bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
223 if (EC)
224 return false;
225 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
226 SaveInfo = CurrentNode;
227 CurrentNode = SQ->Entries[Index].get();
228 return true;
230 return false;
233 void Input::postflightElement(void *SaveInfo) {
234 CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
237 unsigned Input::beginFlowSequence() { return beginSequence(); }
239 bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
240 if (EC)
241 return false;
242 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
243 SaveInfo = CurrentNode;
244 CurrentNode = SQ->Entries[index].get();
245 return true;
247 return false;
250 void Input::postflightFlowElement(void *SaveInfo) {
251 CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
254 void Input::endFlowSequence() {
257 void Input::beginEnumScalar() {
258 ScalarMatchFound = false;
261 bool Input::matchEnumScalar(const char *Str, bool) {
262 if (ScalarMatchFound)
263 return false;
264 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
265 if (SN->value().equals(Str)) {
266 ScalarMatchFound = true;
267 return true;
270 return false;
273 bool Input::matchEnumFallback() {
274 if (ScalarMatchFound)
275 return false;
276 ScalarMatchFound = true;
277 return true;
280 void Input::endEnumScalar() {
281 if (!ScalarMatchFound) {
282 setError(CurrentNode, "unknown enumerated scalar");
286 bool Input::beginBitSetScalar(bool &DoClear) {
287 BitValuesUsed.clear();
288 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
289 BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
290 } else {
291 setError(CurrentNode, "expected sequence of bit values");
293 DoClear = true;
294 return true;
297 bool Input::bitSetMatch(const char *Str, bool) {
298 if (EC)
299 return false;
300 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
301 unsigned Index = 0;
302 for (auto &N : SQ->Entries) {
303 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
304 if (SN->value().equals(Str)) {
305 BitValuesUsed[Index] = true;
306 return true;
308 } else {
309 setError(CurrentNode, "unexpected scalar in sequence of bit values");
311 ++Index;
313 } else {
314 setError(CurrentNode, "expected sequence of bit values");
316 return false;
319 void Input::endBitSetScalar() {
320 if (EC)
321 return;
322 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
323 assert(BitValuesUsed.size() == SQ->Entries.size());
324 for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
325 if (!BitValuesUsed[i]) {
326 setError(SQ->Entries[i].get(), "unknown bit value");
327 return;
333 void Input::scalarString(StringRef &S, QuotingType) {
334 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
335 S = SN->value();
336 } else {
337 setError(CurrentNode, "unexpected scalar");
341 void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
343 void Input::scalarTag(std::string &Tag) {
344 Tag = CurrentNode->_node->getVerbatimTag();
347 void Input::setError(HNode *hnode, const Twine &message) {
348 assert(hnode && "HNode must not be NULL");
349 setError(hnode->_node, message);
352 NodeKind Input::getNodeKind() {
353 if (isa<ScalarHNode>(CurrentNode))
354 return NodeKind::Scalar;
355 else if (isa<MapHNode>(CurrentNode))
356 return NodeKind::Map;
357 else if (isa<SequenceHNode>(CurrentNode))
358 return NodeKind::Sequence;
359 llvm_unreachable("Unsupported node kind");
362 void Input::setError(Node *node, const Twine &message) {
363 Strm->printError(node, message);
364 EC = make_error_code(errc::invalid_argument);
367 std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
368 SmallString<128> StringStorage;
369 if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
370 StringRef KeyStr = SN->getValue(StringStorage);
371 if (!StringStorage.empty()) {
372 // Copy string to permanent storage
373 KeyStr = StringStorage.str().copy(StringAllocator);
375 return llvm::make_unique<ScalarHNode>(N, KeyStr);
376 } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
377 StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
378 return llvm::make_unique<ScalarHNode>(N, ValueCopy);
379 } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
380 auto SQHNode = llvm::make_unique<SequenceHNode>(N);
381 for (Node &SN : *SQ) {
382 auto Entry = createHNodes(&SN);
383 if (EC)
384 break;
385 SQHNode->Entries.push_back(std::move(Entry));
387 return std::move(SQHNode);
388 } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
389 auto mapHNode = llvm::make_unique<MapHNode>(N);
390 for (KeyValueNode &KVN : *Map) {
391 Node *KeyNode = KVN.getKey();
392 ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode);
393 Node *Value = KVN.getValue();
394 if (!Key || !Value) {
395 if (!Key)
396 setError(KeyNode, "Map key must be a scalar");
397 if (!Value)
398 setError(KeyNode, "Map value must not be empty");
399 break;
401 StringStorage.clear();
402 StringRef KeyStr = Key->getValue(StringStorage);
403 if (!StringStorage.empty()) {
404 // Copy string to permanent storage
405 KeyStr = StringStorage.str().copy(StringAllocator);
407 auto ValueHNode = createHNodes(Value);
408 if (EC)
409 break;
410 mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
412 return std::move(mapHNode);
413 } else if (isa<NullNode>(N)) {
414 return llvm::make_unique<EmptyHNode>(N);
415 } else {
416 setError(N, "unknown node kind");
417 return nullptr;
421 void Input::setError(const Twine &Message) {
422 setError(CurrentNode, Message);
425 bool Input::canElideEmptySequence() {
426 return false;
429 //===----------------------------------------------------------------------===//
430 // Output
431 //===----------------------------------------------------------------------===//
433 Output::Output(raw_ostream &yout, void *context, int WrapColumn)
434 : IO(context), Out(yout), WrapColumn(WrapColumn) {}
436 Output::~Output() = default;
438 bool Output::outputting() {
439 return true;
442 void Output::beginMapping() {
443 StateStack.push_back(inMapFirstKey);
444 NeedsNewLine = true;
447 bool Output::mapTag(StringRef Tag, bool Use) {
448 if (Use) {
449 // If this tag is being written inside a sequence we should write the start
450 // of the sequence before writing the tag, otherwise the tag won't be
451 // attached to the element in the sequence, but rather the sequence itself.
452 bool SequenceElement = false;
453 if (StateStack.size() > 1) {
454 auto &E = StateStack[StateStack.size() - 2];
455 SequenceElement = inSeqAnyElement(E) || inFlowSeqAnyElement(E);
457 if (SequenceElement && StateStack.back() == inMapFirstKey) {
458 newLineCheck();
459 } else {
460 output(" ");
462 output(Tag);
463 if (SequenceElement) {
464 // If we're writing the tag during the first element of a map, the tag
465 // takes the place of the first element in the sequence.
466 if (StateStack.back() == inMapFirstKey) {
467 StateStack.pop_back();
468 StateStack.push_back(inMapOtherKey);
470 // Tags inside maps in sequences should act as keys in the map from a
471 // formatting perspective, so we always want a newline in a sequence.
472 NeedsNewLine = true;
475 return Use;
478 void Output::endMapping() {
479 // If we did not map anything, we should explicitly emit an empty map
480 if (StateStack.back() == inMapFirstKey)
481 output("{}");
482 StateStack.pop_back();
485 std::vector<StringRef> Output::keys() {
486 report_fatal_error("invalid call");
489 bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
490 bool &UseDefault, void *&) {
491 UseDefault = false;
492 if (Required || !SameAsDefault || WriteDefaultValues) {
493 auto State = StateStack.back();
494 if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
495 flowKey(Key);
496 } else {
497 newLineCheck();
498 paddedKey(Key);
500 return true;
502 return false;
505 void Output::postflightKey(void *) {
506 if (StateStack.back() == inMapFirstKey) {
507 StateStack.pop_back();
508 StateStack.push_back(inMapOtherKey);
509 } else if (StateStack.back() == inFlowMapFirstKey) {
510 StateStack.pop_back();
511 StateStack.push_back(inFlowMapOtherKey);
515 void Output::beginFlowMapping() {
516 StateStack.push_back(inFlowMapFirstKey);
517 newLineCheck();
518 ColumnAtMapFlowStart = Column;
519 output("{ ");
522 void Output::endFlowMapping() {
523 StateStack.pop_back();
524 outputUpToEndOfLine(" }");
527 void Output::beginDocuments() {
528 outputUpToEndOfLine("---");
531 bool Output::preflightDocument(unsigned index) {
532 if (index > 0)
533 outputUpToEndOfLine("\n---");
534 return true;
537 void Output::postflightDocument() {
540 void Output::endDocuments() {
541 output("\n...\n");
544 unsigned Output::beginSequence() {
545 StateStack.push_back(inSeqFirstElement);
546 NeedsNewLine = true;
547 return 0;
550 void Output::endSequence() {
551 // If we did not emit anything, we should explicitly emit an empty sequence
552 if (StateStack.back() == inSeqFirstElement)
553 output("[]");
554 StateStack.pop_back();
557 bool Output::preflightElement(unsigned, void *&) {
558 return true;
561 void Output::postflightElement(void *) {
562 if (StateStack.back() == inSeqFirstElement) {
563 StateStack.pop_back();
564 StateStack.push_back(inSeqOtherElement);
565 } else if (StateStack.back() == inFlowSeqFirstElement) {
566 StateStack.pop_back();
567 StateStack.push_back(inFlowSeqOtherElement);
571 unsigned Output::beginFlowSequence() {
572 StateStack.push_back(inFlowSeqFirstElement);
573 newLineCheck();
574 ColumnAtFlowStart = Column;
575 output("[ ");
576 NeedFlowSequenceComma = false;
577 return 0;
580 void Output::endFlowSequence() {
581 StateStack.pop_back();
582 outputUpToEndOfLine(" ]");
585 bool Output::preflightFlowElement(unsigned, void *&) {
586 if (NeedFlowSequenceComma)
587 output(", ");
588 if (WrapColumn && Column > WrapColumn) {
589 output("\n");
590 for (int i = 0; i < ColumnAtFlowStart; ++i)
591 output(" ");
592 Column = ColumnAtFlowStart;
593 output(" ");
595 return true;
598 void Output::postflightFlowElement(void *) {
599 NeedFlowSequenceComma = true;
602 void Output::beginEnumScalar() {
603 EnumerationMatchFound = false;
606 bool Output::matchEnumScalar(const char *Str, bool Match) {
607 if (Match && !EnumerationMatchFound) {
608 newLineCheck();
609 outputUpToEndOfLine(Str);
610 EnumerationMatchFound = true;
612 return false;
615 bool Output::matchEnumFallback() {
616 if (EnumerationMatchFound)
617 return false;
618 EnumerationMatchFound = true;
619 return true;
622 void Output::endEnumScalar() {
623 if (!EnumerationMatchFound)
624 llvm_unreachable("bad runtime enum value");
627 bool Output::beginBitSetScalar(bool &DoClear) {
628 newLineCheck();
629 output("[ ");
630 NeedBitValueComma = false;
631 DoClear = false;
632 return true;
635 bool Output::bitSetMatch(const char *Str, bool Matches) {
636 if (Matches) {
637 if (NeedBitValueComma)
638 output(", ");
639 output(Str);
640 NeedBitValueComma = true;
642 return false;
645 void Output::endBitSetScalar() {
646 outputUpToEndOfLine(" ]");
649 void Output::scalarString(StringRef &S, QuotingType MustQuote) {
650 newLineCheck();
651 if (S.empty()) {
652 // Print '' for the empty string because leaving the field empty is not
653 // allowed.
654 outputUpToEndOfLine("''");
655 return;
657 if (MustQuote == QuotingType::None) {
658 // Only quote if we must.
659 outputUpToEndOfLine(S);
660 return;
663 unsigned i = 0;
664 unsigned j = 0;
665 unsigned End = S.size();
666 const char *Base = S.data();
668 const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
669 output(Quote); // Starting quote.
671 // When using double-quoted strings (and only in that case), non-printable characters may be
672 // present, and will be escaped using a variety of unicode-scalar and special short-form
673 // escapes. This is handled in yaml::escape.
674 if (MustQuote == QuotingType::Double) {
675 output(yaml::escape(Base, /* EscapePrintable= */ false));
676 outputUpToEndOfLine(Quote);
677 return;
680 // When using single-quoted strings, any single quote ' must be doubled to be escaped.
681 while (j < End) {
682 if (S[j] == '\'') { // Escape quotes.
683 output(StringRef(&Base[i], j - i)); // "flush".
684 output(StringLiteral("''")); // Print it as ''
685 i = j + 1;
687 ++j;
689 output(StringRef(&Base[i], j - i));
690 outputUpToEndOfLine(Quote); // Ending quote.
693 void Output::blockScalarString(StringRef &S) {
694 if (!StateStack.empty())
695 newLineCheck();
696 output(" |");
697 outputNewLine();
699 unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
701 auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
702 for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
703 for (unsigned I = 0; I < Indent; ++I) {
704 output(" ");
706 output(*Lines);
707 outputNewLine();
711 void Output::scalarTag(std::string &Tag) {
712 if (Tag.empty())
713 return;
714 newLineCheck();
715 output(Tag);
716 output(" ");
719 void Output::setError(const Twine &message) {
722 bool Output::canElideEmptySequence() {
723 // Normally, with an optional key/value where the value is an empty sequence,
724 // the whole key/value can be not written. But, that produces wrong yaml
725 // if the key/value is the only thing in the map and the map is used in
726 // a sequence. This detects if the this sequence is the first key/value
727 // in map that itself is embedded in a sequnce.
728 if (StateStack.size() < 2)
729 return true;
730 if (StateStack.back() != inMapFirstKey)
731 return true;
732 return !inSeqAnyElement(StateStack[StateStack.size() - 2]);
735 void Output::output(StringRef s) {
736 Column += s.size();
737 Out << s;
740 void Output::outputUpToEndOfLine(StringRef s) {
741 output(s);
742 if (StateStack.empty() || (!inFlowSeqAnyElement(StateStack.back()) &&
743 !inFlowMapAnyKey(StateStack.back())))
744 NeedsNewLine = true;
747 void Output::outputNewLine() {
748 Out << "\n";
749 Column = 0;
752 // if seq at top, indent as if map, then add "- "
753 // if seq in middle, use "- " if firstKey, else use " "
756 void Output::newLineCheck() {
757 if (!NeedsNewLine)
758 return;
759 NeedsNewLine = false;
761 outputNewLine();
763 if (StateStack.size() == 0)
764 return;
766 unsigned Indent = StateStack.size() - 1;
767 bool OutputDash = false;
769 if (StateStack.back() == inSeqFirstElement ||
770 StateStack.back() == inSeqOtherElement) {
771 OutputDash = true;
772 } else if ((StateStack.size() > 1) &&
773 ((StateStack.back() == inMapFirstKey) ||
774 inFlowSeqAnyElement(StateStack.back()) ||
775 (StateStack.back() == inFlowMapFirstKey)) &&
776 inSeqAnyElement(StateStack[StateStack.size() - 2])) {
777 --Indent;
778 OutputDash = true;
781 for (unsigned i = 0; i < Indent; ++i) {
782 output(" ");
784 if (OutputDash) {
785 output("- ");
790 void Output::paddedKey(StringRef key) {
791 output(key);
792 output(":");
793 const char *spaces = " ";
794 if (key.size() < strlen(spaces))
795 output(&spaces[key.size()]);
796 else
797 output(" ");
800 void Output::flowKey(StringRef Key) {
801 if (StateStack.back() == inFlowMapOtherKey)
802 output(", ");
803 if (WrapColumn && Column > WrapColumn) {
804 output("\n");
805 for (int I = 0; I < ColumnAtMapFlowStart; ++I)
806 output(" ");
807 Column = ColumnAtMapFlowStart;
808 output(" ");
810 output(Key);
811 output(": ");
814 NodeKind Output::getNodeKind() { report_fatal_error("invalid call"); }
816 bool Output::inSeqAnyElement(InState State) {
817 return State == inSeqFirstElement || State == inSeqOtherElement;
820 bool Output::inFlowSeqAnyElement(InState State) {
821 return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement;
824 bool Output::inMapAnyKey(InState State) {
825 return State == inMapFirstKey || State == inMapOtherKey;
828 bool Output::inFlowMapAnyKey(InState State) {
829 return State == inFlowMapFirstKey || State == inFlowMapOtherKey;
832 //===----------------------------------------------------------------------===//
833 // traits for built-in types
834 //===----------------------------------------------------------------------===//
836 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
837 Out << (Val ? "true" : "false");
840 StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
841 if (Scalar.equals("true")) {
842 Val = true;
843 return StringRef();
844 } else if (Scalar.equals("false")) {
845 Val = false;
846 return StringRef();
848 return "invalid boolean";
851 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
852 raw_ostream &Out) {
853 Out << Val;
856 StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
857 StringRef &Val) {
858 Val = Scalar;
859 return StringRef();
862 void ScalarTraits<std::string>::output(const std::string &Val, void *,
863 raw_ostream &Out) {
864 Out << Val;
867 StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
868 std::string &Val) {
869 Val = Scalar.str();
870 return StringRef();
873 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
874 raw_ostream &Out) {
875 // use temp uin32_t because ostream thinks uint8_t is a character
876 uint32_t Num = Val;
877 Out << Num;
880 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
881 unsigned long long n;
882 if (getAsUnsignedInteger(Scalar, 0, n))
883 return "invalid number";
884 if (n > 0xFF)
885 return "out of range number";
886 Val = n;
887 return StringRef();
890 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
891 raw_ostream &Out) {
892 Out << Val;
895 StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
896 uint16_t &Val) {
897 unsigned long long n;
898 if (getAsUnsignedInteger(Scalar, 0, n))
899 return "invalid number";
900 if (n > 0xFFFF)
901 return "out of range number";
902 Val = n;
903 return StringRef();
906 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
907 raw_ostream &Out) {
908 Out << Val;
911 StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
912 uint32_t &Val) {
913 unsigned long long n;
914 if (getAsUnsignedInteger(Scalar, 0, n))
915 return "invalid number";
916 if (n > 0xFFFFFFFFUL)
917 return "out of range number";
918 Val = n;
919 return StringRef();
922 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
923 raw_ostream &Out) {
924 Out << Val;
927 StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
928 uint64_t &Val) {
929 unsigned long long N;
930 if (getAsUnsignedInteger(Scalar, 0, N))
931 return "invalid number";
932 Val = N;
933 return StringRef();
936 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
937 // use temp in32_t because ostream thinks int8_t is a character
938 int32_t Num = Val;
939 Out << Num;
942 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
943 long long N;
944 if (getAsSignedInteger(Scalar, 0, N))
945 return "invalid number";
946 if ((N > 127) || (N < -128))
947 return "out of range number";
948 Val = N;
949 return StringRef();
952 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
953 raw_ostream &Out) {
954 Out << Val;
957 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
958 long long N;
959 if (getAsSignedInteger(Scalar, 0, N))
960 return "invalid number";
961 if ((N > INT16_MAX) || (N < INT16_MIN))
962 return "out of range number";
963 Val = N;
964 return StringRef();
967 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
968 raw_ostream &Out) {
969 Out << Val;
972 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
973 long long N;
974 if (getAsSignedInteger(Scalar, 0, N))
975 return "invalid number";
976 if ((N > INT32_MAX) || (N < INT32_MIN))
977 return "out of range number";
978 Val = N;
979 return StringRef();
982 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
983 raw_ostream &Out) {
984 Out << Val;
987 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
988 long long N;
989 if (getAsSignedInteger(Scalar, 0, N))
990 return "invalid number";
991 Val = N;
992 return StringRef();
995 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
996 Out << format("%g", Val);
999 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
1000 if (to_float(Scalar, Val))
1001 return StringRef();
1002 return "invalid floating point number";
1005 void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
1006 Out << format("%g", Val);
1009 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
1010 if (to_float(Scalar, Val))
1011 return StringRef();
1012 return "invalid floating point number";
1015 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
1016 uint8_t Num = Val;
1017 Out << format("0x%02X", Num);
1020 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
1021 unsigned long long n;
1022 if (getAsUnsignedInteger(Scalar, 0, n))
1023 return "invalid hex8 number";
1024 if (n > 0xFF)
1025 return "out of range hex8 number";
1026 Val = n;
1027 return StringRef();
1030 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
1031 uint16_t Num = Val;
1032 Out << format("0x%04X", Num);
1035 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
1036 unsigned long long n;
1037 if (getAsUnsignedInteger(Scalar, 0, n))
1038 return "invalid hex16 number";
1039 if (n > 0xFFFF)
1040 return "out of range hex16 number";
1041 Val = n;
1042 return StringRef();
1045 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
1046 uint32_t Num = Val;
1047 Out << format("0x%08X", Num);
1050 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
1051 unsigned long long n;
1052 if (getAsUnsignedInteger(Scalar, 0, n))
1053 return "invalid hex32 number";
1054 if (n > 0xFFFFFFFFUL)
1055 return "out of range hex32 number";
1056 Val = n;
1057 return StringRef();
1060 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
1061 uint64_t Num = Val;
1062 Out << format("0x%016llX", Num);
1065 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
1066 unsigned long long Num;
1067 if (getAsUnsignedInteger(Scalar, 0, Num))
1068 return "invalid hex64 number";
1069 Val = Num;
1070 return StringRef();