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