40 IO::IO(
void *
Context) : Ctxt(Context) {}
44 void *IO::getContext() {
48 void IO::setContext(
void *
Context) {
56 Input::Input(
StringRef InputContent,
void *Ctxt,
61 DocIterator = Strm->begin();
69 DocIterator = Strm->begin();
72 Input::~Input() =
default;
77 void Input::HNode::anchor() {}
78 void Input::EmptyHNode::anchor() {}
79 void Input::ScalarHNode::anchor() {}
80 void Input::MapHNode::anchor() {}
81 void Input::SequenceHNode::anchor() {}
83 bool Input::outputting() {
87 bool Input::setCurrentDocument() {
88 if (DocIterator != Strm->end()) {
89 Node *
N = DocIterator->getRoot();
91 assert(Strm->failed() &&
"Root is NULL iff parsing failed");
96 if (isa<NullNode>(N)) {
99 return setCurrentDocument();
101 TopNode = createHNodes(N);
102 CurrentNode = TopNode.get();
108 bool Input::nextDocument() {
109 return ++DocIterator != Strm->end();
112 const Node *Input::getCurrentNode()
const {
113 return CurrentNode ? CurrentNode->_node :
nullptr;
116 bool Input::mapTag(
StringRef Tag,
bool Default) {
118 if (foundTag.empty()) {
123 return Tag.
equals(foundTag);
126 void Input::beginMapping() {
130 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
132 MN->ValidKeys.clear();
136 std::vector<StringRef> Input::keys() {
137 MapHNode *MN =
dyn_cast<MapHNode>(CurrentNode);
138 std::vector<StringRef>
Ret;
140 setError(CurrentNode,
"not a mapping");
143 for (
auto &
P : MN->Mapping)
144 Ret.push_back(
P.first());
148 bool Input::preflightKey(
const char *
Key,
bool Required,
bool,
bool &UseDefault,
162 MapHNode *MN =
dyn_cast<MapHNode>(CurrentNode);
164 if (Required || !isa<EmptyHNode>(CurrentNode))
165 setError(CurrentNode,
"not a mapping");
168 MN->ValidKeys.push_back(Key);
169 HNode *
Value = MN->Mapping[
Key].get();
172 setError(CurrentNode,
Twine(
"missing required key '") + Key +
"'");
177 SaveInfo = CurrentNode;
182 void Input::postflightKey(
void *saveInfo) {
183 CurrentNode =
reinterpret_cast<HNode *
>(saveInfo);
186 void Input::endMapping() {
190 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
193 for (
const auto &NN : MN->Mapping) {
195 setError(NN.second.get(),
Twine(
"unknown key '") + NN.first() +
"'");
201 void Input::beginFlowMapping() { beginMapping(); }
203 void Input::endFlowMapping() { endMapping(); }
205 unsigned Input::beginSequence() {
206 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
207 return SQ->Entries.size();
208 if (isa<EmptyHNode>(CurrentNode))
211 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
212 if (isNull(SN->value()))
216 setError(CurrentNode,
"not a sequence");
220 void Input::endSequence() {
223 bool Input::preflightElement(
unsigned Index,
void *&SaveInfo) {
226 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
227 SaveInfo = CurrentNode;
228 CurrentNode = SQ->Entries[
Index].get();
234 void Input::postflightElement(
void *SaveInfo) {
235 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
238 unsigned Input::beginFlowSequence() {
return beginSequence(); }
240 bool Input::preflightFlowElement(
unsigned index,
void *&SaveInfo) {
243 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
244 SaveInfo = CurrentNode;
245 CurrentNode = SQ->Entries[index].get();
251 void Input::postflightFlowElement(
void *SaveInfo) {
252 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
255 void Input::endFlowSequence() {
258 void Input::beginEnumScalar() {
259 ScalarMatchFound =
false;
262 bool Input::matchEnumScalar(
const char *Str,
bool) {
263 if (ScalarMatchFound)
265 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
266 if (SN->value().equals(Str)) {
267 ScalarMatchFound =
true;
274 bool Input::matchEnumFallback() {
275 if (ScalarMatchFound)
277 ScalarMatchFound =
true;
281 void Input::endEnumScalar() {
282 if (!ScalarMatchFound) {
283 setError(CurrentNode,
"unknown enumerated scalar");
287 bool Input::beginBitSetScalar(
bool &DoClear) {
288 BitValuesUsed.clear();
289 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
290 BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(),
false);
292 setError(CurrentNode,
"expected sequence of bit values");
298 bool Input::bitSetMatch(
const char *Str,
bool) {
301 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
303 for (
auto &N : SQ->Entries) {
304 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
305 if (SN->value().equals(Str)) {
306 BitValuesUsed[
Index] =
true;
310 setError(CurrentNode,
"unexpected scalar in sequence of bit values");
315 setError(CurrentNode,
"expected sequence of bit values");
320 void Input::endBitSetScalar() {
323 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
324 assert(BitValuesUsed.size() == SQ->Entries.size());
325 for (
unsigned i = 0; i < SQ->Entries.size(); ++i) {
326 if (!BitValuesUsed[i]) {
327 setError(SQ->Entries[i].get(),
"unknown bit value");
334 void Input::scalarString(
StringRef &S, QuotingType) {
335 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
338 setError(CurrentNode,
"unexpected scalar");
344 void Input::scalarTag(std::string &Tag) {
345 Tag = CurrentNode->_node->getVerbatimTag();
348 void Input::setError(HNode *hnode,
const Twine &message) {
349 assert(hnode &&
"HNode must not be NULL");
350 setError(hnode->_node, message);
354 if (isa<ScalarHNode>(CurrentNode))
356 else if (isa<MapHNode>(CurrentNode))
357 return NodeKind::Map;
358 else if (isa<SequenceHNode>(CurrentNode))
363 void Input::setError(
Node *node,
const Twine &message) {
364 Strm->printError(node, message);
368 std::unique_ptr<Input::HNode> Input::createHNodes(
Node *N) {
370 if (
ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
371 StringRef KeyStr = SN->getValue(StringStorage);
372 if (!StringStorage.
empty()) {
374 KeyStr = StringStorage.
str().
copy(StringAllocator);
376 return llvm::make_unique<ScalarHNode>(
N, KeyStr);
379 return llvm::make_unique<ScalarHNode>(
N, ValueCopy);
380 }
else if (
SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
381 auto SQHNode = llvm::make_unique<SequenceHNode>(
N);
382 for (
Node &SN : *SQ) {
383 auto Entry = createHNodes(&SN);
386 SQHNode->Entries.push_back(std::move(Entry));
388 return std::move(SQHNode);
389 }
else if (
MappingNode *Map = dyn_cast<MappingNode>(N)) {
390 auto mapHNode = llvm::make_unique<MapHNode>(
N);
392 Node *KeyNode = KVN.getKey();
394 Node *Value = KVN.getValue();
395 if (!Key || !Value) {
397 setError(KeyNode,
"Map key must be a scalar");
399 setError(KeyNode,
"Map value must not be empty");
402 StringStorage.
clear();
404 if (!StringStorage.
empty()) {
406 KeyStr = StringStorage.
str().
copy(StringAllocator);
408 auto ValueHNode = createHNodes(Value);
411 mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
413 return std::move(mapHNode);
414 }
else if (isa<NullNode>(N)) {
415 return llvm::make_unique<EmptyHNode>(
N);
417 setError(N,
"unknown node kind");
422 void Input::setError(
const Twine &Message) {
423 setError(CurrentNode, Message);
426 bool Input::canElideEmptySequence() {
434 Output::Output(
raw_ostream &yout,
void *context,
int WrapColumn)
435 : IO(context), Out(yout), WrapColumn(WrapColumn) {}
437 Output::~Output() =
default;
439 bool Output::outputting() {
443 void Output::beginMapping() {
444 StateStack.push_back(inMapFirstKey);
453 bool SequenceElement =
false;
454 if (StateStack.size() > 1) {
455 auto &
E = StateStack[StateStack.size() - 2];
456 SequenceElement = inSeqAnyElement(
E) || inFlowSeqAnyElement(
E);
458 if (SequenceElement && StateStack.back() == inMapFirstKey) {
464 if (SequenceElement) {
467 if (StateStack.back() == inMapFirstKey) {
468 StateStack.pop_back();
469 StateStack.push_back(inMapOtherKey);
479 void Output::endMapping() {
481 if (StateStack.back() == inMapFirstKey)
483 StateStack.pop_back();
486 std::vector<StringRef> Output::keys() {
490 bool Output::preflightKey(
const char *Key,
bool Required,
bool SameAsDefault,
491 bool &UseDefault,
void *&) {
493 if (Required || !SameAsDefault || WriteDefaultValues) {
494 auto State = StateStack.back();
495 if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
506 void Output::postflightKey(
void *) {
507 if (StateStack.back() == inMapFirstKey) {
508 StateStack.pop_back();
509 StateStack.push_back(inMapOtherKey);
510 }
else if (StateStack.back() == inFlowMapFirstKey) {
511 StateStack.pop_back();
512 StateStack.push_back(inFlowMapOtherKey);
516 void Output::beginFlowMapping() {
517 StateStack.push_back(inFlowMapFirstKey);
519 ColumnAtMapFlowStart = Column;
523 void Output::endFlowMapping() {
524 StateStack.pop_back();
525 outputUpToEndOfLine(
" }");
528 void Output::beginDocuments() {
529 outputUpToEndOfLine(
"---");
532 bool Output::preflightDocument(
unsigned index) {
534 outputUpToEndOfLine(
"\n---");
538 void Output::postflightDocument() {
541 void Output::endDocuments() {
545 unsigned Output::beginSequence() {
546 StateStack.push_back(inSeqFirstElement);
551 void Output::endSequence() {
553 if (StateStack.back() == inSeqFirstElement)
555 StateStack.pop_back();
558 bool Output::preflightElement(
unsigned,
void *&) {
562 void Output::postflightElement(
void *) {
563 if (StateStack.back() == inSeqFirstElement) {
564 StateStack.pop_back();
565 StateStack.push_back(inSeqOtherElement);
566 }
else if (StateStack.back() == inFlowSeqFirstElement) {
567 StateStack.pop_back();
568 StateStack.push_back(inFlowSeqOtherElement);
572 unsigned Output::beginFlowSequence() {
573 StateStack.push_back(inFlowSeqFirstElement);
575 ColumnAtFlowStart = Column;
577 NeedFlowSequenceComma =
false;
581 void Output::endFlowSequence() {
582 StateStack.pop_back();
583 outputUpToEndOfLine(
" ]");
586 bool Output::preflightFlowElement(
unsigned,
void *&) {
587 if (NeedFlowSequenceComma)
589 if (WrapColumn && Column > WrapColumn) {
591 for (
int i = 0; i < ColumnAtFlowStart; ++i)
593 Column = ColumnAtFlowStart;
599 void Output::postflightFlowElement(
void *) {
600 NeedFlowSequenceComma =
true;
603 void Output::beginEnumScalar() {
604 EnumerationMatchFound =
false;
607 bool Output::matchEnumScalar(
const char *Str,
bool Match) {
608 if (Match && !EnumerationMatchFound) {
610 outputUpToEndOfLine(Str);
611 EnumerationMatchFound =
true;
616 bool Output::matchEnumFallback() {
617 if (EnumerationMatchFound)
619 EnumerationMatchFound =
true;
623 void Output::endEnumScalar() {
624 if (!EnumerationMatchFound)
628 bool Output::beginBitSetScalar(
bool &DoClear) {
631 NeedBitValueComma =
false;
636 bool Output::bitSetMatch(
const char *Str,
bool Matches) {
638 if (NeedBitValueComma)
641 NeedBitValueComma =
true;
646 void Output::endBitSetScalar() {
647 outputUpToEndOfLine(
" ]");
650 void Output::scalarString(
StringRef &S, QuotingType MustQuote) {
655 outputUpToEndOfLine(
"''");
660 outputUpToEndOfLine(S);
666 unsigned End = S.
size();
677 outputUpToEndOfLine(Quote);
691 outputUpToEndOfLine(Quote);
694 void Output::blockScalarString(
StringRef &S) {
695 if (!StateStack.empty())
700 unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
712 void Output::scalarTag(std::string &Tag) {
720 void Output::setError(
const Twine &message) {
723 bool Output::canElideEmptySequence() {
729 if (StateStack.size() < 2)
731 if (StateStack.back() != inMapFirstKey)
733 return !inSeqAnyElement(StateStack[StateStack.size() - 2]);
741 void Output::outputUpToEndOfLine(
StringRef s) {
743 if (StateStack.empty() || (!inFlowSeqAnyElement(StateStack.back()) &&
744 !inFlowMapAnyKey(StateStack.back())))
748 void Output::outputNewLine() {
757 void Output::newLineCheck() {
760 NeedsNewLine =
false;
764 if (StateStack.size() == 0)
767 unsigned Indent = StateStack.size() - 1;
768 bool OutputDash =
false;
770 if (StateStack.back() == inSeqFirstElement ||
771 StateStack.back() == inSeqOtherElement) {
773 }
else if ((StateStack.size() > 1) &&
774 ((StateStack.back() == inMapFirstKey) ||
775 inFlowSeqAnyElement(StateStack.back()) ||
776 (StateStack.back() == inFlowMapFirstKey)) &&
777 inSeqAnyElement(StateStack[StateStack.size() - 2])) {
782 for (
unsigned i = 0; i <
Indent; ++i) {
794 const char *spaces =
" ";
795 if (key.
size() < strlen(spaces))
796 output(&spaces[key.
size()]);
802 if (StateStack.back() == inFlowMapOtherKey)
804 if (WrapColumn && Column > WrapColumn) {
806 for (
int I = 0;
I < ColumnAtMapFlowStart; ++
I)
808 Column = ColumnAtMapFlowStart;
817 bool Output::inSeqAnyElement(InState State) {
818 return State == inSeqFirstElement || State == inSeqOtherElement;
821 bool Output::inFlowSeqAnyElement(InState State) {
822 return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement;
825 bool Output::inMapAnyKey(InState State) {
826 return State == inMapFirstKey || State == inMapOtherKey;
829 bool Output::inFlowMapAnyKey(InState State) {
830 return State == inFlowMapFirstKey || State == inFlowMapOtherKey;
837 void ScalarTraits<bool>::output(
const bool &Val,
void *,
raw_ostream &Out) {
838 Out << (Val ?
"true" :
"false");
842 if (Scalar.
equals(
"true")) {
845 }
else if (Scalar.
equals(
"false")) {
849 return "invalid boolean";
852 void ScalarTraits<StringRef>::output(
const StringRef &Val,
void *,
863 void ScalarTraits<std::string>::output(
const std::string &Val,
void *,
874 void ScalarTraits<uint8_t>::output(
const uint8_t &Val,
void *,
882 unsigned long long n;
884 return "invalid number";
886 return "out of range number";
891 void ScalarTraits<uint16_t>::output(
const uint16_t &Val,
void *,
898 unsigned long long n;
900 return "invalid number";
902 return "out of range number";
907 void ScalarTraits<uint32_t>::output(
const uint32_t &Val,
void *,
914 unsigned long long n;
916 return "invalid number";
917 if (n > 0xFFFFFFFFUL)
918 return "out of range number";
923 void ScalarTraits<uint64_t>::output(
const uint64_t &Val,
void *,
930 unsigned long long N;
932 return "invalid number";
937 void ScalarTraits<int8_t>::output(
const int8_t &Val,
void *,
raw_ostream &Out) {
946 return "invalid number";
947 if ((N > 127) || (N < -128))
948 return "out of range number";
953 void ScalarTraits<int16_t>::output(
const int16_t &Val,
void *,
961 return "invalid number";
962 if ((N > INT16_MAX) || (N < INT16_MIN))
963 return "out of range number";
968 void ScalarTraits<int32_t>::output(
const int32_t &Val,
void *,
976 return "invalid number";
977 if ((N > INT32_MAX) || (N < INT32_MIN))
978 return "out of range number";
983 void ScalarTraits<int64_t>::output(
const int64_t &Val,
void *,
991 return "invalid number";
996 void ScalarTraits<double>::output(
const double &Val,
void *,
raw_ostream &Out) {
1003 return "invalid floating point number";
1006 void ScalarTraits<float>::output(
const float &Val,
void *,
raw_ostream &Out) {
1007 Out <<
format(
"%g", Val);
1013 return "invalid floating point number";
1016 void ScalarTraits<Hex8>::output(
const Hex8 &Val,
void *,
raw_ostream &Out) {
1018 Out <<
format(
"0x%02X", Num);
1022 unsigned long long n;
1024 return "invalid hex8 number";
1026 return "out of range hex8 number";
1031 void ScalarTraits<Hex16>::output(
const Hex16 &Val,
void *,
raw_ostream &Out) {
1033 Out <<
format(
"0x%04X", Num);
1037 unsigned long long n;
1039 return "invalid hex16 number";
1041 return "out of range hex16 number";
1046 void ScalarTraits<Hex32>::output(
const Hex32 &Val,
void *,
raw_ostream &Out) {
1048 Out <<
format(
"0x%08X", Num);
1052 unsigned long long n;
1054 return "invalid hex32 number";
1055 if (n > 0xFFFFFFFFUL)
1056 return "out of range hex32 number";
1061 void ScalarTraits<Hex64>::output(
const Hex64 &Val,
void *,
raw_ostream &Out) {
1063 Out <<
format(
"0x%016llX", Num);
1067 unsigned long long Num;
1069 return "invalid hex64 number";
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Represents a YAML sequence created from either a block sequence for a flow sequence.
A forward iterator which reads text lines from a buffer.
std::string escape(StringRef Input, bool EscapePrintable=true)
Escape Input for a double quoted scalar; if EscapePrintable is true, all UTF8 sequences will be escap...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_NODISCARD StringRef copy(Allocator &A) const
A Use represents the edge between a Value definition and its users.
std::error_code make_error_code(BitcodeError E)
StringRef str() const
Explicit conversion to StringRef.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
bool to_float(const Twine &T, float &Num)
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A scalar node is an opaque datum that can be presented as a series of zero or more Unicode scalar val...
This class represents a YAML stream potentially containing multiple documents.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
LLVM_NODISCARD bool empty() const
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
A block scalar node is an opaque datum that can be presented as a series of zero or more Unicode scal...
Represents a YAML map created from either a block map for a flow map.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
std::string getVerbatimTag() const
Get the verbatium tag for a given Node.
StringRef - Represent a constant reference to a string, i.e.
StringRef getValue(SmallVectorImpl< char > &Storage) const
Gets the value of this node as a StringRef.
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result)
Abstract base class for all Nodes.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.