#ifndef LLVM_SUPPORT_YAMLPARSER_H
#define LLVM_SUPPORT_YAMLPARSER_H
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SMLoc.h"
#include <utility>
namespace llvm {
-class MemoryBuffer;
+class MemoryBufferRef;
class SourceMgr;
-class raw_ostream;
class Twine;
+class raw_ostream;
namespace yaml {
class Stream {
public:
/// \brief This keeps a reference to the string referenced by \p Input.
- Stream(StringRef Input, SourceMgr &);
+ Stream(StringRef Input, SourceMgr &, bool ShowColors = true);
- /// \brief This takes ownership of \p InputBuffer.
- Stream(MemoryBuffer *InputBuffer, SourceMgr &);
+ Stream(MemoryBufferRef InputBuffer, SourceMgr &, bool ShowColors = true);
~Stream();
document_iterator begin();
/// \brief Abstract base class for all Nodes.
class Node {
- virtual void anchor();
+ virtual void anchor();
+
public:
enum NodeKind {
NK_Null,
NK_Scalar,
+ NK_BlockScalar,
NK_KeyValue,
NK_Mapping,
NK_Sequence,
unsigned int getType() const { return TypeID; }
- void *operator new ( size_t Size
- , BumpPtrAllocator &Alloc
- , size_t Alignment = 16) throw() {
+ void *operator new(size_t Size, BumpPtrAllocator &Alloc,
+ size_t Alignment = 16) throw() {
return Alloc.Allocate(Size, Alignment);
}
- void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t) throw() {
- Alloc.Deallocate(Ptr);
+ void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t Size) throw() {
+ Alloc.Deallocate(Ptr, Size);
}
protected:
void operator delete(void *) throw() {}
- virtual ~Node() {}
+ ~Node() = default;
private:
unsigned int TypeID;
///
/// Example:
/// !!null null
-class NullNode : public Node {
+class NullNode final : public Node {
void anchor() override;
+
public:
NullNode(std::unique_ptr<Document> &D)
: Node(NK_Null, D, StringRef(), StringRef()) {}
- static inline bool classof(const Node *N) {
- return N->getType() == NK_Null;
- }
+ static inline bool classof(const Node *N) { return N->getType() == NK_Null; }
};
/// \brief A scalar node is an opaque datum that can be presented as a
///
/// Example:
/// Adena
-class ScalarNode : public Node {
+class ScalarNode final : public Node {
void anchor() override;
+
public:
ScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
StringRef Val)
private:
StringRef Value;
- StringRef unescapeDoubleQuoted( StringRef UnquotedValue
- , StringRef::size_type Start
- , SmallVectorImpl<char> &Storage) const;
+ StringRef unescapeDoubleQuoted(StringRef UnquotedValue,
+ StringRef::size_type Start,
+ SmallVectorImpl<char> &Storage) const;
+};
+
+/// \brief A block scalar node is an opaque datum that can be presented as a
+/// series of zero or more Unicode scalar values.
+///
+/// Example:
+/// |
+/// Hello
+/// World
+class BlockScalarNode final : public Node {
+ void anchor() override;
+
+public:
+ BlockScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
+ StringRef Value, StringRef RawVal)
+ : Node(NK_BlockScalar, D, Anchor, Tag), Value(Value) {
+ SMLoc Start = SMLoc::getFromPointer(RawVal.begin());
+ SMLoc End = SMLoc::getFromPointer(RawVal.end());
+ SourceRange = SMRange(Start, End);
+ }
+
+ /// \brief Gets the value of this node as a StringRef.
+ StringRef getValue() const { return Value; }
+
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_BlockScalar;
+ }
+
+private:
+ StringRef Value;
};
/// \brief A key and value pair. While not technically a Node under the YAML
///
/// Example:
/// Section: .text
-class KeyValueNode : public Node {
+class KeyValueNode final : public Node {
void anchor() override;
+
public:
KeyValueNode(std::unique_ptr<Document> &D)
- : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(nullptr),
- Value(nullptr) {}
+ : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(nullptr),
+ Value(nullptr) {}
/// \brief Parse and return the key.
///
void skip() override {
getKey()->skip();
- getValue()->skip();
+ if (Node *Val = getValue())
+ Val->skip();
}
static inline bool classof(const Node *N) {
/// increment() which must set CurrentEntry to 0 to create an end iterator.
template <class BaseT, class ValueT>
class basic_collection_iterator
- : public std::iterator<std::forward_iterator_tag, ValueT> {
+ : public std::iterator<std::forward_iterator_tag, ValueT> {
public:
basic_collection_iterator() : Base(nullptr) {}
basic_collection_iterator(BaseT *B) : Base(B) {}
- ValueT *operator ->() const {
+ ValueT *operator->() const {
assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
return Base->CurrentEntry;
}
- ValueT &operator *() const {
+ ValueT &operator*() const {
assert(Base && Base->CurrentEntry &&
"Attempted to dereference end iterator!");
return *Base->CurrentEntry;
}
- operator ValueT*() const {
+ operator ValueT *() const {
assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
return Base->CurrentEntry;
}
- bool operator !=(const basic_collection_iterator &Other) const {
- if(Base != Other.Base)
+ bool operator!=(const basic_collection_iterator &Other) const {
+ if (Base != Other.Base)
return true;
- return (Base && Other.Base) && Base->CurrentEntry
- != Other.Base->CurrentEntry;
+ return (Base && Other.Base) &&
+ Base->CurrentEntry != Other.Base->CurrentEntry;
}
basic_collection_iterator &operator++() {
return ret;
}
-template <class CollectionType>
-void skip(CollectionType &C) {
+template <class CollectionType> void skip(CollectionType &C) {
// TODO: support skipping from the middle of a parsed collection ;/
assert((C.IsAtBeginning || C.IsAtEnd) && "Cannot skip mid parse!");
if (C.IsAtBeginning)
- for (typename CollectionType::iterator i = begin(C), e = C.end();
- i != e; ++i)
+ for (typename CollectionType::iterator i = begin(C), e = C.end(); i != e;
+ ++i)
i->skip();
}
/// Example:
/// Name: _main
/// Scope: Global
-class MappingNode : public Node {
+class MappingNode final : public Node {
void anchor() override;
+
public:
enum MappingType {
MT_Block,
template <class T> friend typename T::iterator yaml::begin(T &);
template <class T> friend void yaml::skip(T &);
- iterator begin() {
- return yaml::begin(*this);
- }
+ iterator begin() { return yaml::begin(*this); }
iterator end() { return iterator(); }
- void skip() override {
- yaml::skip(*this);
- }
+ void skip() override { yaml::skip(*this); }
static inline bool classof(const Node *N) {
return N->getType() == NK_Mapping;
/// Example:
/// - Hello
/// - World
-class SequenceNode : public Node {
+class SequenceNode final : public Node {
void anchor() override;
+
public:
enum SequenceType {
ST_Block,
void increment();
- iterator begin() {
- return yaml::begin(*this);
- }
+ iterator begin() { return yaml::begin(*this); }
iterator end() { return iterator(); }
- void skip() override {
- yaml::skip(*this);
- }
+ void skip() override { yaml::skip(*this); }
static inline bool classof(const Node *N) {
return N->getType() == NK_Sequence;
///
/// Example:
/// *AnchorName
-class AliasNode : public Node {
+class AliasNode final : public Node {
void anchor() override;
+
public:
AliasNode(std::unique_ptr<Document> &D, StringRef Val)
: Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
StringRef getName() const { return Name; }
Node *getTarget();
- static inline bool classof(const Node *N) {
- return N->getType() == NK_Alias;
- }
+ static inline bool classof(const Node *N) { return N->getType() == NK_Alias; }
private:
StringRef Name;
return Root = parseBlockNode();
}
- const std::map<StringRef, StringRef> &getTagMap() const {
- return TagMap;
- }
+ const std::map<StringRef, StringRef> &getTagMap() const { return TagMap; }
private:
friend class Node;
document_iterator() : Doc(nullptr) {}
document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {}
- bool operator ==(const document_iterator &Other) {
+ bool operator==(const document_iterator &Other) {
if (isAtEnd() || Other.isAtEnd())
return isAtEnd() && Other.isAtEnd();
return Doc == Other.Doc;
}
- bool operator !=(const document_iterator &Other) {
- return !(*this == Other);
- }
+ bool operator!=(const document_iterator &Other) { return !(*this == Other); }
- document_iterator operator ++() {
+ document_iterator operator++() {
assert(Doc && "incrementing iterator past the end.");
if (!(*Doc)->skip()) {
Doc->reset(nullptr);
return *this;
}
- Document &operator *() {
- return *Doc->get();
- }
+ Document &operator*() { return *Doc->get(); }
std::unique_ptr<Document> &operator->() { return *Doc; }
private:
- bool isAtEnd() const {
- return !Doc || !*Doc;
- }
+ bool isAtEnd() const { return !Doc || !*Doc; }
std::unique_ptr<Document> *Doc;
};
-}
-}
+} // End namespace yaml.
+
+} // End namespace llvm.
#endif