xref: /freebsd/contrib/llvm-project/llvm/lib/Remarks/YAMLRemarkParser.h (revision 8bcb0991864975618c09697b1aca10683346d9f0)
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/ADT/Optional.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
180b57cec5SDimitry Andric #include "llvm/Remarks/Remark.h"
190b57cec5SDimitry Andric #include "llvm/Remarks/RemarkParser.h"
200b57cec5SDimitry Andric #include "llvm/Support/Error.h"
21*8bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
220b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
230b57cec5SDimitry Andric #include "llvm/Support/YAMLParser.h"
240b57cec5SDimitry Andric #include "llvm/Support/YAMLTraits.h"
250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
260b57cec5SDimitry Andric #include <string>
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric namespace llvm {
290b57cec5SDimitry Andric namespace remarks {
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric class YAMLParseError : public ErrorInfo<YAMLParseError> {
320b57cec5SDimitry Andric public:
330b57cec5SDimitry Andric   static char ID;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric   YAMLParseError(StringRef Message, SourceMgr &SM, yaml::Stream &Stream,
360b57cec5SDimitry Andric                  yaml::Node &Node);
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   YAMLParseError(StringRef Message) : Message(Message) {}
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   void log(raw_ostream &OS) const override { OS << Message; }
410b57cec5SDimitry Andric   std::error_code convertToErrorCode() const override {
420b57cec5SDimitry Andric     return inconvertibleErrorCode();
430b57cec5SDimitry Andric   }
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric private:
460b57cec5SDimitry Andric   std::string Message;
470b57cec5SDimitry Andric };
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric /// Regular YAML to Remark parser.
50*8bcb0991SDimitry Andric struct YAMLRemarkParser : public RemarkParser {
510b57cec5SDimitry Andric   /// The string table used for parsing strings.
52*8bcb0991SDimitry Andric   Optional<ParsedStringTable> StrTab;
530b57cec5SDimitry Andric   /// Last error message that can come from the YAML parser diagnostics.
540b57cec5SDimitry Andric   /// We need this for catching errors in the constructor.
550b57cec5SDimitry Andric   std::string LastErrorMessage;
560b57cec5SDimitry Andric   /// Source manager for better error messages.
570b57cec5SDimitry Andric   SourceMgr SM;
580b57cec5SDimitry Andric   /// Stream for yaml parsing.
590b57cec5SDimitry Andric   yaml::Stream Stream;
600b57cec5SDimitry Andric   /// Iterator in the YAML stream.
610b57cec5SDimitry Andric   yaml::document_iterator YAMLIt;
62*8bcb0991SDimitry Andric   /// If we parse remark metadata in separate mode, we need to open a new file
63*8bcb0991SDimitry Andric   /// and parse that.
64*8bcb0991SDimitry Andric   std::unique_ptr<MemoryBuffer> SeparateBuf;
650b57cec5SDimitry Andric 
66*8bcb0991SDimitry Andric   YAMLRemarkParser(StringRef Buf);
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   Expected<std::unique_ptr<Remark>> next() override;
690b57cec5SDimitry Andric 
70*8bcb0991SDimitry Andric   static bool classof(const RemarkParser *P) {
710b57cec5SDimitry Andric     return P->ParserFormat == Format::YAML;
720b57cec5SDimitry Andric   }
730b57cec5SDimitry Andric 
74*8bcb0991SDimitry Andric protected:
75*8bcb0991SDimitry Andric   YAMLRemarkParser(StringRef Buf, Optional<ParsedStringTable> StrTab);
760b57cec5SDimitry Andric   /// Create a YAMLParseError error from an existing error generated by the YAML
770b57cec5SDimitry Andric   /// parser.
780b57cec5SDimitry Andric   /// If there is no error, this returns Success.
790b57cec5SDimitry Andric   Error error();
800b57cec5SDimitry Andric   /// Create a YAMLParseError error referencing a specific node.
810b57cec5SDimitry Andric   Error error(StringRef Message, yaml::Node &Node);
820b57cec5SDimitry Andric   /// Parse a YAML remark to a remarks::Remark object.
830b57cec5SDimitry Andric   Expected<std::unique_ptr<Remark>> parseRemark(yaml::Document &Remark);
840b57cec5SDimitry Andric   /// Parse the type of a remark to an enum type.
850b57cec5SDimitry Andric   Expected<Type> parseType(yaml::MappingNode &Node);
860b57cec5SDimitry Andric   /// Parse one key to a string.
870b57cec5SDimitry Andric   Expected<StringRef> parseKey(yaml::KeyValueNode &Node);
880b57cec5SDimitry Andric   /// Parse one value to a string.
89*8bcb0991SDimitry Andric   virtual Expected<StringRef> parseStr(yaml::KeyValueNode &Node);
900b57cec5SDimitry Andric   /// Parse one value to an unsigned.
910b57cec5SDimitry Andric   Expected<unsigned> parseUnsigned(yaml::KeyValueNode &Node);
920b57cec5SDimitry Andric   /// Parse a debug location.
930b57cec5SDimitry Andric   Expected<RemarkLocation> parseDebugLoc(yaml::KeyValueNode &Node);
940b57cec5SDimitry Andric   /// Parse an argument.
950b57cec5SDimitry Andric   Expected<Argument> parseArg(yaml::Node &Node);
960b57cec5SDimitry Andric };
97*8bcb0991SDimitry Andric 
98*8bcb0991SDimitry Andric /// YAML with a string table to Remark parser.
99*8bcb0991SDimitry Andric struct YAMLStrTabRemarkParser : public YAMLRemarkParser {
100*8bcb0991SDimitry Andric   YAMLStrTabRemarkParser(StringRef Buf, ParsedStringTable StrTab)
101*8bcb0991SDimitry Andric       : YAMLRemarkParser(Buf, std::move(StrTab)) {}
102*8bcb0991SDimitry Andric 
103*8bcb0991SDimitry Andric   static bool classof(const RemarkParser *P) {
104*8bcb0991SDimitry Andric     return P->ParserFormat == Format::YAMLStrTab;
105*8bcb0991SDimitry Andric   }
106*8bcb0991SDimitry Andric 
107*8bcb0991SDimitry Andric protected:
108*8bcb0991SDimitry Andric   /// Parse one value to a string.
109*8bcb0991SDimitry Andric   Expected<StringRef> parseStr(yaml::KeyValueNode &Node) override;
110*8bcb0991SDimitry Andric };
111*8bcb0991SDimitry Andric 
112*8bcb0991SDimitry Andric Expected<std::unique_ptr<YAMLRemarkParser>>
113*8bcb0991SDimitry Andric createYAMLParserFromMeta(StringRef Buf,
114*8bcb0991SDimitry Andric                          Optional<ParsedStringTable> StrTab = None,
115*8bcb0991SDimitry Andric                          Optional<StringRef> ExternalFilePrependPath = None);
116*8bcb0991SDimitry Andric 
1170b57cec5SDimitry Andric } // end namespace remarks
1180b57cec5SDimitry Andric } // end namespace llvm
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric #endif /* LLVM_REMARKS_YAML_REMARK_PARSER_H */
121