//===-- YAMLRemarkParser.h - Parser for YAML remarks ------------*- C++/-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file provides the impementation of the YAML remark parser. // //===----------------------------------------------------------------------===// #ifndef LLVM_REMARKS_YAML_REMARK_PARSER_H #define LLVM_REMARKS_YAML_REMARK_PARSER_H #include "llvm/Remarks/Remark.h" #include "llvm/Remarks/RemarkParser.h" #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" #include #include namespace llvm { namespace remarks { class YAMLParseError : public ErrorInfo { public: static char ID; YAMLParseError(StringRef Message, SourceMgr &SM, yaml::Stream &Stream, yaml::Node &Node); YAMLParseError(StringRef Message) : Message(std::string(Message)) {} void log(raw_ostream &OS) const override { OS << Message; } std::error_code convertToErrorCode() const override { return inconvertibleErrorCode(); } private: std::string Message; }; /// Regular YAML to Remark parser. struct YAMLRemarkParser : public RemarkParser { /// The string table used for parsing strings. std::optional StrTab; /// Last error message that can come from the YAML parser diagnostics. /// We need this for catching errors in the constructor. std::string LastErrorMessage; /// Source manager for better error messages. SourceMgr SM; /// Stream for yaml parsing. yaml::Stream Stream; /// Iterator in the YAML stream. yaml::document_iterator YAMLIt; /// If we parse remark metadata in separate mode, we need to open a new file /// and parse that. std::unique_ptr SeparateBuf; YAMLRemarkParser(StringRef Buf); Expected> next() override; static bool classof(const RemarkParser *P) { return P->ParserFormat == Format::YAML; } protected: YAMLRemarkParser(StringRef Buf, std::optional StrTab); /// Create a YAMLParseError error from an existing error generated by the YAML /// parser. /// If there is no error, this returns Success. Error error(); /// Create a YAMLParseError error referencing a specific node. Error error(StringRef Message, yaml::Node &Node); /// Parse a YAML remark to a remarks::Remark object. Expected> parseRemark(yaml::Document &Remark); /// Parse the type of a remark to an enum type. Expected parseType(yaml::MappingNode &Node); /// Parse one key to a string. Expected parseKey(yaml::KeyValueNode &Node); /// Parse one value to a string. virtual Expected parseStr(yaml::KeyValueNode &Node); /// Parse one value to an unsigned. Expected parseUnsigned(yaml::KeyValueNode &Node); /// Parse a debug location. Expected parseDebugLoc(yaml::KeyValueNode &Node); /// Parse an argument. Expected parseArg(yaml::Node &Node); }; /// YAML with a string table to Remark parser. struct YAMLStrTabRemarkParser : public YAMLRemarkParser { YAMLStrTabRemarkParser(StringRef Buf, ParsedStringTable StrTab) : YAMLRemarkParser(Buf, std::move(StrTab)) {} static bool classof(const RemarkParser *P) { return P->ParserFormat == Format::YAMLStrTab; } protected: /// Parse one value to a string. Expected parseStr(yaml::KeyValueNode &Node) override; }; Expected> createYAMLParserFromMeta( StringRef Buf, std::optional StrTab = std::nullopt, std::optional ExternalFilePrependPath = std::nullopt); } // end namespace remarks } // end namespace llvm #endif /* LLVM_REMARKS_YAML_REMARK_PARSER_H */