39 IO::IO(
void *
Context) : Ctxt(Context) {}
43 void *IO::getContext()
const {
47 void IO::setContext(
void *
Context) {
55 Input::Input(
StringRef InputContent,
void *Ctxt,
60 DocIterator = Strm->begin();
68 DocIterator = Strm->begin();
71 Input::~Input() =
default;
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()
const {
86 bool Input::setCurrentDocument() {
87 if (DocIterator != Strm->end()) {
88 Node *
N = DocIterator->getRoot();
90 assert(Strm->failed() &&
"Root is NULL iff parsing failed");
95 if (isa<NullNode>(N)) {
98 return setCurrentDocument();
100 TopNode = createHNodes(N);
101 CurrentNode = TopNode.get();
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) {
122 if (foundTag.empty()) {
127 return Tag.
equals(foundTag);
130 void Input::beginMapping() {
134 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
136 MN->ValidKeys.clear();
140 std::vector<StringRef> Input::keys() {
141 MapHNode *MN =
dyn_cast<MapHNode>(CurrentNode);
142 std::vector<StringRef>
Ret;
144 setError(CurrentNode,
"not a mapping");
147 for (
auto &
P : MN->Mapping)
148 Ret.push_back(
P.first());
152 bool Input::preflightKey(
const char *
Key,
bool Required,
bool,
bool &UseDefault,
166 MapHNode *MN =
dyn_cast<MapHNode>(CurrentNode);
168 if (Required || !isa<EmptyHNode>(CurrentNode))
169 setError(CurrentNode,
"not a mapping");
172 MN->ValidKeys.push_back(Key);
173 HNode *
Value = MN->Mapping[
Key].get();
176 setError(CurrentNode,
Twine(
"missing required key '") + Key +
"'");
181 SaveInfo = CurrentNode;
186 void Input::postflightKey(
void *saveInfo) {
187 CurrentNode =
reinterpret_cast<HNode *
>(saveInfo);
190 void Input::endMapping() {
194 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
197 for (
const auto &NN : MN->Mapping) {
199 setError(NN.second.get(),
Twine(
"unknown key '") + NN.first() +
"'");
205 void Input::beginFlowMapping() { beginMapping(); }
207 void Input::endFlowMapping() { endMapping(); }
209 unsigned Input::beginSequence() {
210 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
211 return SQ->Entries.size();
212 if (isa<EmptyHNode>(CurrentNode))
215 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
216 if (isNull(SN->value()))
220 setError(CurrentNode,
"not a sequence");
224 void Input::endSequence() {
227 bool Input::preflightElement(
unsigned Index,
void *&SaveInfo) {
230 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
231 SaveInfo = CurrentNode;
232 CurrentNode = SQ->Entries[
Index].get();
238 void Input::postflightElement(
void *SaveInfo) {
239 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
242 unsigned Input::beginFlowSequence() {
return beginSequence(); }
244 bool Input::preflightFlowElement(
unsigned index,
void *&SaveInfo) {
247 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
248 SaveInfo = CurrentNode;
249 CurrentNode = SQ->Entries[index].get();
255 void Input::postflightFlowElement(
void *SaveInfo) {
256 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
259 void Input::endFlowSequence() {
262 void Input::beginEnumScalar() {
263 ScalarMatchFound =
false;
266 bool Input::matchEnumScalar(
const char *Str,
bool) {
267 if (ScalarMatchFound)
269 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
270 if (SN->value().equals(Str)) {
271 ScalarMatchFound =
true;
278 bool Input::matchEnumFallback() {
279 if (ScalarMatchFound)
281 ScalarMatchFound =
true;
285 void Input::endEnumScalar() {
286 if (!ScalarMatchFound) {
287 setError(CurrentNode,
"unknown enumerated scalar");
291 bool Input::beginBitSetScalar(
bool &DoClear) {
292 BitValuesUsed.clear();
293 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
294 BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(),
false);
296 setError(CurrentNode,
"expected sequence of bit values");
302 bool Input::bitSetMatch(
const char *Str,
bool) {
305 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
307 for (
auto &N : SQ->Entries) {
308 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
309 if (SN->value().equals(Str)) {
310 BitValuesUsed[
Index] =
true;
314 setError(CurrentNode,
"unexpected scalar in sequence of bit values");
319 setError(CurrentNode,
"expected sequence of bit values");
324 void Input::endBitSetScalar() {
327 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
328 assert(BitValuesUsed.size() == SQ->Entries.size());
329 for (
unsigned i = 0; i < SQ->Entries.size(); ++i) {
330 if (!BitValuesUsed[i]) {
331 setError(SQ->Entries[i].get(),
"unknown bit value");
338 void Input::scalarString(
StringRef &S, QuotingType) {
339 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
342 setError(CurrentNode,
"unexpected scalar");
348 void Input::scalarTag(std::string &Tag) {
349 Tag = CurrentNode->_node->getVerbatimTag();
352 void Input::setError(HNode *hnode,
const Twine &message) {
353 assert(hnode &&
"HNode must not be NULL");
354 setError(hnode->_node, message);
358 if (isa<ScalarHNode>(CurrentNode))
360 else if (isa<MapHNode>(CurrentNode))
361 return NodeKind::Map;
362 else if (isa<SequenceHNode>(CurrentNode))
367 void Input::setError(
Node *node,
const Twine &message) {
368 Strm->printError(node, message);
372 std::unique_ptr<Input::HNode> Input::createHNodes(
Node *N) {
374 if (
ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
375 StringRef KeyStr = SN->getValue(StringStorage);
376 if (!StringStorage.
empty()) {
378 KeyStr = StringStorage.
str().
copy(StringAllocator);
380 return std::make_unique<ScalarHNode>(
N, KeyStr);
383 return std::make_unique<ScalarHNode>(
N, ValueCopy);
384 }
else if (
SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
385 auto SQHNode = std::make_unique<SequenceHNode>(
N);
386 for (
Node &SN : *SQ) {
387 auto Entry = createHNodes(&SN);
390 SQHNode->Entries.push_back(std::move(
Entry));
392 return std::move(SQHNode);
393 }
else if (
MappingNode *Map = dyn_cast<MappingNode>(N)) {
394 auto mapHNode = std::make_unique<MapHNode>(
N);
396 Node *KeyNode = KVN.getKey();
398 Node *Value = KVN.getValue();
399 if (!Key || !Value) {
401 setError(KeyNode,
"Map key must be a scalar");
403 setError(KeyNode,
"Map value must not be empty");
406 StringStorage.
clear();
408 if (!StringStorage.
empty()) {
410 KeyStr = StringStorage.
str().
copy(StringAllocator);
412 auto ValueHNode = createHNodes(Value);
415 mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
417 return std::move(mapHNode);
418 }
else if (isa<NullNode>(N)) {
419 return std::make_unique<EmptyHNode>(
N);
421 setError(N,
"unknown node kind");
426 void Input::setError(
const Twine &Message) {
427 setError(CurrentNode, Message);
430 bool Input::canElideEmptySequence() {
438 Output::Output(
raw_ostream &yout,
void *context,
int WrapColumn)
439 : IO(context), Out(yout), WrapColumn(WrapColumn) {}
441 Output::~Output() =
default;
443 bool Output::outputting()
const {
447 void Output::beginMapping() {
448 StateStack.push_back(inMapFirstKey);
449 PaddingBeforeContainer = Padding;
458 bool SequenceElement =
false;
459 if (StateStack.size() > 1) {
460 auto &
E = StateStack[StateStack.size() - 2];
461 SequenceElement = inSeqAnyElement(
E) || inFlowSeqAnyElement(
E);
463 if (SequenceElement && StateStack.back() == inMapFirstKey) {
469 if (SequenceElement) {
472 if (StateStack.back() == inMapFirstKey) {
473 StateStack.pop_back();
474 StateStack.push_back(inMapOtherKey);
484 void Output::endMapping() {
486 if (StateStack.back() == inMapFirstKey) {
487 Padding = PaddingBeforeContainer;
492 StateStack.pop_back();
495 std::vector<StringRef> Output::keys() {
499 bool Output::preflightKey(
const char *Key,
bool Required,
bool SameAsDefault,
500 bool &UseDefault,
void *&) {
502 if (Required || !SameAsDefault || WriteDefaultValues) {
503 auto State = StateStack.back();
504 if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
515 void Output::postflightKey(
void *) {
516 if (StateStack.back() == inMapFirstKey) {
517 StateStack.pop_back();
518 StateStack.push_back(inMapOtherKey);
519 }
else if (StateStack.back() == inFlowMapFirstKey) {
520 StateStack.pop_back();
521 StateStack.push_back(inFlowMapOtherKey);
525 void Output::beginFlowMapping() {
526 StateStack.push_back(inFlowMapFirstKey);
528 ColumnAtMapFlowStart = Column;
532 void Output::endFlowMapping() {
533 StateStack.pop_back();
534 outputUpToEndOfLine(
" }");
537 void Output::beginDocuments() {
538 outputUpToEndOfLine(
"---");
541 bool Output::preflightDocument(
unsigned index) {
543 outputUpToEndOfLine(
"\n---");
547 void Output::postflightDocument() {
550 void Output::endDocuments() {
554 unsigned Output::beginSequence() {
555 StateStack.push_back(inSeqFirstElement);
556 PaddingBeforeContainer = Padding;
561 void Output::endSequence() {
563 if (StateStack.back() == inSeqFirstElement) {
564 Padding = PaddingBeforeContainer;
569 StateStack.pop_back();
572 bool Output::preflightElement(
unsigned,
void *&) {
576 void Output::postflightElement(
void *) {
577 if (StateStack.back() == inSeqFirstElement) {
578 StateStack.pop_back();
579 StateStack.push_back(inSeqOtherElement);
580 }
else if (StateStack.back() == inFlowSeqFirstElement) {
581 StateStack.pop_back();
582 StateStack.push_back(inFlowSeqOtherElement);
586 unsigned Output::beginFlowSequence() {
587 StateStack.push_back(inFlowSeqFirstElement);
589 ColumnAtFlowStart = Column;
591 NeedFlowSequenceComma =
false;
595 void Output::endFlowSequence() {
596 StateStack.pop_back();
597 outputUpToEndOfLine(
" ]");
600 bool Output::preflightFlowElement(
unsigned,
void *&) {
601 if (NeedFlowSequenceComma)
603 if (WrapColumn && Column > WrapColumn) {
605 for (
int i = 0; i < ColumnAtFlowStart; ++i)
607 Column = ColumnAtFlowStart;
613 void Output::postflightFlowElement(
void *) {
614 NeedFlowSequenceComma =
true;
617 void Output::beginEnumScalar() {
618 EnumerationMatchFound =
false;
621 bool Output::matchEnumScalar(
const char *Str,
bool Match) {
622 if (Match && !EnumerationMatchFound) {
624 outputUpToEndOfLine(Str);
625 EnumerationMatchFound =
true;
630 bool Output::matchEnumFallback() {
631 if (EnumerationMatchFound)
633 EnumerationMatchFound =
true;
637 void Output::endEnumScalar() {
638 if (!EnumerationMatchFound)
642 bool Output::beginBitSetScalar(
bool &DoClear) {
645 NeedBitValueComma =
false;
650 bool Output::bitSetMatch(
const char *Str,
bool Matches) {
652 if (NeedBitValueComma)
655 NeedBitValueComma =
true;
660 void Output::endBitSetScalar() {
661 outputUpToEndOfLine(
" ]");
664 void Output::scalarString(
StringRef &S, QuotingType MustQuote) {
669 outputUpToEndOfLine(
"''");
674 outputUpToEndOfLine(S);
686 outputUpToEndOfLine(Quote);
692 unsigned End = S.
size();
705 outputUpToEndOfLine(Quote);
708 void Output::blockScalarString(
StringRef &S) {
709 if (!StateStack.empty())
714 unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
718 for (
unsigned I = 0;
I < Indent; ++
I) {
726 void Output::scalarTag(std::string &Tag) {
734 void Output::setError(
const Twine &message) {
737 bool Output::canElideEmptySequence() {
743 if (StateStack.size() < 2)
745 if (StateStack.back() != inMapFirstKey)
747 return !inSeqAnyElement(StateStack[StateStack.size() - 2]);
755 void Output::outputUpToEndOfLine(
StringRef s) {
757 if (StateStack.empty() || (!inFlowSeqAnyElement(StateStack.back()) &&
758 !inFlowMapAnyKey(StateStack.back())))
762 void Output::outputNewLine() {
771 void Output::newLineCheck() {
772 if (Padding !=
"\n") {
780 if (StateStack.size() == 0)
783 unsigned Indent = StateStack.size() - 1;
784 bool OutputDash =
false;
786 if (StateStack.back() == inSeqFirstElement ||
787 StateStack.back() == inSeqOtherElement) {
789 }
else if ((StateStack.size() > 1) &&
790 ((StateStack.back() == inMapFirstKey) ||
791 inFlowSeqAnyElement(StateStack.back()) ||
792 (StateStack.back() == inFlowMapFirstKey)) &&
793 inSeqAnyElement(StateStack[StateStack.size() - 2])) {
798 for (
unsigned i = 0; i < Indent; ++i) {
810 const char *spaces =
" ";
811 if (key.
size() < strlen(spaces))
812 Padding = &spaces[key.
size()];
818 if (StateStack.back() == inFlowMapOtherKey)
820 if (WrapColumn && Column > WrapColumn) {
822 for (
int I = 0;
I < ColumnAtMapFlowStart; ++
I)
824 Column = ColumnAtMapFlowStart;
833 bool Output::inSeqAnyElement(InState State) {
834 return State == inSeqFirstElement || State == inSeqOtherElement;
837 bool Output::inFlowSeqAnyElement(InState State) {
838 return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement;
841 bool Output::inMapAnyKey(InState State) {
842 return State == inMapFirstKey || State == inMapOtherKey;
845 bool Output::inFlowMapAnyKey(InState State) {
846 return State == inFlowMapFirstKey || State == inFlowMapOtherKey;
853 void ScalarTraits<bool>::output(
const bool &Val,
void *,
raw_ostream &Out) {
854 Out << (Val ?
"true" :
"false");
858 if (Scalar.
equals(
"true")) {
861 }
else if (Scalar.
equals(
"false")) {
865 return "invalid boolean";
868 void ScalarTraits<StringRef>::output(
const StringRef &Val,
void *,
879 void ScalarTraits<std::string>::output(
const std::string &Val,
void *,
890 void ScalarTraits<uint8_t>::output(
const uint8_t &Val,
void *,
898 unsigned long long n;
900 return "invalid number";
902 return "out of range number";
907 void ScalarTraits<uint16_t>::output(
const uint16_t &Val,
void *,
914 unsigned long long n;
916 return "invalid number";
918 return "out of range number";
923 void ScalarTraits<uint32_t>::output(
const uint32_t &Val,
void *,
930 unsigned long long n;
932 return "invalid number";
933 if (n > 0xFFFFFFFFUL)
934 return "out of range number";
939 void ScalarTraits<uint64_t>::output(
const uint64_t &Val,
void *,
946 unsigned long long N;
948 return "invalid number";
953 void ScalarTraits<int8_t>::output(
const int8_t &Val,
void *,
raw_ostream &Out) {
962 return "invalid number";
963 if ((N > 127) || (N < -128))
964 return "out of range number";
969 void ScalarTraits<int16_t>::output(
const int16_t &Val,
void *,
977 return "invalid number";
978 if ((N > INT16_MAX) || (N < INT16_MIN))
979 return "out of range number";
984 void ScalarTraits<int32_t>::output(
const int32_t &Val,
void *,
992 return "invalid number";
993 if ((N > INT32_MAX) || (N < INT32_MIN))
994 return "out of range number";
999 void ScalarTraits<int64_t>::output(
const int64_t &Val,
void *,
1007 return "invalid number";
1012 void ScalarTraits<double>::output(
const double &Val,
void *,
raw_ostream &Out) {
1013 Out <<
format(
"%g", Val);
1019 return "invalid floating point number";
1022 void ScalarTraits<float>::output(
const float &Val,
void *,
raw_ostream &Out) {
1023 Out <<
format(
"%g", Val);
1029 return "invalid floating point number";
1032 void ScalarTraits<Hex8>::output(
const Hex8 &Val,
void *,
raw_ostream &Out) {
1034 Out <<
format(
"0x%02X", Num);
1038 unsigned long long n;
1040 return "invalid hex8 number";
1042 return "out of range hex8 number";
1047 void ScalarTraits<Hex16>::output(
const Hex16 &Val,
void *,
raw_ostream &Out) {
1049 Out <<
format(
"0x%04X", Num);
1053 unsigned long long n;
1055 return "invalid hex16 number";
1057 return "out of range hex16 number";
1062 void ScalarTraits<Hex32>::output(
const Hex32 &Val,
void *,
raw_ostream &Out) {
1064 Out <<
format(
"0x%08X", Num);
1068 unsigned long long n;
1070 return "invalid hex32 number";
1071 if (n > 0xFFFFFFFFUL)
1072 return "out of range hex32 number";
1077 void ScalarTraits<Hex64>::output(
const Hex64 &Val,
void *,
raw_ostream &Out) {
1079 Out <<
format(
"0x%016llX", Num);
1083 unsigned long long Num;
1085 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.
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...
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)
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
StringRef str() const
Explicit conversion to StringRef.
bool to_float(const Twine &T, float &Num)
LLVM_NODISCARD size_t size() const
size - Get the string size.
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 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.
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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.