1351278Sdim//===-- YAMLRemarkParser.h - Parser for YAML remarks ------------*- C++/-*-===// 2351278Sdim// 3351278Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4351278Sdim// See https://llvm.org/LICENSE.txt for license information. 5351278Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6351278Sdim// 7351278Sdim//===----------------------------------------------------------------------===// 8351278Sdim// 9351278Sdim// This file provides the impementation of the YAML remark parser. 10351278Sdim// 11351278Sdim//===----------------------------------------------------------------------===// 12351278Sdim 13351278Sdim#ifndef LLVM_REMARKS_YAML_REMARK_PARSER_H 14351278Sdim#define LLVM_REMARKS_YAML_REMARK_PARSER_H 15351278Sdim 16351278Sdim#include "llvm/ADT/Optional.h" 17351278Sdim#include "llvm/ADT/SmallVector.h" 18351278Sdim#include "llvm/Remarks/Remark.h" 19351278Sdim#include "llvm/Remarks/RemarkParser.h" 20351278Sdim#include "llvm/Support/Error.h" 21360784Sdim#include "llvm/Support/MemoryBuffer.h" 22351278Sdim#include "llvm/Support/SourceMgr.h" 23351278Sdim#include "llvm/Support/YAMLParser.h" 24351278Sdim#include "llvm/Support/YAMLTraits.h" 25351278Sdim#include "llvm/Support/raw_ostream.h" 26351278Sdim#include <string> 27351278Sdim 28351278Sdimnamespace llvm { 29351278Sdimnamespace remarks { 30351278Sdim 31351278Sdimclass YAMLParseError : public ErrorInfo<YAMLParseError> { 32351278Sdimpublic: 33351278Sdim static char ID; 34351278Sdim 35351278Sdim YAMLParseError(StringRef Message, SourceMgr &SM, yaml::Stream &Stream, 36351278Sdim yaml::Node &Node); 37351278Sdim 38351278Sdim YAMLParseError(StringRef Message) : Message(Message) {} 39351278Sdim 40351278Sdim void log(raw_ostream &OS) const override { OS << Message; } 41351278Sdim std::error_code convertToErrorCode() const override { 42351278Sdim return inconvertibleErrorCode(); 43351278Sdim } 44351278Sdim 45351278Sdimprivate: 46351278Sdim std::string Message; 47351278Sdim}; 48351278Sdim 49351278Sdim/// Regular YAML to Remark parser. 50360784Sdimstruct YAMLRemarkParser : public RemarkParser { 51351278Sdim /// The string table used for parsing strings. 52360784Sdim Optional<ParsedStringTable> StrTab; 53351278Sdim /// Last error message that can come from the YAML parser diagnostics. 54351278Sdim /// We need this for catching errors in the constructor. 55351278Sdim std::string LastErrorMessage; 56351278Sdim /// Source manager for better error messages. 57351278Sdim SourceMgr SM; 58351278Sdim /// Stream for yaml parsing. 59351278Sdim yaml::Stream Stream; 60351278Sdim /// Iterator in the YAML stream. 61351278Sdim yaml::document_iterator YAMLIt; 62360784Sdim /// If we parse remark metadata in separate mode, we need to open a new file 63360784Sdim /// and parse that. 64360784Sdim std::unique_ptr<MemoryBuffer> SeparateBuf; 65351278Sdim 66360784Sdim YAMLRemarkParser(StringRef Buf); 67351278Sdim 68351278Sdim Expected<std::unique_ptr<Remark>> next() override; 69351278Sdim 70360784Sdim static bool classof(const RemarkParser *P) { 71351278Sdim return P->ParserFormat == Format::YAML; 72351278Sdim } 73351278Sdim 74360784Sdimprotected: 75360784Sdim YAMLRemarkParser(StringRef Buf, Optional<ParsedStringTable> StrTab); 76351278Sdim /// Create a YAMLParseError error from an existing error generated by the YAML 77351278Sdim /// parser. 78351278Sdim /// If there is no error, this returns Success. 79351278Sdim Error error(); 80351278Sdim /// Create a YAMLParseError error referencing a specific node. 81351278Sdim Error error(StringRef Message, yaml::Node &Node); 82351278Sdim /// Parse a YAML remark to a remarks::Remark object. 83351278Sdim Expected<std::unique_ptr<Remark>> parseRemark(yaml::Document &Remark); 84351278Sdim /// Parse the type of a remark to an enum type. 85351278Sdim Expected<Type> parseType(yaml::MappingNode &Node); 86351278Sdim /// Parse one key to a string. 87351278Sdim Expected<StringRef> parseKey(yaml::KeyValueNode &Node); 88351278Sdim /// Parse one value to a string. 89360784Sdim virtual Expected<StringRef> parseStr(yaml::KeyValueNode &Node); 90351278Sdim /// Parse one value to an unsigned. 91351278Sdim Expected<unsigned> parseUnsigned(yaml::KeyValueNode &Node); 92351278Sdim /// Parse a debug location. 93351278Sdim Expected<RemarkLocation> parseDebugLoc(yaml::KeyValueNode &Node); 94351278Sdim /// Parse an argument. 95351278Sdim Expected<Argument> parseArg(yaml::Node &Node); 96351278Sdim}; 97360784Sdim 98360784Sdim/// YAML with a string table to Remark parser. 99360784Sdimstruct YAMLStrTabRemarkParser : public YAMLRemarkParser { 100360784Sdim YAMLStrTabRemarkParser(StringRef Buf, ParsedStringTable StrTab) 101360784Sdim : YAMLRemarkParser(Buf, std::move(StrTab)) {} 102360784Sdim 103360784Sdim static bool classof(const RemarkParser *P) { 104360784Sdim return P->ParserFormat == Format::YAMLStrTab; 105360784Sdim } 106360784Sdim 107360784Sdimprotected: 108360784Sdim /// Parse one value to a string. 109360784Sdim Expected<StringRef> parseStr(yaml::KeyValueNode &Node) override; 110360784Sdim}; 111360784Sdim 112360784SdimExpected<std::unique_ptr<YAMLRemarkParser>> 113360784SdimcreateYAMLParserFromMeta(StringRef Buf, 114360784Sdim Optional<ParsedStringTable> StrTab = None, 115360784Sdim Optional<StringRef> ExternalFilePrependPath = None); 116360784Sdim 117351278Sdim} // end namespace remarks 118351278Sdim} // end namespace llvm 119351278Sdim 120351278Sdim#endif /* LLVM_REMARKS_YAML_REMARK_PARSER_H */ 121