26 IO::IO(
void *Context) : Ctxt(Context) {
47 void *DiagHandlerCtxt)
53 DocIterator = Strm->begin();
64 void Input::HNode::anchor() {}
65 void Input::EmptyHNode::anchor() {}
66 void Input::ScalarHNode::anchor() {}
68 bool Input::outputting()
const {
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.
reset(this->createHNodes(N));
87 CurrentNode = TopNode.
get();
98 std::string foundTag = CurrentNode->_node->getVerbatimTag();
99 if (foundTag.empty()) {
104 return Tag.
equals(foundTag);
107 void Input::beginMapping() {
111 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
113 MN->ValidKeys.clear();
117 bool Input::preflightKey(
const char *Key,
bool Required,
bool,
bool &UseDefault,
131 MapHNode *MN =
dyn_cast<MapHNode>(CurrentNode);
133 setError(CurrentNode,
"not a mapping");
136 MN->ValidKeys.push_back(Key);
137 HNode *
Value = MN->Mapping[Key];
140 setError(CurrentNode,
Twine(
"missing required key '") + Key +
"'");
145 SaveInfo = CurrentNode;
150 void Input::postflightKey(
void *saveInfo) {
151 CurrentNode =
reinterpret_cast<HNode *
>(saveInfo);
154 void Input::endMapping() {
158 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
162 End = MN->Mapping.end(); i != End; ++i) {
163 if (!MN->isValidKey(i->first())) {
164 setError(i->second,
Twine(
"unknown key '") + i->first() +
"'");
170 unsigned Input::beginSequence() {
171 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
172 return SQ->Entries.size();
177 void Input::endSequence() {
180 bool Input::preflightElement(
unsigned Index,
void *&SaveInfo) {
183 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
184 SaveInfo = CurrentNode;
185 CurrentNode = SQ->Entries[Index];
191 void Input::postflightElement(
void *SaveInfo) {
192 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
195 unsigned Input::beginFlowSequence() {
196 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
197 return SQ->Entries.size();
202 bool Input::preflightFlowElement(
unsigned index,
void *&SaveInfo) {
205 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
206 SaveInfo = CurrentNode;
207 CurrentNode = SQ->Entries[index];
213 void Input::postflightFlowElement(
void *SaveInfo) {
214 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
217 void Input::endFlowSequence() {
220 void Input::beginEnumScalar() {
221 ScalarMatchFound =
false;
224 bool Input::matchEnumScalar(
const char *Str,
bool) {
225 if (ScalarMatchFound)
227 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
228 if (SN->value().equals(Str)) {
229 ScalarMatchFound =
true;
236 void Input::endEnumScalar() {
237 if (!ScalarMatchFound) {
238 setError(CurrentNode,
"unknown enumerated scalar");
242 bool Input::beginBitSetScalar(
bool &DoClear) {
243 BitValuesUsed.clear();
244 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
245 BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(),
false);
247 setError(CurrentNode,
"expected sequence of bit values");
253 bool Input::bitSetMatch(
const char *Str,
bool) {
256 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
258 for (std::vector<HNode *>::iterator i = SQ->Entries.begin(),
259 End = SQ->Entries.end(); i != End; ++i) {
260 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(*i)) {
261 if (SN->value().equals(Str)) {
262 BitValuesUsed[Index] =
true;
266 setError(CurrentNode,
"unexpected scalar in sequence of bit values");
271 setError(CurrentNode,
"expected sequence of bit values");
276 void Input::endBitSetScalar() {
279 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
280 assert(BitValuesUsed.size() == SQ->Entries.size());
281 for (
unsigned i = 0; i < SQ->Entries.size(); ++i) {
282 if (!BitValuesUsed[i]) {
283 setError(SQ->Entries[i],
"unknown bit value");
291 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
294 setError(CurrentNode,
"unexpected scalar");
298 void Input::setError(HNode *hnode,
const Twine &message) {
299 assert(hnode &&
"HNode must not be NULL");
300 this->setError(hnode->_node, message);
303 void Input::setError(
Node *node,
const Twine &message) {
304 Strm->printError(node, message);
308 Input::HNode *Input::createHNodes(
Node *
N) {
310 if (
ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
311 StringRef KeyStr = SN->getValue(StringStorage);
312 if (!StringStorage.
empty()) {
314 unsigned Len = StringStorage.
size();
315 char *Buf = StringAllocator.
Allocate<
char>(Len);
316 memcpy(Buf, &StringStorage[0], Len);
319 return new ScalarHNode(N, KeyStr);
320 }
else if (
SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
321 SequenceHNode *SQHNode =
new SequenceHNode(N);
324 HNode *Entry = this->createHNodes(i);
327 SQHNode->Entries.push_back(Entry);
330 }
else if (
MappingNode *Map = dyn_cast<MappingNode>(N)) {
331 MapHNode *mapHNode =
new MapHNode(N);
335 StringStorage.
clear();
337 if (!StringStorage.
empty()) {
339 unsigned Len = StringStorage.
size();
340 char *Buf = StringAllocator.
Allocate<
char>(Len);
341 memcpy(Buf, &StringStorage[0], Len);
344 HNode *ValueHNode = this->createHNodes(i->getValue());
347 mapHNode->Mapping[KeyStr] = ValueHNode;
350 }
else if (isa<NullNode>(N)) {
351 return new EmptyHNode(N);
353 setError(N,
"unknown node kind");
358 bool Input::MapHNode::isValidKey(
StringRef Key) {
360 End = ValidKeys.end(); i != End; ++i) {
367 void Input::setError(
const Twine &Message) {
368 this->setError(CurrentNode, Message);
371 bool Input::canElideEmptySequence() {
375 Input::MapHNode::~MapHNode() {
376 for (MapHNode::NameToNode::iterator i = Mapping.begin(), End = Mapping.end();
382 Input::SequenceHNode::~SequenceHNode() {
383 for (std::vector<HNode*>::iterator i = Entries.begin(), End = Entries.end();
399 ColumnAtFlowStart(0),
400 NeedBitValueComma(
false),
401 NeedFlowSequenceComma(
false),
402 EnumerationMatchFound(
false),
403 NeedsNewLine(
false) {
431 bool &UseDefault,
void *&) {
433 if (Required || !SameAsDefault) {
434 this->newLineCheck();
435 this->paddedKey(Key);
442 if (StateStack.
back() == inMapFirstKey) {
449 this->outputUpToEndOfLine(
"---");
454 this->outputUpToEndOfLine(
"\n---");
484 this->newLineCheck();
485 ColumnAtFlowStart = Column;
487 NeedFlowSequenceComma =
false;
493 this->outputUpToEndOfLine(
" ]");
497 if (NeedFlowSequenceComma)
501 for (
int i = 0; i < ColumnAtFlowStart; ++i)
503 Column = ColumnAtFlowStart;
510 NeedFlowSequenceComma =
true;
514 EnumerationMatchFound =
false;
518 if (Match && !EnumerationMatchFound) {
519 this->newLineCheck();
520 this->outputUpToEndOfLine(Str);
521 EnumerationMatchFound =
true;
527 if (!EnumerationMatchFound)
532 this->newLineCheck();
534 NeedBitValueComma =
false;
541 if (NeedBitValueComma)
544 NeedBitValueComma =
true;
550 this->outputUpToEndOfLine(
" ]");
554 const char ScalarSafeChars[] =
"abcdefghijklmnopqrstuvwxyz"
555 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
557 this->newLineCheck();
561 this->outputUpToEndOfLine(
"''");
565 !isspace(S.
front()) && !isspace(S.
back())) {
568 this->outputUpToEndOfLine(S);
573 unsigned End = S.
size();
575 const char *Base = S.
data();
586 this->outputUpToEndOfLine(
"'");
598 if (StateStack.
size() < 2)
600 if (StateStack.
back() != inMapFirstKey)
602 return (StateStack[StateStack.
size()-2] != inSeq);
610 void Output::outputUpToEndOfLine(
StringRef s) {
612 if (StateStack.
empty() || StateStack.
back() != inFlowSeq)
616 void Output::outputNewLine() {
625 void Output::newLineCheck() {
628 NeedsNewLine =
false;
630 this->outputNewLine();
632 assert(StateStack.
size() > 0);
633 unsigned Indent = StateStack.
size() - 1;
634 bool OutputDash =
false;
636 if (StateStack.
back() == inSeq) {
638 }
else if ((StateStack.
size() > 1) && (StateStack.
back() == inMapFirstKey) &&
639 (StateStack[StateStack.
size() - 2] == inSeq)) {
644 for (
unsigned i = 0; i < Indent; ++i) {
656 const char *spaces =
" ";
658 output(&spaces[key.
size()]);
668 Out << (Val ?
"true" :
"false");
672 if (Scalar.
equals(
"true")) {
675 }
else if (Scalar.
equals(
"false")) {
679 return "invalid boolean";
701 unsigned long long n;
703 return "invalid number";
705 return "out of range number";
717 unsigned long long n;
719 return "invalid number";
721 return "out of range number";
733 unsigned long long n;
735 return "invalid number";
736 if (n > 0xFFFFFFFFUL)
737 return "out of range number";
749 unsigned long long N;
751 return "invalid number";
765 return "invalid number";
766 if ((N > 127) || (N < -128))
767 return "out of range number";
780 return "invalid number";
781 if ((N > INT16_MAX) || (N < INT16_MIN))
782 return "out of range number";
795 return "invalid number";
796 if ((N > INT32_MAX) || (N < INT32_MIN))
797 return "out of range number";
810 return "invalid number";
824 return "invalid floating point number";
837 return "invalid floating point number";
843 Out <<
format(
"0x%02X", Num);
847 unsigned long long n;
849 return "invalid hex8 number";
851 return "out of range hex8 number";
858 Out <<
format(
"0x%04X", Num);
862 unsigned long long n;
864 return "invalid hex16 number";
866 return "out of range hex16 number";
873 Out <<
format(
"0x%08X", Num);
877 unsigned long long n;
879 return "invalid hex32 number";
880 if (n > 0xFFFFFFFFUL)
881 return "out of range hex32 number";
888 Out <<
format(
"0x%016llX", Num);
892 unsigned long long Num;
894 return "invalid hex64 number";
virtual unsigned beginSequence()
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
bool preflightDocument(unsigned)
size_t size() const
size - Get the string size.
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
This is an iterator abstraction over YAML collections shared by both sequences and maps...
Output(llvm::raw_ostream &, void *Ctxt=NULL)
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.
virtual void endFlowSequence()
double strtod(const char *nptr, char **endptr);
virtual bool mapTag(StringRef, bool)
virtual bool matchEnumScalar(const char *, bool)
#define llvm_unreachable(msg)
virtual bool outputting() const
format_object1< T > format(const char *Fmt, const T &Val)
virtual bool preflightFlowElement(unsigned, void *&)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
const char * data() const
virtual bool canElideEmptySequence()
virtual void beginEnumScalar()
StringMapIterator< HNode * > iterator
virtual void endMapping()
void postflightDocument()
virtual bool beginBitSetScalar(bool &)
virtual void endBitSetScalar()
char back() const
back - Get the last character in the string.
void(* DiagHandlerTy)(const SMDiagnostic &, void *Context)
virtual void postflightFlowElement(void *)
virtual void beginMapping()
virtual void endSequence()
size_t find_first_not_of(char C, size_t From=0) const
virtual void scalarString(StringRef &)
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.
virtual void postflightKey(void *)
size_t strlen(const char *s);
void * Allocate(size_t Size, size_t Alignment)
virtual unsigned beginFlowSequence()
bool equals(StringRef RHS) const
virtual bool preflightElement(unsigned, void *&)
virtual void endEnumScalar()
virtual bool bitSetMatch(const char *, bool)
Represents a YAML map created from either a block map for a flow map.
virtual void postflightElement(void *)
virtual void setError(const Twine &message)
char front() const
front - Get the first character in the string.
LLVM Value Representation.
void setDiagHandler(DiagHandlerTy DH, void *Ctx=0)
virtual bool preflightKey(const char *key, bool, bool, bool &, void *&)
error_code make_error_code(errc _e)
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result)
bool empty() const
empty - Check if the string is empty.
Abstract base class for all Nodes.