10b57cec5SDimitry Andric //===-- YAMLRemarkParser.h - Parser for YAML remarks ------------*- C++/-*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file provides the impementation of the YAML remark parser. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_REMARKS_YAML_REMARK_PARSER_H 140b57cec5SDimitry Andric #define LLVM_REMARKS_YAML_REMARK_PARSER_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 180b57cec5SDimitry Andric #include "llvm/Remarks/Remark.h" 190b57cec5SDimitry Andric #include "llvm/Remarks/RemarkParser.h" 200b57cec5SDimitry Andric #include "llvm/Support/Error.h" 21*8bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 220b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 230b57cec5SDimitry Andric #include "llvm/Support/YAMLParser.h" 240b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h" 250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 260b57cec5SDimitry Andric #include <string> 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace llvm { 290b57cec5SDimitry Andric namespace remarks { 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric class YAMLParseError : public ErrorInfo<YAMLParseError> { 320b57cec5SDimitry Andric public: 330b57cec5SDimitry Andric static char ID; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric YAMLParseError(StringRef Message, SourceMgr &SM, yaml::Stream &Stream, 360b57cec5SDimitry Andric yaml::Node &Node); 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric YAMLParseError(StringRef Message) : Message(Message) {} 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric void log(raw_ostream &OS) const override { OS << Message; } 410b57cec5SDimitry Andric std::error_code convertToErrorCode() const override { 420b57cec5SDimitry Andric return inconvertibleErrorCode(); 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric private: 460b57cec5SDimitry Andric std::string Message; 470b57cec5SDimitry Andric }; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric /// Regular YAML to Remark parser. 50*8bcb0991SDimitry Andric struct YAMLRemarkParser : public RemarkParser { 510b57cec5SDimitry Andric /// The string table used for parsing strings. 52*8bcb0991SDimitry Andric Optional<ParsedStringTable> StrTab; 530b57cec5SDimitry Andric /// Last error message that can come from the YAML parser diagnostics. 540b57cec5SDimitry Andric /// We need this for catching errors in the constructor. 550b57cec5SDimitry Andric std::string LastErrorMessage; 560b57cec5SDimitry Andric /// Source manager for better error messages. 570b57cec5SDimitry Andric SourceMgr SM; 580b57cec5SDimitry Andric /// Stream for yaml parsing. 590b57cec5SDimitry Andric yaml::Stream Stream; 600b57cec5SDimitry Andric /// Iterator in the YAML stream. 610b57cec5SDimitry Andric yaml::document_iterator YAMLIt; 62*8bcb0991SDimitry Andric /// If we parse remark metadata in separate mode, we need to open a new file 63*8bcb0991SDimitry Andric /// and parse that. 64*8bcb0991SDimitry Andric std::unique_ptr<MemoryBuffer> SeparateBuf; 650b57cec5SDimitry Andric 66*8bcb0991SDimitry Andric YAMLRemarkParser(StringRef Buf); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric Expected<std::unique_ptr<Remark>> next() override; 690b57cec5SDimitry Andric 70*8bcb0991SDimitry Andric static bool classof(const RemarkParser *P) { 710b57cec5SDimitry Andric return P->ParserFormat == Format::YAML; 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 74*8bcb0991SDimitry Andric protected: 75*8bcb0991SDimitry Andric YAMLRemarkParser(StringRef Buf, Optional<ParsedStringTable> StrTab); 760b57cec5SDimitry Andric /// Create a YAMLParseError error from an existing error generated by the YAML 770b57cec5SDimitry Andric /// parser. 780b57cec5SDimitry Andric /// If there is no error, this returns Success. 790b57cec5SDimitry Andric Error error(); 800b57cec5SDimitry Andric /// Create a YAMLParseError error referencing a specific node. 810b57cec5SDimitry Andric Error error(StringRef Message, yaml::Node &Node); 820b57cec5SDimitry Andric /// Parse a YAML remark to a remarks::Remark object. 830b57cec5SDimitry Andric Expected<std::unique_ptr<Remark>> parseRemark(yaml::Document &Remark); 840b57cec5SDimitry Andric /// Parse the type of a remark to an enum type. 850b57cec5SDimitry Andric Expected<Type> parseType(yaml::MappingNode &Node); 860b57cec5SDimitry Andric /// Parse one key to a string. 870b57cec5SDimitry Andric Expected<StringRef> parseKey(yaml::KeyValueNode &Node); 880b57cec5SDimitry Andric /// Parse one value to a string. 89*8bcb0991SDimitry Andric virtual Expected<StringRef> parseStr(yaml::KeyValueNode &Node); 900b57cec5SDimitry Andric /// Parse one value to an unsigned. 910b57cec5SDimitry Andric Expected<unsigned> parseUnsigned(yaml::KeyValueNode &Node); 920b57cec5SDimitry Andric /// Parse a debug location. 930b57cec5SDimitry Andric Expected<RemarkLocation> parseDebugLoc(yaml::KeyValueNode &Node); 940b57cec5SDimitry Andric /// Parse an argument. 950b57cec5SDimitry Andric Expected<Argument> parseArg(yaml::Node &Node); 960b57cec5SDimitry Andric }; 97*8bcb0991SDimitry Andric 98*8bcb0991SDimitry Andric /// YAML with a string table to Remark parser. 99*8bcb0991SDimitry Andric struct YAMLStrTabRemarkParser : public YAMLRemarkParser { 100*8bcb0991SDimitry Andric YAMLStrTabRemarkParser(StringRef Buf, ParsedStringTable StrTab) 101*8bcb0991SDimitry Andric : YAMLRemarkParser(Buf, std::move(StrTab)) {} 102*8bcb0991SDimitry Andric 103*8bcb0991SDimitry Andric static bool classof(const RemarkParser *P) { 104*8bcb0991SDimitry Andric return P->ParserFormat == Format::YAMLStrTab; 105*8bcb0991SDimitry Andric } 106*8bcb0991SDimitry Andric 107*8bcb0991SDimitry Andric protected: 108*8bcb0991SDimitry Andric /// Parse one value to a string. 109*8bcb0991SDimitry Andric Expected<StringRef> parseStr(yaml::KeyValueNode &Node) override; 110*8bcb0991SDimitry Andric }; 111*8bcb0991SDimitry Andric 112*8bcb0991SDimitry Andric Expected<std::unique_ptr<YAMLRemarkParser>> 113*8bcb0991SDimitry Andric createYAMLParserFromMeta(StringRef Buf, 114*8bcb0991SDimitry Andric Optional<ParsedStringTable> StrTab = None, 115*8bcb0991SDimitry Andric Optional<StringRef> ExternalFilePrependPath = None); 116*8bcb0991SDimitry Andric 1170b57cec5SDimitry Andric } // end namespace remarks 1180b57cec5SDimitry Andric } // end namespace llvm 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric #endif /* LLVM_REMARKS_YAML_REMARK_PARSER_H */ 121