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