50 CurrentNode(nullptr) {
53 DocIterator = Strm->begin();
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() {}
68 bool Input::outputting() {
73 if (DocIterator != Strm->end()) {
74 Node *
N = DocIterator->getRoot();
76 assert(Strm->failed() &&
"Root is NULL iff parsing failed");
81 if (isa<NullNode>(N)) {
86 TopNode = this->createHNodes(N);
87 CurrentNode = TopNode.get();
94 return ++DocIterator != Strm->end();
98 return CurrentNode ? CurrentNode->_node :
nullptr;
102 std::string foundTag = CurrentNode->_node->getVerbatimTag();
103 if (foundTag.empty()) {
108 return Tag.
equals(foundTag);
111 void Input::beginMapping() {
115 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
117 MN->ValidKeys.clear();
121 std::vector<StringRef> Input::keys() {
122 MapHNode *MN =
dyn_cast<MapHNode>(CurrentNode);
123 std::vector<StringRef>
Ret;
125 setError(CurrentNode,
"not a mapping");
128 for (
auto &
P : MN->Mapping)
129 Ret.push_back(
P.first());
133 bool Input::preflightKey(
const char *Key,
bool Required,
bool,
bool &UseDefault,
147 MapHNode *MN =
dyn_cast<MapHNode>(CurrentNode);
149 setError(CurrentNode,
"not a mapping");
152 MN->ValidKeys.push_back(Key);
153 HNode *
Value = MN->Mapping[Key].get();
156 setError(CurrentNode,
Twine(
"missing required key '") + Key +
"'");
161 SaveInfo = CurrentNode;
166 void Input::postflightKey(
void *saveInfo) {
167 CurrentNode =
reinterpret_cast<HNode *
>(saveInfo);
170 void Input::endMapping() {
174 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
177 for (
const auto &NN : MN->Mapping) {
179 setError(NN.second.get(),
Twine(
"unknown key '") + NN.first() +
"'");
185 void Input::beginFlowMapping() { beginMapping(); }
187 void Input::endFlowMapping() { endMapping(); }
189 unsigned Input::beginSequence() {
190 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
191 return SQ->Entries.size();
192 if (isa<EmptyHNode>(CurrentNode))
195 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
200 setError(CurrentNode,
"not a sequence");
204 void Input::endSequence() {
207 bool Input::preflightElement(
unsigned Index,
void *&SaveInfo) {
210 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
211 SaveInfo = CurrentNode;
212 CurrentNode = SQ->Entries[Index].get();
218 void Input::postflightElement(
void *SaveInfo) {
219 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
222 unsigned Input::beginFlowSequence() {
return beginSequence(); }
224 bool Input::preflightFlowElement(
unsigned index,
void *&SaveInfo) {
227 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
228 SaveInfo = CurrentNode;
229 CurrentNode = SQ->Entries[index].get();
235 void Input::postflightFlowElement(
void *SaveInfo) {
236 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
239 void Input::endFlowSequence() {
242 void Input::beginEnumScalar() {
243 ScalarMatchFound =
false;
246 bool Input::matchEnumScalar(
const char *Str,
bool) {
247 if (ScalarMatchFound)
249 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
250 if (SN->value().equals(Str)) {
251 ScalarMatchFound =
true;
258 bool Input::matchEnumFallback() {
259 if (ScalarMatchFound)
261 ScalarMatchFound =
true;
265 void Input::endEnumScalar() {
266 if (!ScalarMatchFound) {
267 setError(CurrentNode,
"unknown enumerated scalar");
271 bool Input::beginBitSetScalar(
bool &DoClear) {
272 BitValuesUsed.clear();
273 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
274 BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(),
false);
276 setError(CurrentNode,
"expected sequence of bit values");
282 bool Input::bitSetMatch(
const char *Str,
bool) {
285 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
287 for (
auto &
N : SQ->Entries) {
288 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(
N.get())) {
289 if (SN->value().equals(Str)) {
290 BitValuesUsed[Index] =
true;
294 setError(CurrentNode,
"unexpected scalar in sequence of bit values");
299 setError(CurrentNode,
"expected sequence of bit values");
304 void Input::endBitSetScalar() {
307 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
308 assert(BitValuesUsed.size() == SQ->Entries.size());
309 for (
unsigned i = 0;
i < SQ->Entries.size(); ++
i) {
310 if (!BitValuesUsed[
i]) {
311 setError(SQ->Entries[i].get(),
"unknown bit value");
318 void Input::scalarString(
StringRef &S,
bool) {
319 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
322 setError(CurrentNode,
"unexpected scalar");
326 void Input::blockScalarString(
StringRef &S) { scalarString(S,
false); }
328 void Input::setError(HNode *hnode,
const Twine &message) {
329 assert(hnode &&
"HNode must not be NULL");
330 this->setError(hnode->_node, message);
333 void Input::setError(
Node *node,
const Twine &message) {
334 Strm->printError(node, message);
338 std::unique_ptr<Input::HNode> Input::createHNodes(
Node *
N) {
340 if (
ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
341 StringRef KeyStr = SN->getValue(StringStorage);
342 if (!StringStorage.
empty()) {
344 KeyStr = StringStorage.
str().
copy(StringAllocator);
346 return llvm::make_unique<ScalarHNode>(
N, KeyStr);
349 return llvm::make_unique<ScalarHNode>(
N, ValueCopy);
350 }
else if (
SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
351 auto SQHNode = llvm::make_unique<SequenceHNode>(
N);
352 for (
Node &SN : *SQ) {
353 auto Entry = this->createHNodes(&SN);
356 SQHNode->Entries.push_back(std::move(Entry));
358 return std::move(SQHNode);
359 }
else if (
MappingNode *Map = dyn_cast<MappingNode>(N)) {
360 auto mapHNode = llvm::make_unique<MapHNode>(
N);
362 Node *KeyNode = KVN.getKey();
365 setError(KeyNode,
"Map key must be a scalar");
368 StringStorage.
clear();
370 if (!StringStorage.
empty()) {
372 KeyStr = StringStorage.
str().
copy(StringAllocator);
374 auto ValueHNode = this->createHNodes(KVN.getValue());
377 mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
379 return std::move(mapHNode);
380 }
else if (isa<NullNode>(N)) {
381 return llvm::make_unique<EmptyHNode>(
N);
383 setError(N,
"unknown node kind");
388 void Input::setError(
const Twine &Message) {
389 this->setError(CurrentNode, Message);
392 bool Input::canElideEmptySequence() {
403 WrapColumn(WrapColumn),
405 ColumnAtFlowStart(0),
406 ColumnAtMapFlowStart(0),
407 NeedBitValueComma(
false),
408 NeedFlowSequenceComma(
false),
409 EnumerationMatchFound(
false),
410 NeedsNewLine(
false) {
430 bool SequenceElement =
431 StateStack.
size() > 1 && (StateStack[StateStack.
size() - 2] == inSeq ||
432 StateStack[StateStack.
size() - 2] == inFlowSeq);
433 if (SequenceElement && StateStack.
back() == inMapFirstKey) {
434 this->newLineCheck();
439 if (SequenceElement) {
442 if (StateStack.
back() == inMapFirstKey) {
463 bool &UseDefault,
void *&) {
465 if (Required || !SameAsDefault) {
466 auto State = StateStack.
back();
467 if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
470 this->newLineCheck();
471 this->paddedKey(Key);
479 if (StateStack.
back() == inMapFirstKey) {
482 }
else if (StateStack.
back() == inFlowMapFirstKey) {
490 this->newLineCheck();
491 ColumnAtMapFlowStart = Column;
497 this->outputUpToEndOfLine(
" }");
501 this->outputUpToEndOfLine(
"---");
506 this->outputUpToEndOfLine(
"\n---");
536 this->newLineCheck();
537 ColumnAtFlowStart = Column;
539 NeedFlowSequenceComma =
false;
545 this->outputUpToEndOfLine(
" ]");
549 if (NeedFlowSequenceComma)
551 if (WrapColumn && Column > WrapColumn) {
553 for (
int i = 0;
i < ColumnAtFlowStart; ++
i)
555 Column = ColumnAtFlowStart;
562 NeedFlowSequenceComma =
true;
566 EnumerationMatchFound =
false;
570 if (Match && !EnumerationMatchFound) {
571 this->newLineCheck();
572 this->outputUpToEndOfLine(Str);
573 EnumerationMatchFound =
true;
579 if (EnumerationMatchFound)
581 EnumerationMatchFound =
true;
586 if (!EnumerationMatchFound)
591 this->newLineCheck();
593 NeedBitValueComma =
false;
600 if (NeedBitValueComma)
603 NeedBitValueComma =
true;
609 this->outputUpToEndOfLine(
" ]");
613 this->newLineCheck();
617 this->outputUpToEndOfLine(
"''");
622 this->outputUpToEndOfLine(S);
629 const char *Base = S.
data();
640 this->outputUpToEndOfLine(
"'");
644 if (!StateStack.
empty())
649 unsigned Indent = StateStack.
empty() ? 1 : StateStack.
size();
652 for (
line_iterator Lines(*Buffer,
false); !Lines.is_at_end(); ++Lines) {
653 for (
unsigned I = 0;
I < Indent; ++
I) {
670 if (StateStack.
size() < 2)
672 if (StateStack.
back() != inMapFirstKey)
674 return (StateStack[StateStack.
size()-2] != inSeq);
682 void Output::outputUpToEndOfLine(
StringRef s) {
684 if (StateStack.
empty() || (StateStack.
back() != inFlowSeq &&
685 StateStack.
back() != inFlowMapFirstKey &&
686 StateStack.
back() != inFlowMapOtherKey))
690 void Output::outputNewLine() {
699 void Output::newLineCheck() {
702 NeedsNewLine =
false;
704 this->outputNewLine();
707 unsigned Indent = StateStack.
size() - 1;
708 bool OutputDash =
false;
710 if (StateStack.
back() == inSeq) {
712 }
else if ((StateStack.
size() > 1) && ((StateStack.
back() == inMapFirstKey) ||
713 (StateStack.
back() == inFlowSeq) ||
714 (StateStack.
back() == inFlowMapFirstKey)) &&
715 (StateStack[StateStack.
size() - 2] == inSeq)) {
720 for (
unsigned i = 0;
i < Indent; ++
i) {
732 const char *spaces =
" ";
733 if (key.
size() < strlen(spaces))
734 output(&spaces[key.
size()]);
740 if (StateStack.
back() == inFlowMapOtherKey)
742 if (WrapColumn && Column > WrapColumn) {
744 for (
int I = 0;
I < ColumnAtMapFlowStart; ++
I)
746 Column = ColumnAtMapFlowStart;
758 Out << (Val ?
"true" :
"false");
762 if (Scalar.
equals(
"true")) {
765 }
else if (Scalar.
equals(
"false")) {
769 return "invalid boolean";
802 unsigned long long n;
804 return "invalid number";
806 return "out of range number";
818 unsigned long long n;
820 return "invalid number";
822 return "out of range number";
834 unsigned long long n;
836 return "invalid number";
837 if (n > 0xFFFFFFFFUL)
838 return "out of range number";
850 unsigned long long N;
852 return "invalid number";
866 return "invalid number";
867 if ((N > 127) || (N < -128))
868 return "out of range number";
881 return "invalid number";
882 if ((N > INT16_MAX) || (N < INT16_MIN))
883 return "out of range number";
896 return "invalid number";
897 if ((N > INT32_MAX) || (N < INT32_MIN))
898 return "out of range number";
911 return "invalid number";
923 Val = strtod(buff.c_str(), &
end);
925 return "invalid floating point number";
936 Val = strtod(buff.c_str(), &
end);
938 return "invalid floating point number";
944 Out <<
format(
"0x%02X", Num);
948 unsigned long long n;
950 return "invalid hex8 number";
952 return "out of range hex8 number";
959 Out <<
format(
"0x%04X", Num);
963 unsigned long long n;
965 return "invalid hex16 number";
967 return "out of range hex16 number";
974 Out <<
format(
"0x%08X", Num);
978 unsigned long long n;
980 return "invalid hex32 number";
981 if (n > 0xFFFFFFFFUL)
982 return "out of range hex32 number";
989 Out <<
format(
"0x%016llX", Num);
993 unsigned long long Num;
995 return "invalid hex64 number";
void setError(const Twine &message) override
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
bool preflightElement(unsigned, void *&) override
bool preflightDocument(unsigned)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
void beginMapping() override
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.
void endFlowMapping() override
StringRef getValue(SmallVectorImpl< char > &Storage) const
Gets the value of this node as a StringRef.
Represents a YAML sequence created from either a block sequence for a flow sequence.
void endSequence() override
A forward iterator which reads text lines from a buffer.
void beginFlowMapping() override
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
void postflightElement(void *) override
bool matchEnumScalar(const char *, bool) override
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 ...
std::error_code make_error_code(BitcodeError E)
Output(llvm::raw_ostream &, void *Ctxt=nullptr, int WrapColumn=70)
void scalarString(StringRef &, bool) override
bool matchEnumFallback() override
bool beginBitSetScalar(bool &) override
LLVM_NODISCARD bool empty() const
bool outputting() override
Function Alias Analysis false
std::vector< StringRef > keys() override
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
bool mapTag(StringRef, bool) override
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
void endMapping() override
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
void postflightDocument()
void postflightFlowElement(void *) override
void(* DiagHandlerTy)(const SMDiagnostic &, void *Context)
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
static const unsigned End
void endFlowSequence() override
bool preflightKey(const char *key, bool, bool, bool &, void *&) override
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
#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...
bool preflightFlowElement(unsigned, void *&) override
This class represents a YAML stream potentially containing multiple documents.
This class should be specialized by type that requires custom conversion to/from a yaml scalar...
void endBitSetScalar() override
bool bitSetMatch(const char *, bool) override
StringRef str() const
Explicit conversion to StringRef.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
LLVM_NODISCARD StringRef copy(Allocator &A) const
unsigned beginFlowSequence() override
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
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.
void beginEnumScalar() override
unsigned beginSequence() override
This class implements an extremely fast bulk output stream that can only output to a stream...
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).
StringRef - Represent a constant reference to a string, i.e.
void endEnumScalar() override
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result)
void postflightKey(void *) override
void blockScalarString(StringRef &) override
bool canElideEmptySequence() override
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.