LLVM 20.0.0git
RemarkParser.cpp
Go to the documentation of this file.
1//===- RemarkParser.cpp --------------------------------------------------===//
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 utility methods used by clients that want to use the
10// parser for remark diagnostics in LLVM.
11//
12//===----------------------------------------------------------------------===//
13
15#include "BitstreamRemarkParser.h"
16#include "YAMLRemarkParser.h"
17#include "llvm-c/Remarks.h"
19#include <optional>
20
21using namespace llvm;
22using namespace llvm::remarks;
23
24char EndOfFileError::ID = 0;
25
26ParsedStringTable::ParsedStringTable(StringRef InBuffer) : Buffer(InBuffer) {
27 while (!InBuffer.empty()) {
28 // Strings are separated by '\0' bytes.
29 std::pair<StringRef, StringRef> Split = InBuffer.split('\0');
30 // We only store the offset from the beginning of the buffer.
31 Offsets.push_back(Split.first.data() - Buffer.data());
32 InBuffer = Split.second;
33 }
34}
35
37 if (Index >= Offsets.size())
38 return createStringError(
39 std::make_error_code(std::errc::invalid_argument),
40 "String with index %u is out of bounds (size = %u).", Index,
41 Offsets.size());
42
43 size_t Offset = Offsets[Index];
44 // If it's the last offset, we can't use the next offset to know the size of
45 // the string.
46 size_t NextOffset =
47 (Index == Offsets.size() - 1) ? Buffer.size() : Offsets[Index + 1];
48 return StringRef(Buffer.data() + Offset, NextOffset - Offset - 1);
49}
50
53 switch (ParserFormat) {
54 case Format::YAML:
55 return std::make_unique<YAMLRemarkParser>(Buf);
57 return createStringError(
58 std::make_error_code(std::errc::invalid_argument),
59 "The YAML with string table format requires a parsed string table.");
61 return std::make_unique<BitstreamRemarkParser>(Buf);
62 case Format::Unknown:
63 return createStringError(std::make_error_code(std::errc::invalid_argument),
64 "Unknown remark parser format.");
65 }
66 llvm_unreachable("unhandled ParseFormat");
67}
68
71 ParsedStringTable StrTab) {
72 switch (ParserFormat) {
73 case Format::YAML:
74 return createStringError(std::make_error_code(std::errc::invalid_argument),
75 "The YAML format can't be used with a string "
76 "table. Use yaml-strtab instead.");
78 return std::make_unique<YAMLStrTabRemarkParser>(Buf, std::move(StrTab));
80 return std::make_unique<BitstreamRemarkParser>(Buf, std::move(StrTab));
81 case Format::Unknown:
82 return createStringError(std::make_error_code(std::errc::invalid_argument),
83 "Unknown remark parser format.");
84 }
85 llvm_unreachable("unhandled ParseFormat");
86}
87
90 Format ParserFormat, StringRef Buf, std::optional<ParsedStringTable> StrTab,
91 std::optional<StringRef> ExternalFilePrependPath) {
92 switch (ParserFormat) {
93 // Depending on the metadata, the format can be either yaml or yaml-strtab,
94 // regardless of the input argument.
95 case Format::YAML:
97 return createYAMLParserFromMeta(Buf, std::move(StrTab),
98 std::move(ExternalFilePrependPath));
100 return createBitstreamParserFromMeta(Buf, std::move(StrTab),
101 std::move(ExternalFilePrependPath));
102 case Format::Unknown:
103 return createStringError(std::make_error_code(std::errc::invalid_argument),
104 "Unknown remark parser format.");
105 }
106 llvm_unreachable("unhandled ParseFormat");
107}
108
109namespace {
110// Wrapper that holds the state needed to interact with the C API.
111struct CParser {
112 std::unique_ptr<RemarkParser> TheParser;
113 std::optional<std::string> Err;
114
115 CParser(Format ParserFormat, StringRef Buf,
116 std::optional<ParsedStringTable> StrTab = std::nullopt)
117 : TheParser(cantFail(
118 StrTab ? createRemarkParser(ParserFormat, Buf, std::move(*StrTab))
119 : createRemarkParser(ParserFormat, Buf))) {}
120
121 void handleError(Error E) { Err.emplace(toString(std::move(E))); }
122 bool hasError() const { return Err.has_value(); }
123 const char *getMessage() const { return Err ? Err->c_str() : nullptr; };
124};
125} // namespace
126
127// Create wrappers for C Binding types (see CBindingWrapping.h).
129
131 uint64_t Size) {
132 return wrap(new CParser(Format::YAML,
133 StringRef(static_cast<const char *>(Buf), Size)));
134}
135
137 uint64_t Size) {
138 return wrap(new CParser(Format::Bitstream,
139 StringRef(static_cast<const char *>(Buf), Size)));
140}
141
142extern "C" LLVMRemarkEntryRef
144 CParser &TheCParser = *unwrap(Parser);
145 remarks::RemarkParser &TheParser = *TheCParser.TheParser;
146
147 Expected<std::unique_ptr<Remark>> MaybeRemark = TheParser.next();
148 if (Error E = MaybeRemark.takeError()) {
149 if (E.isA<EndOfFileError>()) {
150 consumeError(std::move(E));
151 return nullptr;
152 }
153
154 // Handle the error. Allow it to be checked through HasError and
155 // GetErrorMessage.
156 TheCParser.handleError(std::move(E));
157 return nullptr;
158 }
159
160 // Valid remark.
161 return wrap(MaybeRemark->release());
162}
163
165 return unwrap(Parser)->hasError();
166}
167
168extern "C" const char *
170 return unwrap(Parser)->getMessage();
171}
172
174 delete unwrap(Parser);
175}
aarch64 promote const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)
uint64_t Size
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
bool isA() const
Check whether one error is a subclass of another.
Definition: Error.h:247
Tagged union holding either a T or a Error.
Definition: Error.h:481
Error takeError()
Take ownership of the stored error.
Definition: Error.h:608
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:700
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:144
struct LLVMRemarkOpaqueEntry * LLVMRemarkEntryRef
A remark emitted by the compiler.
Definition: Remarks.h:140
LLVMRemarkParserRef LLVMRemarkParserCreateBitstream(const void *Buf, uint64_t Size)
Creates a remark parser that can be used to parse the buffer located in Buf of size Size bytes.
LLVMRemarkParserRef LLVMRemarkParserCreateYAML(const void *Buf, uint64_t Size)
Creates a remark parser that can be used to parse the buffer located in Buf of size Size bytes.
struct LLVMRemarkOpaqueParser * LLVMRemarkParserRef
Definition: Remarks.h:230
LLVMBool LLVMRemarkParserHasError(LLVMRemarkParserRef Parser)
Returns 1 if the parser encountered an error while parsing the buffer.
const char * LLVMRemarkParserGetErrorMessage(LLVMRemarkParserRef Parser)
Returns a null-terminated string containing an error message.
void LLVMRemarkParserDispose(LLVMRemarkParserRef Parser)
Releases all the resources used by Parser.
LLVMRemarkEntryRef LLVMRemarkParserGetNext(LLVMRemarkParserRef Parser)
Returns the next remark in the file.
int LLVMBool
Definition: Types.h:28
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
Expected< std::unique_ptr< BitstreamRemarkParser > > createBitstreamParserFromMeta(StringRef Buf, std::optional< ParsedStringTable > StrTab=std::nullopt, std::optional< StringRef > ExternalFilePrependPath=std::nullopt)
Format
The format used for serializing/deserializing remarks.
Definition: RemarkFormat.h:25
Expected< std::unique_ptr< RemarkParser > > createRemarkParserFromMeta(Format ParserFormat, StringRef Buf, std::optional< ParsedStringTable > StrTab=std::nullopt, std::optional< StringRef > ExternalFilePrependPath=std::nullopt)
Expected< std::unique_ptr< RemarkParser > > createRemarkParser(Format ParserFormat, StringRef Buf)
Expected< std::unique_ptr< YAMLRemarkParser > > createYAMLParserFromMeta(StringRef Buf, std::optional< ParsedStringTable > StrTab=std::nullopt, std::optional< StringRef > ExternalFilePrependPath=std::nullopt)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1291
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:756
Attribute unwrap(LLVMAttributeRef Attr)
Definition: Attributes.h:332
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
LLVMAttributeRef wrap(Attribute Attr)
Definition: Attributes.h:327
const char * toString(DWARFSectionKind Kind)
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1069
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
In-memory representation of the string table parsed from a buffer (e.g.
Definition: RemarkParser.h:60
Expected< StringRef > operator[](size_t Index) const
std::vector< size_t > Offsets
This object has high changes to be std::move'd around, so don't use a SmallVector for once.
Definition: RemarkParser.h:65
StringRef Buffer
The buffer mapped from the section contents.
Definition: RemarkParser.h:62
ParsedStringTable(StringRef Buffer)
Parser used to parse a raw buffer to remarks::Remark objects.
Definition: RemarkParser.h:40
virtual Expected< std::unique_ptr< Remark > > next()=0
If no error occurs, this returns a valid Remark object.