Index: llvm/include/llvm/Support/YAMLTraits.h =================================================================== --- llvm/include/llvm/Support/YAMLTraits.h +++ llvm/include/llvm/Support/YAMLTraits.h @@ -951,6 +951,258 @@ void *Ctxt; }; +/// +/// The Input class is used to parse a yaml document into in-memory structs +/// and vectors. +/// +/// It works by using YAMLParser to do a syntax parse of the entire yaml +/// document, then the Input class builds a graph of HNodes which wraps +/// each yaml Node. The extra layer is buffering. The low level yaml +/// parser only lets you look at each node once. The buffering layer lets +/// you search and interate multiple times. This is necessary because +/// the mapRequired() method calls may not be in the same order +/// as the keys in the document. +/// +class Input : public IO { +public: + // Construct a yaml Input object from a StringRef and optional + // user-data. The DiagHandler can be specified to provide + // alternative error reporting. + Input(StringRef InputContent, void *Ctxt = nullptr, + SourceMgr::DiagHandlerTy DiagHandler = nullptr, + void *DiagHandlerCtxt = nullptr); + Input(MemoryBufferRef Input, void *Ctxt = nullptr, + SourceMgr::DiagHandlerTy DiagHandler = nullptr, + void *DiagHandlerCtxt = nullptr); + ~Input() override; + + // Check if there was an syntax or semantic error during parsing. + std::error_code error(); + +private: + bool outputting() const override; + bool mapTag(StringRef, bool) override; + void beginMapping() override; + void endMapping() override; + bool preflightKey(const char *, bool, bool, bool &, void *&) override; + void postflightKey(void *) override; + std::vector keys() override; + void beginFlowMapping() override; + void endFlowMapping() override; + unsigned beginSequence() override; + void endSequence() override; + bool preflightElement(unsigned index, void *&) override; + void postflightElement(void *) override; + unsigned beginFlowSequence() override; + bool preflightFlowElement(unsigned, void *&) override; + void postflightFlowElement(void *) override; + void endFlowSequence() override; + void beginEnumScalar() override; + bool matchEnumScalar(const char *, bool) override; + bool matchEnumFallback() override; + void endEnumScalar() override; + bool beginBitSetScalar(bool &) override; + bool bitSetMatch(const char *, bool) override; + void endBitSetScalar() override; + void scalarString(StringRef &, QuotingType) override; + void blockScalarString(StringRef &) override; + void scalarTag(std::string &) override; + NodeKind getNodeKind() override; + void setError(const Twine &message) override; + bool canElideEmptySequence() override; + + class HNode { + virtual void anchor(); + + public: + HNode(Node *n) : _node(n) {} + virtual ~HNode() = default; + + static bool classof(const HNode *) { return true; } + + Node *_node; + }; + + class EmptyHNode : public HNode { + void anchor() override; + + public: + EmptyHNode(Node *n) : HNode(n) {} + + static bool classof(const HNode *n) { return NullNode::classof(n->_node); } + + static bool classof(const EmptyHNode *) { return true; } + }; + + class ScalarHNode : public HNode { + void anchor() override; + + public: + ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) {} + + StringRef value() const { return _value; } + + static bool classof(const HNode *n) { + return ScalarNode::classof(n->_node) || + BlockScalarNode::classof(n->_node); + } + + static bool classof(const ScalarHNode *) { return true; } + + protected: + StringRef _value; + }; + + class MapHNode : public HNode { + void anchor() override; + + public: + MapHNode(Node *n) : HNode(n) {} + + static bool classof(const HNode *n) { + return MappingNode::classof(n->_node); + } + + static bool classof(const MapHNode *) { return true; } + + using NameToNode = StringMap>; + + NameToNode Mapping; + SmallVector ValidKeys; + }; + + class SequenceHNode : public HNode { + void anchor() override; + + public: + SequenceHNode(Node *n) : HNode(n) {} + + static bool classof(const HNode *n) { + return SequenceNode::classof(n->_node); + } + + static bool classof(const SequenceHNode *) { return true; } + + std::vector> Entries; + }; + + std::unique_ptr createHNodes(Node *node); + void setError(HNode *hnode, const Twine &message); + void setError(Node *node, const Twine &message); + +public: + // These are only used by operator>>. They could be private + // if those templated things could be made friends. + bool setCurrentDocument(); + bool nextDocument(); + + /// Returns the current node that's being parsed by the YAML Parser. + const Node *getCurrentNode() const; + +private: + SourceMgr SrcMgr; // must be before Strm + std::unique_ptr Strm; + std::unique_ptr TopNode; + std::error_code EC; + BumpPtrAllocator StringAllocator; + document_iterator DocIterator; + std::vector BitValuesUsed; + HNode *CurrentNode = nullptr; + bool ScalarMatchFound = false; +}; + +/// +/// The Output class is used to generate a yaml document from in-memory structs +/// and vectors. +/// +class Output : public IO { +public: + Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70); + ~Output() override; + + /// Set whether or not to output optional values which are equal + /// to the default value. By default, when outputting if you attempt + /// to write a value that is equal to the default, the value gets ignored. + /// Sometimes, it is useful to be able to see these in the resulting YAML + /// anyway. + void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; } + + bool outputting() const override; + bool mapTag(StringRef, bool) override; + void beginMapping() override; + void endMapping() override; + bool preflightKey(const char *key, bool, bool, bool &, void *&) override; + void postflightKey(void *) override; + std::vector keys() override; + void beginFlowMapping() override; + void endFlowMapping() override; + unsigned beginSequence() override; + void endSequence() override; + bool preflightElement(unsigned, void *&) override; + void postflightElement(void *) override; + unsigned beginFlowSequence() override; + bool preflightFlowElement(unsigned, void *&) override; + void postflightFlowElement(void *) override; + void endFlowSequence() override; + void beginEnumScalar() override; + bool matchEnumScalar(const char *, bool) override; + bool matchEnumFallback() override; + void endEnumScalar() override; + bool beginBitSetScalar(bool &) override; + bool bitSetMatch(const char *, bool) override; + void endBitSetScalar() override; + void scalarString(StringRef &, QuotingType) override; + void blockScalarString(StringRef &) override; + void scalarTag(std::string &) override; + NodeKind getNodeKind() override; + void setError(const Twine &message) override; + bool canElideEmptySequence() override; + + // These are only used by operator<<. They could be private + // if that templated operator could be made a friend. + void beginDocuments(); + bool preflightDocument(unsigned); + void postflightDocument(); + void endDocuments(); + +private: + void output(StringRef s); + void outputUpToEndOfLine(StringRef s); + void newLineCheck(); + void outputNewLine(); + void paddedKey(StringRef key); + void flowKey(StringRef Key); + + enum InState { + inSeqFirstElement, + inSeqOtherElement, + inFlowSeqFirstElement, + inFlowSeqOtherElement, + inMapFirstKey, + inMapOtherKey, + inFlowMapFirstKey, + inFlowMapOtherKey + }; + + static bool inSeqAnyElement(InState State); + static bool inFlowSeqAnyElement(InState State); + static bool inMapAnyKey(InState State); + static bool inFlowMapAnyKey(InState State); + + raw_ostream &Out; + int WrapColumn; + SmallVector StateStack; + int Column = 0; + int ColumnAtFlowStart = 0; + int ColumnAtMapFlowStart = 0; + bool NeedBitValueComma = false; + bool NeedFlowSequenceComma = false; + bool EnumerationMatchFound = false; + bool WriteDefaultValues = false; + StringRef Padding; + StringRef PaddingBeforeContainer; +}; + namespace detail { template @@ -1372,260 +1624,6 @@ TFinal &Result; }; -/// -/// The Input class is used to parse a yaml document into in-memory structs -/// and vectors. -/// -/// It works by using YAMLParser to do a syntax parse of the entire yaml -/// document, then the Input class builds a graph of HNodes which wraps -/// each yaml Node. The extra layer is buffering. The low level yaml -/// parser only lets you look at each node once. The buffering layer lets -/// you search and interate multiple times. This is necessary because -/// the mapRequired() method calls may not be in the same order -/// as the keys in the document. -/// -class Input : public IO { -public: - // Construct a yaml Input object from a StringRef and optional - // user-data. The DiagHandler can be specified to provide - // alternative error reporting. - Input(StringRef InputContent, - void *Ctxt = nullptr, - SourceMgr::DiagHandlerTy DiagHandler = nullptr, - void *DiagHandlerCtxt = nullptr); - Input(MemoryBufferRef Input, - void *Ctxt = nullptr, - SourceMgr::DiagHandlerTy DiagHandler = nullptr, - void *DiagHandlerCtxt = nullptr); - ~Input() override; - - // Check if there was an syntax or semantic error during parsing. - std::error_code error(); - -private: - bool outputting() const override; - bool mapTag(StringRef, bool) override; - void beginMapping() override; - void endMapping() override; - bool preflightKey(const char *, bool, bool, bool &, void *&) override; - void postflightKey(void *) override; - std::vector keys() override; - void beginFlowMapping() override; - void endFlowMapping() override; - unsigned beginSequence() override; - void endSequence() override; - bool preflightElement(unsigned index, void *&) override; - void postflightElement(void *) override; - unsigned beginFlowSequence() override; - bool preflightFlowElement(unsigned , void *&) override; - void postflightFlowElement(void *) override; - void endFlowSequence() override; - void beginEnumScalar() override; - bool matchEnumScalar(const char*, bool) override; - bool matchEnumFallback() override; - void endEnumScalar() override; - bool beginBitSetScalar(bool &) override; - bool bitSetMatch(const char *, bool ) override; - void endBitSetScalar() override; - void scalarString(StringRef &, QuotingType) override; - void blockScalarString(StringRef &) override; - void scalarTag(std::string &) override; - NodeKind getNodeKind() override; - void setError(const Twine &message) override; - bool canElideEmptySequence() override; - - class HNode { - virtual void anchor(); - - public: - HNode(Node *n) : _node(n) { } - virtual ~HNode() = default; - - static bool classof(const HNode *) { return true; } - - Node *_node; - }; - - class EmptyHNode : public HNode { - void anchor() override; - - public: - EmptyHNode(Node *n) : HNode(n) { } - - static bool classof(const HNode *n) { return NullNode::classof(n->_node); } - - static bool classof(const EmptyHNode *) { return true; } - }; - - class ScalarHNode : public HNode { - void anchor() override; - - public: - ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { } - - StringRef value() const { return _value; } - - static bool classof(const HNode *n) { - return ScalarNode::classof(n->_node) || - BlockScalarNode::classof(n->_node); - } - - static bool classof(const ScalarHNode *) { return true; } - - protected: - StringRef _value; - }; - - class MapHNode : public HNode { - void anchor() override; - - public: - MapHNode(Node *n) : HNode(n) { } - - static bool classof(const HNode *n) { - return MappingNode::classof(n->_node); - } - - static bool classof(const MapHNode *) { return true; } - - using NameToNode = StringMap>; - - NameToNode Mapping; - SmallVector ValidKeys; - }; - - class SequenceHNode : public HNode { - void anchor() override; - - public: - SequenceHNode(Node *n) : HNode(n) { } - - static bool classof(const HNode *n) { - return SequenceNode::classof(n->_node); - } - - static bool classof(const SequenceHNode *) { return true; } - - std::vector> Entries; - }; - - std::unique_ptr createHNodes(Node *node); - void setError(HNode *hnode, const Twine &message); - void setError(Node *node, const Twine &message); - -public: - // These are only used by operator>>. They could be private - // if those templated things could be made friends. - bool setCurrentDocument(); - bool nextDocument(); - - /// Returns the current node that's being parsed by the YAML Parser. - const Node *getCurrentNode() const; - -private: - SourceMgr SrcMgr; // must be before Strm - std::unique_ptr Strm; - std::unique_ptr TopNode; - std::error_code EC; - BumpPtrAllocator StringAllocator; - document_iterator DocIterator; - std::vector BitValuesUsed; - HNode *CurrentNode = nullptr; - bool ScalarMatchFound = false; -}; - -/// -/// The Output class is used to generate a yaml document from in-memory structs -/// and vectors. -/// -class Output : public IO { -public: - Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70); - ~Output() override; - - /// Set whether or not to output optional values which are equal - /// to the default value. By default, when outputting if you attempt - /// to write a value that is equal to the default, the value gets ignored. - /// Sometimes, it is useful to be able to see these in the resulting YAML - /// anyway. - void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; } - - bool outputting() const override; - bool mapTag(StringRef, bool) override; - void beginMapping() override; - void endMapping() override; - bool preflightKey(const char *key, bool, bool, bool &, void *&) override; - void postflightKey(void *) override; - std::vector keys() override; - void beginFlowMapping() override; - void endFlowMapping() override; - unsigned beginSequence() override; - void endSequence() override; - bool preflightElement(unsigned, void *&) override; - void postflightElement(void *) override; - unsigned beginFlowSequence() override; - bool preflightFlowElement(unsigned, void *&) override; - void postflightFlowElement(void *) override; - void endFlowSequence() override; - void beginEnumScalar() override; - bool matchEnumScalar(const char*, bool) override; - bool matchEnumFallback() override; - void endEnumScalar() override; - bool beginBitSetScalar(bool &) override; - bool bitSetMatch(const char *, bool ) override; - void endBitSetScalar() override; - void scalarString(StringRef &, QuotingType) override; - void blockScalarString(StringRef &) override; - void scalarTag(std::string &) override; - NodeKind getNodeKind() override; - void setError(const Twine &message) override; - bool canElideEmptySequence() override; - - // These are only used by operator<<. They could be private - // if that templated operator could be made a friend. - void beginDocuments(); - bool preflightDocument(unsigned); - void postflightDocument(); - void endDocuments(); - -private: - void output(StringRef s); - void outputUpToEndOfLine(StringRef s); - void newLineCheck(); - void outputNewLine(); - void paddedKey(StringRef key); - void flowKey(StringRef Key); - - enum InState { - inSeqFirstElement, - inSeqOtherElement, - inFlowSeqFirstElement, - inFlowSeqOtherElement, - inMapFirstKey, - inMapOtherKey, - inFlowMapFirstKey, - inFlowMapOtherKey - }; - - static bool inSeqAnyElement(InState State); - static bool inFlowSeqAnyElement(InState State); - static bool inMapAnyKey(InState State); - static bool inFlowMapAnyKey(InState State); - - raw_ostream &Out; - int WrapColumn; - SmallVector StateStack; - int Column = 0; - int ColumnAtFlowStart = 0; - int ColumnAtMapFlowStart = 0; - bool NeedBitValueComma = false; - bool NeedFlowSequenceComma = false; - bool EnumerationMatchFound = false; - bool WriteDefaultValues = false; - StringRef Padding; - StringRef PaddingBeforeContainer; -}; - /// YAML I/O does conversion based on types. But often native data types /// are just a typedef of built in intergral types (e.g. int). But the C++ /// type matching system sees through the typedef and all the typedefed types