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