summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Remarks/RemarkParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Remarks/RemarkParser.cpp')
-rw-r--r--llvm/lib/Remarks/RemarkParser.cpp143
1 files changed, 46 insertions, 97 deletions
diff --git a/llvm/lib/Remarks/RemarkParser.cpp b/llvm/lib/Remarks/RemarkParser.cpp
index 41ed64d022b..46130d28f72 100644
--- a/llvm/lib/Remarks/RemarkParser.cpp
+++ b/llvm/lib/Remarks/RemarkParser.cpp
@@ -20,69 +20,7 @@
using namespace llvm;
using namespace llvm::remarks;
-static std::unique_ptr<ParserImpl> formatToParserImpl(Format ParserFormat,
- StringRef Buf) {
- switch (ParserFormat) {
- case Format::YAML:
- return llvm::make_unique<YAMLParserImpl>(Buf);
- case Format::Unknown:
- llvm_unreachable("Unhandled llvm::remarks::ParserFormat enum");
- return nullptr;
- };
-}
-
-static std::unique_ptr<ParserImpl>
-formatToParserImpl(Format ParserFormat, StringRef Buf,
- const ParsedStringTable &StrTab) {
- switch (ParserFormat) {
- case Format::YAML:
- return llvm::make_unique<YAMLParserImpl>(Buf, &StrTab);
- case Format::Unknown:
- llvm_unreachable("Unhandled llvm::remarks::ParserFormat enum");
- return nullptr;
- };
-}
-
-Parser::Parser(Format ParserFormat, StringRef Buf)
- : Impl(formatToParserImpl(ParserFormat, Buf)) {}
-
-Parser::Parser(Format ParserFormat, StringRef Buf,
- const ParsedStringTable &StrTab)
- : Impl(formatToParserImpl(ParserFormat, Buf, StrTab)) {}
-
-Parser::~Parser() = default;
-
-static Expected<const Remark *> getNextYAML(YAMLParserImpl &Impl) {
- YAMLRemarkParser &YAMLParser = Impl.YAMLParser;
- // Check for EOF.
- if (Impl.YAMLIt == Impl.YAMLParser.Stream.end())
- return nullptr;
-
- auto CurrentIt = Impl.YAMLIt;
-
- // Try to parse an entry.
- if (Error E = YAMLParser.parseYAMLElement(*CurrentIt)) {
- // Set the iterator to the end, in case the user calls getNext again.
- Impl.YAMLIt = Impl.YAMLParser.Stream.end();
- return std::move(E);
- }
-
- // Move on.
- ++Impl.YAMLIt;
-
- // Return the just-parsed remark.
- if (const Optional<YAMLRemarkParser::ParseState> &State = YAMLParser.State)
- return &State->TheRemark;
- else
- return createStringError(std::make_error_code(std::errc::invalid_argument),
- "unexpected error while parsing.");
-}
-
-Expected<const Remark *> Parser::getNext() const {
- if (auto *Impl = dyn_cast<YAMLParserImpl>(this->Impl.get()))
- return getNextYAML(*Impl);
- llvm_unreachable("Get next called with an unknown parsing implementation.");
-}
+char EndOfFileError::ID = 0;
ParsedStringTable::ParsedStringTable(StringRef InBuffer) : Buffer(InBuffer) {
while (!InBuffer.empty()) {
@@ -109,59 +47,70 @@ Expected<StringRef> ParsedStringTable::operator[](size_t Index) const {
return StringRef(Buffer.data() + Offset, NextOffset - Offset - 1);
}
+Expected<std::unique_ptr<Parser>>
+llvm::remarks::createRemarkParser(Format ParserFormat, StringRef Buf,
+ Optional<const ParsedStringTable *> StrTab) {
+ switch (ParserFormat) {
+ case Format::YAML:
+ return llvm::make_unique<YAMLRemarkParser>(Buf, StrTab);
+ case Format::Unknown:
+ return createStringError(std::make_error_code(std::errc::invalid_argument),
+ "Unknown remark parser format.");
+ }
+}
+
+// Wrapper that holds the state needed to interact with the C API.
+struct CParser {
+ std::unique_ptr<Parser> TheParser;
+ Optional<std::string> Err;
+
+ CParser(Format ParserFormat, StringRef Buf,
+ Optional<const ParsedStringTable *> StrTab = None)
+ : TheParser(cantFail(createRemarkParser(ParserFormat, Buf, StrTab))) {}
+
+ void handleError(Error E) { Err.emplace(toString(std::move(E))); }
+ bool hasError() const { return Err.hasValue(); }
+ const char *getMessage() const { return Err ? Err->c_str() : nullptr; };
+};
+
// Create wrappers for C Binding types (see CBindingWrapping.h).
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(remarks::Parser, LLVMRemarkParserRef)
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(CParser, LLVMRemarkParserRef)
extern "C" LLVMRemarkParserRef LLVMRemarkParserCreateYAML(const void *Buf,
uint64_t Size) {
- return wrap(new remarks::Parser(
- remarks::Format::YAML, StringRef(static_cast<const char *>(Buf), Size)));
-}
-
-static void handleYAMLError(remarks::YAMLParserImpl &Impl, Error E) {
- handleAllErrors(
- std::move(E),
- [&](const YAMLParseError &PE) {
- Impl.YAMLParser.Stream.printError(&PE.getNode(),
- Twine(PE.getMessage()) + Twine('\n'));
- },
- [&](const ErrorInfoBase &EIB) { EIB.log(Impl.YAMLParser.ErrorStream); });
- Impl.HasErrors = true;
+ return wrap(new CParser(Format::YAML,
+ StringRef(static_cast<const char *>(Buf), Size)));
}
extern "C" LLVMRemarkEntryRef
LLVMRemarkParserGetNext(LLVMRemarkParserRef Parser) {
- remarks::Parser &TheParser = *unwrap(Parser);
-
- Expected<const remarks::Remark *> RemarkOrErr = TheParser.getNext();
- if (!RemarkOrErr) {
- // Error during parsing.
- if (auto *Impl = dyn_cast<remarks::YAMLParserImpl>(TheParser.Impl.get()))
- handleYAMLError(*Impl, RemarkOrErr.takeError());
- else
- llvm_unreachable("unkown parser implementation.");
+ CParser &TheCParser = *unwrap(Parser);
+ remarks::Parser &TheParser = *TheCParser.TheParser;
+
+ Expected<std::unique_ptr<Remark>> MaybeRemark = TheParser.next();
+ if (Error E = MaybeRemark.takeError()) {
+ if (E.isA<EndOfFileError>()) {
+ consumeError(std::move(E));
+ return nullptr;
+ }
+
+ // Handle the error. Allow it to be checked through HasError and
+ // GetErrorMessage.
+ TheCParser.handleError(std::move(E));
return nullptr;
}
- if (*RemarkOrErr == nullptr)
- return nullptr;
// Valid remark.
- return wrap(*RemarkOrErr);
+ return wrap(MaybeRemark->release());
}
extern "C" LLVMBool LLVMRemarkParserHasError(LLVMRemarkParserRef Parser) {
- if (auto *Impl =
- dyn_cast<remarks::YAMLParserImpl>(unwrap(Parser)->Impl.get()))
- return Impl->HasErrors;
- llvm_unreachable("unkown parser implementation.");
+ return unwrap(Parser)->hasError();
}
extern "C" const char *
LLVMRemarkParserGetErrorMessage(LLVMRemarkParserRef Parser) {
- if (auto *Impl =
- dyn_cast<remarks::YAMLParserImpl>(unwrap(Parser)->Impl.get()))
- return Impl->YAMLParser.ErrorStream.str().c_str();
- llvm_unreachable("unkown parser implementation.");
+ return unwrap(Parser)->getMessage();
}
extern "C" void LLVMRemarkParserDispose(LLVMRemarkParserRef Parser) {
OpenPOWER on IntegriCloud