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/Remarks/Remark.h" 170b57cec5SDimitry Andric #include "llvm/Remarks/RemarkParser.h" 180b57cec5SDimitry Andric #include "llvm/Support/Error.h" 198bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 200b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 210b57cec5SDimitry Andric #include "llvm/Support/YAMLParser.h" 220b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 23*bdd1243dSDimitry Andric #include <optional> 240b57cec5SDimitry Andric #include <string> 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace llvm { 270b57cec5SDimitry Andric namespace remarks { 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric class YAMLParseError : public ErrorInfo<YAMLParseError> { 300b57cec5SDimitry Andric public: 310b57cec5SDimitry Andric static char ID; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric YAMLParseError(StringRef Message, SourceMgr &SM, yaml::Stream &Stream, 340b57cec5SDimitry Andric yaml::Node &Node); 350b57cec5SDimitry Andric YAMLParseError(StringRef Message)365ffd83dbSDimitry Andric YAMLParseError(StringRef Message) : Message(std::string(Message)) {} 370b57cec5SDimitry Andric log(raw_ostream & OS)380b57cec5SDimitry Andric void log(raw_ostream &OS) const override { OS << Message; } convertToErrorCode()390b57cec5SDimitry Andric std::error_code convertToErrorCode() const override { 400b57cec5SDimitry Andric return inconvertibleErrorCode(); 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric private: 440b57cec5SDimitry Andric std::string Message; 450b57cec5SDimitry Andric }; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric /// Regular YAML to Remark parser. 488bcb0991SDimitry Andric struct YAMLRemarkParser : public RemarkParser { 490b57cec5SDimitry Andric /// The string table used for parsing strings. 50*bdd1243dSDimitry Andric std::optional<ParsedStringTable> StrTab; 510b57cec5SDimitry Andric /// Last error message that can come from the YAML parser diagnostics. 520b57cec5SDimitry Andric /// We need this for catching errors in the constructor. 530b57cec5SDimitry Andric std::string LastErrorMessage; 540b57cec5SDimitry Andric /// Source manager for better error messages. 550b57cec5SDimitry Andric SourceMgr SM; 560b57cec5SDimitry Andric /// Stream for yaml parsing. 570b57cec5SDimitry Andric yaml::Stream Stream; 580b57cec5SDimitry Andric /// Iterator in the YAML stream. 590b57cec5SDimitry Andric yaml::document_iterator YAMLIt; 608bcb0991SDimitry Andric /// If we parse remark metadata in separate mode, we need to open a new file 618bcb0991SDimitry Andric /// and parse that. 628bcb0991SDimitry Andric std::unique_ptr<MemoryBuffer> SeparateBuf; 630b57cec5SDimitry Andric 648bcb0991SDimitry Andric YAMLRemarkParser(StringRef Buf); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric Expected<std::unique_ptr<Remark>> next() override; 670b57cec5SDimitry Andric classofYAMLRemarkParser688bcb0991SDimitry Andric static bool classof(const RemarkParser *P) { 690b57cec5SDimitry Andric return P->ParserFormat == Format::YAML; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 728bcb0991SDimitry Andric protected: 73*bdd1243dSDimitry Andric YAMLRemarkParser(StringRef Buf, std::optional<ParsedStringTable> StrTab); 740b57cec5SDimitry Andric /// Create a YAMLParseError error from an existing error generated by the YAML 750b57cec5SDimitry Andric /// parser. 760b57cec5SDimitry Andric /// If there is no error, this returns Success. 770b57cec5SDimitry Andric Error error(); 780b57cec5SDimitry Andric /// Create a YAMLParseError error referencing a specific node. 790b57cec5SDimitry Andric Error error(StringRef Message, yaml::Node &Node); 800b57cec5SDimitry Andric /// Parse a YAML remark to a remarks::Remark object. 810b57cec5SDimitry Andric Expected<std::unique_ptr<Remark>> parseRemark(yaml::Document &Remark); 820b57cec5SDimitry Andric /// Parse the type of a remark to an enum type. 830b57cec5SDimitry Andric Expected<Type> parseType(yaml::MappingNode &Node); 840b57cec5SDimitry Andric /// Parse one key to a string. 850b57cec5SDimitry Andric Expected<StringRef> parseKey(yaml::KeyValueNode &Node); 860b57cec5SDimitry Andric /// Parse one value to a string. 878bcb0991SDimitry Andric virtual Expected<StringRef> parseStr(yaml::KeyValueNode &Node); 880b57cec5SDimitry Andric /// Parse one value to an unsigned. 890b57cec5SDimitry Andric Expected<unsigned> parseUnsigned(yaml::KeyValueNode &Node); 900b57cec5SDimitry Andric /// Parse a debug location. 910b57cec5SDimitry Andric Expected<RemarkLocation> parseDebugLoc(yaml::KeyValueNode &Node); 920b57cec5SDimitry Andric /// Parse an argument. 930b57cec5SDimitry Andric Expected<Argument> parseArg(yaml::Node &Node); 940b57cec5SDimitry Andric }; 958bcb0991SDimitry Andric 968bcb0991SDimitry Andric /// YAML with a string table to Remark parser. 978bcb0991SDimitry Andric struct YAMLStrTabRemarkParser : public YAMLRemarkParser { YAMLStrTabRemarkParserYAMLStrTabRemarkParser988bcb0991SDimitry Andric YAMLStrTabRemarkParser(StringRef Buf, ParsedStringTable StrTab) 998bcb0991SDimitry Andric : YAMLRemarkParser(Buf, std::move(StrTab)) {} 1008bcb0991SDimitry Andric classofYAMLStrTabRemarkParser1018bcb0991SDimitry Andric static bool classof(const RemarkParser *P) { 1028bcb0991SDimitry Andric return P->ParserFormat == Format::YAMLStrTab; 1038bcb0991SDimitry Andric } 1048bcb0991SDimitry Andric 1058bcb0991SDimitry Andric protected: 1068bcb0991SDimitry Andric /// Parse one value to a string. 1078bcb0991SDimitry Andric Expected<StringRef> parseStr(yaml::KeyValueNode &Node) override; 1088bcb0991SDimitry Andric }; 1098bcb0991SDimitry Andric 110*bdd1243dSDimitry Andric Expected<std::unique_ptr<YAMLRemarkParser>> createYAMLParserFromMeta( 111*bdd1243dSDimitry Andric StringRef Buf, std::optional<ParsedStringTable> StrTab = std::nullopt, 112*bdd1243dSDimitry Andric std::optional<StringRef> ExternalFilePrependPath = std::nullopt); 1138bcb0991SDimitry Andric 1140b57cec5SDimitry Andric } // end namespace remarks 1150b57cec5SDimitry Andric } // end namespace llvm 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric #endif /* LLVM_REMARKS_YAML_REMARK_PARSER_H */ 118