1 //===-- YAMLRemarkParser.h - Parser for YAML remarks ------------*- C++/-*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file provides the impementation of the YAML remark parser. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_REMARKS_YAML_REMARK_PARSER_H 14 #define LLVM_REMARKS_YAML_REMARK_PARSER_H 15 16 #include "llvm/Remarks/Remark.h" 17 #include "llvm/Remarks/RemarkParser.h" 18 #include "llvm/Support/Error.h" 19 #include "llvm/Support/MemoryBuffer.h" 20 #include "llvm/Support/SourceMgr.h" 21 #include "llvm/Support/YAMLParser.h" 22 #include "llvm/Support/raw_ostream.h" 23 #include <optional> 24 #include <string> 25 26 namespace llvm { 27 namespace remarks { 28 29 class YAMLParseError : public ErrorInfo<YAMLParseError> { 30 public: 31 static char ID; 32 33 YAMLParseError(StringRef Message, SourceMgr &SM, yaml::Stream &Stream, 34 yaml::Node &Node); 35 36 YAMLParseError(StringRef Message) : Message(std::string(Message)) {} 37 38 void log(raw_ostream &OS) const override { OS << Message; } 39 std::error_code convertToErrorCode() const override { 40 return inconvertibleErrorCode(); 41 } 42 43 private: 44 std::string Message; 45 }; 46 47 /// Regular YAML to Remark parser. 48 struct YAMLRemarkParser : public RemarkParser { 49 /// The string table used for parsing strings. 50 std::optional<ParsedStringTable> StrTab; 51 /// Last error message that can come from the YAML parser diagnostics. 52 /// We need this for catching errors in the constructor. 53 std::string LastErrorMessage; 54 /// Source manager for better error messages. 55 SourceMgr SM; 56 /// Stream for yaml parsing. 57 yaml::Stream Stream; 58 /// Iterator in the YAML stream. 59 yaml::document_iterator YAMLIt; 60 /// If we parse remark metadata in separate mode, we need to open a new file 61 /// and parse that. 62 std::unique_ptr<MemoryBuffer> SeparateBuf; 63 64 YAMLRemarkParser(StringRef Buf); 65 66 Expected<std::unique_ptr<Remark>> next() override; 67 68 static bool classof(const RemarkParser *P) { 69 return P->ParserFormat == Format::YAML; 70 } 71 72 protected: 73 YAMLRemarkParser(StringRef Buf, std::optional<ParsedStringTable> StrTab); 74 /// Create a YAMLParseError error from an existing error generated by the YAML 75 /// parser. 76 /// If there is no error, this returns Success. 77 Error error(); 78 /// Create a YAMLParseError error referencing a specific node. 79 Error error(StringRef Message, yaml::Node &Node); 80 /// Parse a YAML remark to a remarks::Remark object. 81 Expected<std::unique_ptr<Remark>> parseRemark(yaml::Document &Remark); 82 /// Parse the type of a remark to an enum type. 83 Expected<Type> parseType(yaml::MappingNode &Node); 84 /// Parse one key to a string. 85 Expected<StringRef> parseKey(yaml::KeyValueNode &Node); 86 /// Parse one value to a string. 87 virtual Expected<StringRef> parseStr(yaml::KeyValueNode &Node); 88 /// Parse one value to an unsigned. 89 Expected<unsigned> parseUnsigned(yaml::KeyValueNode &Node); 90 /// Parse a debug location. 91 Expected<RemarkLocation> parseDebugLoc(yaml::KeyValueNode &Node); 92 /// Parse an argument. 93 Expected<Argument> parseArg(yaml::Node &Node); 94 }; 95 96 /// YAML with a string table to Remark parser. 97 struct YAMLStrTabRemarkParser : public YAMLRemarkParser { 98 YAMLStrTabRemarkParser(StringRef Buf, ParsedStringTable StrTab) 99 : YAMLRemarkParser(Buf, std::move(StrTab)) {} 100 101 static bool classof(const RemarkParser *P) { 102 return P->ParserFormat == Format::YAMLStrTab; 103 } 104 105 protected: 106 /// Parse one value to a string. 107 Expected<StringRef> parseStr(yaml::KeyValueNode &Node) override; 108 }; 109 110 Expected<std::unique_ptr<YAMLRemarkParser>> createYAMLParserFromMeta( 111 StringRef Buf, std::optional<ParsedStringTable> StrTab = std::nullopt, 112 std::optional<StringRef> ExternalFilePrependPath = std::nullopt); 113 114 } // end namespace remarks 115 } // end namespace llvm 116 117 #endif /* LLVM_REMARKS_YAML_REMARK_PARSER_H */ 118