1/*===-- llvm-c/Remarks.h - Remarks Public C Interface -------------*- C -*-===*\
2|* *|
3|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
4|* Exceptions. *|
5|* See https://llvm.org/LICENSE.txt for license information. *|
6|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
7|* *|
8|*===----------------------------------------------------------------------===*|
9|* *|
10|* This header provides a public interface to a remark diagnostics library. *|
11|* LLVM provides an implementation of this interface. *|
12|* *|
13\*===----------------------------------------------------------------------===*/
14
15#ifndef LLVM_C_REMARKS_H
16#define LLVM_C_REMARKS_H
17
18#include "llvm-c/ExternC.h"
19#include "llvm-c/Types.h"
20#ifdef __cplusplus
21#include <cstddef>
22#else
23#include <stddef.h>
24#endif /* !defined(__cplusplus) */
25
26LLVM_C_EXTERN_C_BEGIN
27
28/**
29 * @defgroup LLVMCREMARKS Remarks
30 * @ingroup LLVMC
31 *
32 * @{
33 */
34
35// 0 -> 1: Bitstream remarks support.
36#define REMARKS_API_VERSION 1
37
38/**
39 * The type of the emitted remark.
40 */
41enum LLVMRemarkType {
42 LLVMRemarkTypeUnknown,
43 LLVMRemarkTypePassed,
44 LLVMRemarkTypeMissed,
45 LLVMRemarkTypeAnalysis,
46 LLVMRemarkTypeAnalysisFPCommute,
47 LLVMRemarkTypeAnalysisAliasing,
48 LLVMRemarkTypeFailure
49};
50
51/**
52 * String containing a buffer and a length. The buffer is not guaranteed to be
53 * zero-terminated.
54 *
55 * \since REMARKS_API_VERSION=0
56 */
57typedef struct LLVMRemarkOpaqueString *LLVMRemarkStringRef;
58
59/**
60 * Returns the buffer holding the string.
61 *
62 * \since REMARKS_API_VERSION=0
63 */
64extern const char *LLVMRemarkStringGetData(LLVMRemarkStringRef String);
65
66/**
67 * Returns the size of the string.
68 *
69 * \since REMARKS_API_VERSION=0
70 */
71extern uint32_t LLVMRemarkStringGetLen(LLVMRemarkStringRef String);
72
73/**
74 * DebugLoc containing File, Line and Column.
75 *
76 * \since REMARKS_API_VERSION=0
77 */
78typedef struct LLVMRemarkOpaqueDebugLoc *LLVMRemarkDebugLocRef;
79
80/**
81 * Return the path to the source file for a debug location.
82 *
83 * \since REMARKS_API_VERSION=0
84 */
85extern LLVMRemarkStringRef
86LLVMRemarkDebugLocGetSourceFilePath(LLVMRemarkDebugLocRef DL);
87
88/**
89 * Return the line in the source file for a debug location.
90 *
91 * \since REMARKS_API_VERSION=0
92 */
93extern uint32_t LLVMRemarkDebugLocGetSourceLine(LLVMRemarkDebugLocRef DL);
94
95/**
96 * Return the column in the source file for a debug location.
97 *
98 * \since REMARKS_API_VERSION=0
99 */
100extern uint32_t LLVMRemarkDebugLocGetSourceColumn(LLVMRemarkDebugLocRef DL);
101
102/**
103 * Element of the "Args" list. The key might give more information about what
104 * the semantics of the value are, e.g. "Callee" will tell you that the value
105 * is a symbol that names a function.
106 *
107 * \since REMARKS_API_VERSION=0
108 */
109typedef struct LLVMRemarkOpaqueArg *LLVMRemarkArgRef;
110
111/**
112 * Returns the key of an argument. The key defines what the value is, and the
113 * same key can appear multiple times in the list of arguments.
114 *
115 * \since REMARKS_API_VERSION=0
116 */
117extern LLVMRemarkStringRef LLVMRemarkArgGetKey(LLVMRemarkArgRef Arg);
118
119/**
120 * Returns the value of an argument. This is a string that can contain newlines.
121 *
122 * \since REMARKS_API_VERSION=0
123 */
124extern LLVMRemarkStringRef LLVMRemarkArgGetValue(LLVMRemarkArgRef Arg);
125
126/**
127 * Returns the debug location that is attached to the value of this argument.
128 *
129 * If there is no debug location, the return value will be `NULL`.
130 *
131 * \since REMARKS_API_VERSION=0
132 */
133extern LLVMRemarkDebugLocRef LLVMRemarkArgGetDebugLoc(LLVMRemarkArgRef Arg);
134
135/**
136 * A remark emitted by the compiler.
137 *
138 * \since REMARKS_API_VERSION=0
139 */
140typedef struct LLVMRemarkOpaqueEntry *LLVMRemarkEntryRef;
141
142/**
143 * Free the resources used by the remark entry.
144 *
145 * \since REMARKS_API_VERSION=0
146 */
147extern void LLVMRemarkEntryDispose(LLVMRemarkEntryRef Remark);
148
149/**
150 * The type of the remark. For example, it can allow users to only keep the
151 * missed optimizations from the compiler.
152 *
153 * \since REMARKS_API_VERSION=0
154 */
155extern enum LLVMRemarkType LLVMRemarkEntryGetType(LLVMRemarkEntryRef Remark);
156
157/**
158 * Get the name of the pass that emitted this remark.
159 *
160 * \since REMARKS_API_VERSION=0
161 */
162extern LLVMRemarkStringRef
163LLVMRemarkEntryGetPassName(LLVMRemarkEntryRef Remark);
164
165/**
166 * Get an identifier of the remark.
167 *
168 * \since REMARKS_API_VERSION=0
169 */
170extern LLVMRemarkStringRef
171LLVMRemarkEntryGetRemarkName(LLVMRemarkEntryRef Remark);
172
173/**
174 * Get the name of the function being processed when the remark was emitted.
175 *
176 * \since REMARKS_API_VERSION=0
177 */
178extern LLVMRemarkStringRef
179LLVMRemarkEntryGetFunctionName(LLVMRemarkEntryRef Remark);
180
181/**
182 * Returns the debug location that is attached to this remark.
183 *
184 * If there is no debug location, the return value will be `NULL`.
185 *
186 * \since REMARKS_API_VERSION=0
187 */
188extern LLVMRemarkDebugLocRef
189LLVMRemarkEntryGetDebugLoc(LLVMRemarkEntryRef Remark);
190
191/**
192 * Return the hotness of the remark.
193 *
194 * A hotness of `0` means this value is not set.
195 *
196 * \since REMARKS_API_VERSION=0
197 */
198extern uint64_t LLVMRemarkEntryGetHotness(LLVMRemarkEntryRef Remark);
199
200/**
201 * The number of arguments the remark holds.
202 *
203 * \since REMARKS_API_VERSION=0
204 */
205extern uint32_t LLVMRemarkEntryGetNumArgs(LLVMRemarkEntryRef Remark);
206
207/**
208 * Get a new iterator to iterate over a remark's argument.
209 *
210 * If there are no arguments in \p Remark, the return value will be `NULL`.
211 *
212 * The lifetime of the returned value is bound to the lifetime of \p Remark.
213 *
214 * \since REMARKS_API_VERSION=0
215 */
216extern LLVMRemarkArgRef LLVMRemarkEntryGetFirstArg(LLVMRemarkEntryRef Remark);
217
218/**
219 * Get the next argument in \p Remark from the position of \p It.
220 *
221 * Returns `NULL` if there are no more arguments available.
222 *
223 * The lifetime of the returned value is bound to the lifetime of \p Remark.
224 *
225 * \since REMARKS_API_VERSION=0
226 */
227extern LLVMRemarkArgRef LLVMRemarkEntryGetNextArg(LLVMRemarkArgRef It,
228 LLVMRemarkEntryRef Remark);
229
230typedef struct LLVMRemarkOpaqueParser *LLVMRemarkParserRef;
231
232/**
233 * Creates a remark parser that can be used to parse the buffer located in \p
234 * Buf of size \p Size bytes.
235 *
236 * \p Buf cannot be `NULL`.
237 *
238 * This function should be paired with LLVMRemarkParserDispose() to avoid
239 * leaking resources.
240 *
241 * \since REMARKS_API_VERSION=0
242 */
243extern LLVMRemarkParserRef LLVMRemarkParserCreateYAML(const void *Buf,
244 uint64_t Size);
245
246/**
247 * Creates a remark parser that can be used to parse the buffer located in \p
248 * Buf of size \p Size bytes.
249 *
250 * \p Buf cannot be `NULL`.
251 *
252 * This function should be paired with LLVMRemarkParserDispose() to avoid
253 * leaking resources.
254 *
255 * \since REMARKS_API_VERSION=1
256 */
257extern LLVMRemarkParserRef LLVMRemarkParserCreateBitstream(const void *Buf,
258 uint64_t Size);
259
260/**
261 * Returns the next remark in the file.
262 *
263 * The value pointed to by the return value needs to be disposed using a call to
264 * LLVMRemarkEntryDispose().
265 *
266 * All the entries in the returned value that are of LLVMRemarkStringRef type
267 * will become invalidated once a call to LLVMRemarkParserDispose is made.
268 *
269 * If the parser reaches the end of the buffer, the return value will be `NULL`.
270 *
271 * In the case of an error, the return value will be `NULL`, and:
272 *
273 * 1) LLVMRemarkParserHasError() will return `1`.
274 *
275 * 2) LLVMRemarkParserGetErrorMessage() will return a descriptive error
276 * message.
277 *
278 * An error may occur if:
279 *
280 * 1) An argument is invalid.
281 *
282 * 2) There is a parsing error. This can occur on things like malformed YAML.
283 *
284 * 3) There is a Remark semantic error. This can occur on well-formed files with
285 * missing or extra fields.
286 *
287 * Here is a quick example of the usage:
288 *
289 * ```
290 * LLVMRemarkParserRef Parser = LLVMRemarkParserCreateYAML(Buf, Size);
291 * LLVMRemarkEntryRef Remark = NULL;
292 * while ((Remark = LLVMRemarkParserGetNext(Parser))) {
293 * // use Remark
294 * LLVMRemarkEntryDispose(Remark); // Release memory.
295 * }
296 * bool HasError = LLVMRemarkParserHasError(Parser);
297 * LLVMRemarkParserDispose(Parser);
298 * ```
299 *
300 * \since REMARKS_API_VERSION=0
301 */
302extern LLVMRemarkEntryRef LLVMRemarkParserGetNext(LLVMRemarkParserRef Parser);
303
304/**
305 * Returns `1` if the parser encountered an error while parsing the buffer.
306 *
307 * \since REMARKS_API_VERSION=0
308 */
309extern LLVMBool LLVMRemarkParserHasError(LLVMRemarkParserRef Parser);
310
311/**
312 * Returns a null-terminated string containing an error message.
313 *
314 * In case of no error, the result is `NULL`.
315 *
316 * The memory of the string is bound to the lifetime of \p Parser. If
317 * LLVMRemarkParserDispose() is called, the memory of the string will be
318 * released.
319 *
320 * \since REMARKS_API_VERSION=0
321 */
322extern const char *LLVMRemarkParserGetErrorMessage(LLVMRemarkParserRef Parser);
323
324/**
325 * Releases all the resources used by \p Parser.
326 *
327 * \since REMARKS_API_VERSION=0
328 */
329extern void LLVMRemarkParserDispose(LLVMRemarkParserRef Parser);
330
331/**
332 * Returns the version of the remarks library.
333 *
334 * \since REMARKS_API_VERSION=0
335 */
336extern uint32_t LLVMRemarkVersion(void);
337
338/**
339 * @} // endgoup LLVMCREMARKS
340 */
341
342LLVM_C_EXTERN_C_END
343
344#endif /* LLVM_C_REMARKS_H */
345