29 IO::IO(
void *Context) : Ctxt(Context) {
50 void *DiagHandlerCtxt)
53 CurrentNode(nullptr) {
56 DocIterator = Strm->begin();
65 void Input::HNode::anchor() {}
66 void Input::EmptyHNode::anchor() {}
67 void Input::ScalarHNode::anchor() {}
68 void Input::MapHNode::anchor() {}
69 void Input::SequenceHNode::anchor() {}
71 bool Input::outputting() {
76 if (DocIterator != Strm->end()) {
77 Node *
N = DocIterator->getRoot();
79 assert(Strm->failed() &&
"Root is NULL iff parsing failed");
84 if (isa<NullNode>(N)) {
89 TopNode = this->createHNodes(N);
90 CurrentNode = TopNode.get();
97 return ++DocIterator != Strm->end();
101 return CurrentNode ? CurrentNode->_node :
nullptr;
105 std::string foundTag = CurrentNode->_node->getVerbatimTag();
106 if (foundTag.empty()) {
111 return Tag.
equals(foundTag);
114 void Input::beginMapping() {
118 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
120 MN->ValidKeys.clear();
124 bool Input::preflightKey(
const char *Key,
bool Required,
bool,
bool &UseDefault,
138 MapHNode *MN =
dyn_cast<MapHNode>(CurrentNode);
140 setError(CurrentNode,
"not a mapping");
143 MN->ValidKeys.push_back(Key);
144 HNode *
Value = MN->Mapping[Key].get();
147 setError(CurrentNode,
Twine(
"missing required key '") + Key +
"'");
152 SaveInfo = CurrentNode;
157 void Input::postflightKey(
void *saveInfo) {
158 CurrentNode =
reinterpret_cast<HNode *
>(saveInfo);
161 void Input::endMapping() {
165 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
168 for (
const auto &NN : MN->Mapping) {
169 if (!MN->isValidKey(NN.first())) {
170 setError(NN.second.get(),
Twine(
"unknown key '") + NN.first() +
"'");
176 void Input::beginFlowMapping() { beginMapping(); }
178 void Input::endFlowMapping() { endMapping(); }
180 unsigned Input::beginSequence() {
181 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
182 return SQ->Entries.size();
183 if (isa<EmptyHNode>(CurrentNode))
186 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
191 setError(CurrentNode,
"not a sequence");
195 void Input::endSequence() {
198 bool Input::preflightElement(
unsigned Index,
void *&SaveInfo) {
201 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
202 SaveInfo = CurrentNode;
203 CurrentNode = SQ->Entries[Index].get();
209 void Input::postflightElement(
void *SaveInfo) {
210 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
213 unsigned Input::beginFlowSequence() {
return beginSequence(); }
215 bool Input::preflightFlowElement(
unsigned index,
void *&SaveInfo) {
218 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
219 SaveInfo = CurrentNode;
220 CurrentNode = SQ->Entries[index].get();
226 void Input::postflightFlowElement(
void *SaveInfo) {
227 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
230 void Input::endFlowSequence() {
233 void Input::beginEnumScalar() {
234 ScalarMatchFound =
false;
237 bool Input::matchEnumScalar(
const char *Str,
bool) {
238 if (ScalarMatchFound)
240 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
241 if (SN->value().equals(Str)) {
242 ScalarMatchFound =
true;
249 bool Input::matchEnumFallback() {
250 if (ScalarMatchFound)
252 ScalarMatchFound =
true;
256 void Input::endEnumScalar() {
257 if (!ScalarMatchFound) {
258 setError(CurrentNode,
"unknown enumerated scalar");
262 bool Input::beginBitSetScalar(
bool &DoClear) {
263 BitValuesUsed.clear();
264 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
265 BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(),
false);
267 setError(CurrentNode,
"expected sequence of bit values");
273 bool Input::bitSetMatch(
const char *Str,
bool) {
276 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
278 for (
auto &
N : SQ->Entries) {
279 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(
N.get())) {
280 if (SN->value().equals(Str)) {
281 BitValuesUsed[Index] =
true;
285 setError(CurrentNode,
"unexpected scalar in sequence of bit values");
290 setError(CurrentNode,
"expected sequence of bit values");
295 void Input::endBitSetScalar() {
298 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
299 assert(BitValuesUsed.size() == SQ->Entries.size());
300 for (
unsigned i = 0; i < SQ->Entries.size(); ++i) {
301 if (!BitValuesUsed[i]) {
302 setError(SQ->Entries[i].get(),
"unknown bit value");
309 void Input::scalarString(
StringRef &S,
bool) {
310 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
313 setError(CurrentNode,
"unexpected scalar");
317 void Input::blockScalarString(
StringRef &S) { scalarString(S,
false); }
319 void Input::setError(HNode *hnode,
const Twine &message) {
320 assert(hnode &&
"HNode must not be NULL");
321 this->setError(hnode->_node, message);
324 void Input::setError(
Node *node,
const Twine &message) {
325 Strm->printError(node, message);
329 std::unique_ptr<Input::HNode> Input::createHNodes(
Node *
N) {
331 if (
ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
332 StringRef KeyStr = SN->getValue(StringStorage);
333 if (!StringStorage.
empty()) {
335 unsigned Len = StringStorage.
size();
336 char *Buf = StringAllocator.
Allocate<
char>(Len);
337 memcpy(Buf, &StringStorage[0], Len);
340 return llvm::make_unique<ScalarHNode>(
N, KeyStr);
343 char *Buf = StringAllocator.
Allocate<
char>(Value.
size());
344 memcpy(Buf, Value.
data(), Value.
size());
345 return llvm::make_unique<ScalarHNode>(
N,
StringRef(Buf, Value.
size()));
346 }
else if (
SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
347 auto SQHNode = llvm::make_unique<SequenceHNode>(
N);
348 for (
Node &SN : *SQ) {
349 auto Entry = this->createHNodes(&SN);
352 SQHNode->Entries.push_back(std::move(Entry));
354 return std::move(SQHNode);
355 }
else if (
MappingNode *Map = dyn_cast<MappingNode>(N)) {
356 auto mapHNode = llvm::make_unique<MapHNode>(
N);
358 Node *KeyNode = KVN.getKey();
361 setError(KeyNode,
"Map key must be a scalar");
364 StringStorage.
clear();
366 if (!StringStorage.
empty()) {
368 unsigned Len = StringStorage.
size();
369 char *Buf = StringAllocator.
Allocate<
char>(Len);
370 memcpy(Buf, &StringStorage[0], Len);
373 auto ValueHNode = this->createHNodes(KVN.getValue());
376 mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
378 return std::move(mapHNode);
379 }
else if (isa<NullNode>(N)) {
380 return llvm::make_unique<EmptyHNode>(
N);
382 setError(N,
"unknown node kind");
387 bool Input::MapHNode::isValidKey(
StringRef Key) {
388 for (
const char *K : ValidKeys) {
395 void Input::setError(
const Twine &Message) {
396 this->setError(CurrentNode, Message);
399 bool Input::canElideEmptySequence() {
410 WrapColumn(WrapColumn),
412 ColumnAtFlowStart(0),
413 ColumnAtMapFlowStart(0),
414 NeedBitValueComma(
false),
415 NeedFlowSequenceComma(
false),
416 EnumerationMatchFound(
false),
417 NeedsNewLine(
false) {
445 bool &UseDefault,
void *&) {
447 if (Required || !SameAsDefault) {
448 auto State = StateStack.
back();
449 if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
452 this->newLineCheck();
453 this->paddedKey(Key);
461 if (StateStack.
back() == inMapFirstKey) {
464 }
else if (StateStack.
back() == inFlowMapFirstKey) {
472 this->newLineCheck();
473 ColumnAtMapFlowStart = Column;
479 this->outputUpToEndOfLine(
" }");
483 this->outputUpToEndOfLine(
"---");
488 this->outputUpToEndOfLine(
"\n---");
518 this->newLineCheck();
519 ColumnAtFlowStart = Column;
521 NeedFlowSequenceComma =
false;
527 this->outputUpToEndOfLine(
" ]");
531 if (NeedFlowSequenceComma)
533 if (WrapColumn && Column > WrapColumn) {
535 for (
int i = 0; i < ColumnAtFlowStart; ++i)
537 Column = ColumnAtFlowStart;
544 NeedFlowSequenceComma =
true;
548 EnumerationMatchFound =
false;
552 if (Match && !EnumerationMatchFound) {
553 this->newLineCheck();
554 this->outputUpToEndOfLine(Str);
555 EnumerationMatchFound =
true;
561 if (EnumerationMatchFound)
563 EnumerationMatchFound =
true;
568 if (!EnumerationMatchFound)
573 this->newLineCheck();
575 NeedBitValueComma =
false;
582 if (NeedBitValueComma)
585 NeedBitValueComma =
true;
591 this->outputUpToEndOfLine(
" ]");
595 this->newLineCheck();
599 this->outputUpToEndOfLine(
"''");
604 this->outputUpToEndOfLine(S);
609 unsigned End = S.
size();
611 const char *Base = S.
data();
622 this->outputUpToEndOfLine(
"'");
626 if (!StateStack.
empty())
631 unsigned Indent = StateStack.
empty() ? 1 : StateStack.
size();
635 for (
unsigned I = 0;
I < Indent; ++
I) {
652 if (StateStack.
size() < 2)
654 if (StateStack.
back() != inMapFirstKey)
656 return (StateStack[StateStack.
size()-2] != inSeq);
664 void Output::outputUpToEndOfLine(
StringRef s) {
666 if (StateStack.
empty() || (StateStack.
back() != inFlowSeq &&
667 StateStack.
back() != inFlowMapFirstKey &&
668 StateStack.
back() != inFlowMapOtherKey))
672 void Output::outputNewLine() {
681 void Output::newLineCheck() {
684 NeedsNewLine =
false;
686 this->outputNewLine();
688 assert(StateStack.
size() > 0);
689 unsigned Indent = StateStack.
size() - 1;
690 bool OutputDash =
false;
692 if (StateStack.
back() == inSeq) {
694 }
else if ((StateStack.
size() > 1) && ((StateStack.
back() == inMapFirstKey) ||
695 (StateStack.
back() == inFlowSeq) ||
696 (StateStack.
back() == inFlowMapFirstKey)) &&
697 (StateStack[StateStack.
size() - 2] == inSeq)) {
702 for (
unsigned i = 0; i < Indent; ++i) {
714 const char *spaces =
" ";
715 if (key.
size() < strlen(spaces))
716 output(&spaces[key.
size()]);
722 if (StateStack.
back() == inFlowMapOtherKey)
724 if (WrapColumn && Column > WrapColumn) {
726 for (
int I = 0;
I < ColumnAtMapFlowStart; ++
I)
728 Column = ColumnAtMapFlowStart;
740 Out << (Val ?
"true" :
"false");
744 if (Scalar.
equals(
"true")) {
747 }
else if (Scalar.
equals(
"false")) {
751 return "invalid boolean";
784 unsigned long long n;
786 return "invalid number";
788 return "out of range number";
800 unsigned long long n;
802 return "invalid number";
804 return "out of range number";
816 unsigned long long n;
818 return "invalid number";
819 if (n > 0xFFFFFFFFUL)
820 return "out of range number";
832 unsigned long long N;
834 return "invalid number";
848 return "invalid number";
849 if ((N > 127) || (N < -128))
850 return "out of range number";
863 return "invalid number";
864 if ((N > INT16_MAX) || (N < INT16_MIN))
865 return "out of range number";
878 return "invalid number";
879 if ((N > INT32_MAX) || (N < INT32_MIN))
880 return "out of range number";
893 return "invalid number";
905 Val = strtod(buff.c_str(), &
end);
907 return "invalid floating point number";
918 Val = strtod(buff.c_str(), &
end);
920 return "invalid floating point number";
926 Out <<
format(
"0x%02X", Num);
930 unsigned long long n;
932 return "invalid hex8 number";
934 return "out of range hex8 number";
941 Out <<
format(
"0x%04X", Num);
945 unsigned long long n;
947 return "invalid hex16 number";
949 return "out of range hex16 number";
956 Out <<
format(
"0x%08X", Num);
960 unsigned long long n;
962 return "invalid hex32 number";
963 if (n > 0xFFFFFFFFUL)
964 return "out of range hex32 number";
971 Out <<
format(
"0x%016llX", Num);
975 unsigned long long Num;
977 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)
size_t size() const
size - Get the string size.
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
std::string str() const
str - Get the contents as an std::string.
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...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A Use represents the edge between a Value definition and its users.
void postflightElement(void *) override
bool matchEnumScalar(const char *, bool) override
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
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool outputting() override
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()
bool is_at_end() const
Return true if we're an "end" iterator or have reached EOF.
void postflightFlowElement(void *) override
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
void(* DiagHandlerTy)(const SMDiagnostic &, void *Context)
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
void endFlowSequence() override
bool preflightKey(const char *key, bool, bool, bool &, void *&) override
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
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
unsigned beginFlowSequence() override
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 Value Representation.
void beginEnumScalar() override
unsigned beginSequence() override
This class implements an extremely fast bulk output stream that can only output to a stream...
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
bool empty() const
empty - Check if the string is empty.
Abstract base class for all Nodes.