Skip to content

Commit

Permalink
Allow using MemoryBuffers with yaml::Stream directly.
Browse files Browse the repository at this point in the history
The rationale is to get YAML filenames in diagnostics from
yaml::Stream::printError -- currently the filename is hard-coded as
"YAML" because there's no buffer information available.

Patch by Kim Gräsman!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168341 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
chisophugis committed Nov 19, 2012
1 parent c4639d6 commit 525398e
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/llvm/Support/YAMLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ std::string escape(StringRef Input);
/// documents.
class Stream {
public:
/// @brief This keeps a reference to the string referenced by \p Input.
Stream(StringRef Input, SourceMgr &);

/// @brief This takes ownership of \p InputBuffer.
Stream(MemoryBuffer *InputBuffer, SourceMgr &);
~Stream();

document_iterator begin();
Expand Down
20 changes: 20 additions & 0 deletions lib/Support/YAMLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ namespace yaml {
class Scanner {
public:
Scanner(const StringRef Input, SourceMgr &SM);
Scanner(MemoryBuffer *Buffer, SourceMgr &SM_);

/// @brief Parse the next token and return it without popping it.
Token &peekNext();
Expand Down Expand Up @@ -708,6 +709,21 @@ Scanner::Scanner(StringRef Input, SourceMgr &sm)
End = InputBuffer->getBufferEnd();
}

Scanner::Scanner(MemoryBuffer *Buffer, SourceMgr &SM_)
: SM(SM_)
, InputBuffer(Buffer)
, Current(InputBuffer->getBufferStart())
, End(InputBuffer->getBufferEnd())
, Indent(-1)
, Column(0)
, Line(0)
, FlowLevel(0)
, IsStartOfStream(true)
, IsSimpleKeyAllowed(true)
, Failed(false) {
SM.AddNewSourceBuffer(InputBuffer, SMLoc());
}

Token &Scanner::peekNext() {
// If the current token is a possible simple key, keep parsing until we
// can confirm.
Expand Down Expand Up @@ -1532,6 +1548,10 @@ Stream::Stream(StringRef Input, SourceMgr &SM)
: scanner(new Scanner(Input, SM))
, CurrentDoc(0) {}

Stream::Stream(MemoryBuffer *InputBuffer, SourceMgr &SM)
: scanner(new Scanner(InputBuffer, SM))
, CurrentDoc(0) {}

Stream::~Stream() {}

bool Stream::failed() { return scanner->failed(); }
Expand Down
34 changes: 34 additions & 0 deletions unittests/Support/YAMLParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "gtest/gtest.h"
Expand All @@ -21,6 +22,12 @@ static void SuppressDiagnosticsOutput(const SMDiagnostic &, void *) {
// to reduce noise in unit test runs.
}

// Assumes Ctx is an SMDiagnostic where Diag can be stored.
static void CollectDiagnosticsOutput(const SMDiagnostic &Diag, void *Ctx) {
SMDiagnostic* DiagOut = static_cast<SMDiagnostic*>(Ctx);
*DiagOut = Diag;
}

// Checks that the given input gives a parse error. Makes sure that an error
// text is available and the parse fails.
static void ExpectParseError(StringRef Message, StringRef Input) {
Expand Down Expand Up @@ -182,4 +189,31 @@ TEST(YAMLParser, WorksWithIteratorAlgorithms) {
EXPECT_EQ(6, std::distance(Array->begin(), Array->end()));
}

TEST(YAMLParser, DefaultDiagnosticFilename) {
SourceMgr SM;

SMDiagnostic GeneratedDiag;
SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag);

// When we construct a YAML stream over an unnamed string,
// the filename is hard-coded as "YAML".
yaml::Stream UnnamedStream("[]", SM);
UnnamedStream.printError(UnnamedStream.begin()->getRoot(), "Hello, World!");
EXPECT_EQ("YAML", GeneratedDiag.getFilename());
}

TEST(YAMLParser, DiagnosticFilenameFromBufferID) {
SourceMgr SM;

SMDiagnostic GeneratedDiag;
SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag);

// When we construct a YAML stream over a named buffer,
// we get its ID as filename in diagnostics.
MemoryBuffer* Buffer = MemoryBuffer::getMemBuffer("[]", "buffername.yaml");
yaml::Stream Stream(Buffer, SM);
Stream.printError(Stream.begin()->getRoot(), "Hello, World!");
EXPECT_EQ("buffername.yaml", GeneratedDiag.getFilename());
}

} // end namespace llvm

0 comments on commit 525398e

Please sign in to comment.