1//===- YAMLRemarkParser.cpp -----------------------------------------------===// 
  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 
  7//===----------------------------------------------------------------------===// 
  9// This file provides utility methods used by clients that want to use the 
  10// parser for remark diagnostics in LLVM. 
  12//===----------------------------------------------------------------------===// 
  27 assert(Ctx && 
"Expected non-null Ctx in diagnostic handler.");
 
  28 std::string &Message = *
static_cast<std::string *
>(Ctx);
 
  29 assert(Message.empty() && 
"Expected an empty string.");
 
  31 Diag.
print(
/*ProgName=*/nullptr, OS, 
/*ShowColors*/ false,
 
  32 /*ShowKindLabels*/ true);
 
 
  39 // 1) Set up a diagnostic handler to avoid errors being printed out to 
  41 // 2) Use the stream to print the error with the associated node. 
  42 // 3) The stream will use the source manager to print the error, which will 
  43 // call the diagnostic handler. 
  44 // 4) The diagnostic handler will stream the error directly into this object's 
  45 // Message member, which is used when logging is asked for. 
  50 // Restore the old handlers. 
 
  60// Parse the magic number. This function returns true if this represents remark 
  61// metadata, false otherwise. 
  68 "Expecting \0円 after magic number.");
 
 
  75 "Expecting version number.");
 
  81 "Mismatching remark version. Got %" PRId64
 
  82 ", expected %" PRId64 
".",
 
 
  91 "Expecting string table size.");
 
 
  99 StringRef Buf, std::optional<StringRef> ExternalFilePrependPath) {
 
  100 // We now have a magic number. The metadata has to be correct. 
  104 // If it's not recognized as metadata, roll back. 
  105 std::unique_ptr<MemoryBuffer> SeparateBuf;
 
  115 if (*StrTabSize != 0) {
 
  117 "String table unsupported for YAML format.");
 
  119 // If it starts with "---", there is no external file. 
  121 // At this point, we expect Buf to contain the external file path. 
  124 if (ExternalFilePrependPath)
 
  125 FullPath = *ExternalFilePrependPath;
 
  128 // Try to open the file and start parsing from there. 
  131 if (std::error_code EC = BufferOrErr.
getError())
 
  134 // Keep the buffer alive. 
  135 SeparateBuf = std::move(*BufferOrErr);
 
  136 Buf = SeparateBuf->getBuffer();
 
  140 std::unique_ptr<YAMLRemarkParser> Result =
 
  141 std::make_unique<YAMLRemarkParser>(Buf);
 
  143 Result->SeparateBuf = std::move(SeparateBuf);
 
  144 return std::move(Result);
 
 
  171 "not a valid YAML file.");
 
  176 return error(
"document root is not of mapping type.", *YAMLRoot);
 
  178 std::unique_ptr<Remark> Result = std::make_unique<Remark>();
 
  179 Remark &TheRemark = *Result;
 
  181 // First, the type. It needs special handling since is not part of the 
  185 return T.takeError();
 
  189 // Then, parse the fields, one by one. 
  196 if (KeyName == 
"Pass") {
 
  200 return MaybeStr.takeError();
 
  201 } 
else if (KeyName == 
"Name") {
 
  205 return MaybeStr.takeError();
 
  206 } 
else if (KeyName == 
"Function") {
 
  210 return MaybeStr.takeError();
 
  211 } 
else if (KeyName == 
"Hotness") {
 
  215 return MaybeU.takeError();
 
  216 } 
else if (KeyName == 
"DebugLoc") {
 
  218 TheRemark.
Loc = *MaybeLoc;
 
  220 return MaybeLoc.takeError();
 
  221 } 
else if (KeyName == 
"Args") {
 
  224 return error(
"wrong value type for key.", RemarkField);
 
  228 TheRemark.
Args.push_back(*MaybeArg);
 
  230 return MaybeArg.takeError();
 
  233 return error(
"unknown key.", RemarkField);
 
  237 // Check if any of the mandatory fields are missing. 
  240 return error(
"Type, Pass, Name or Function missing.",
 
  243 return std::move(Result);
 
 
  256 return error(
"expected a remark tag.", 
Node);
 
 
  262 return Key->getRawValue();
 
  264 return error(
"key is not a string.", 
Node);
 
 
  272 // Try to parse the value as a block node. 
  275 return error(
"expected a value of scalar type.", 
Node);
 
  278 Result = 
Value->getRawValue();
 
  280 Result.consume_front(
"\'");
 
  281 Result.consume_back(
"\'");
 
 
  290 return error(
"expected a value of scalar type.", 
Node);
 
  291 unsigned UnsignedValue = 0;
 
  292 if (
Value->getValue(Tmp).getAsInteger(10, UnsignedValue))
 
  293 return error(
"expected a value of integer type.", *
Value);
 
  294 return UnsignedValue;
 
 
  301 return error(
"expected a value of mapping type.", 
Node);
 
  303 std::optional<StringRef> File;
 
  304 std::optional<unsigned> Line;
 
  305 std::optional<unsigned> Column;
 
  313 if (KeyName == 
"File") {
 
  317 return MaybeStr.takeError();
 
  318 } 
else if (KeyName == 
"Column") {
 
  322 return MaybeU.takeError();
 
  323 } 
else if (KeyName == 
"Line") {
 
  327 return MaybeU.takeError();
 
  329 return error(
"unknown entry in DebugLoc map.", DLNode);
 
  333 // If any of the debug loc fields is missing, return an error. 
  334 if (!File || !Line || !Column)
 
  335 return error(
"DebugLoc node incomplete.", 
Node);
 
 
  343 return error(
"expected a value of mapping type.", 
Node);
 
  345 std::optional<StringRef> KeyStr;
 
  346 std::optional<StringRef> ValueStr;
 
  347 std::optional<RemarkLocation> 
Loc;
 
  355 // Try to parse debug locs. 
  356 if (KeyName == 
"DebugLoc") {
 
  357 // Can't have multiple DebugLoc entries per argument. 
  359 return error(
"only one DebugLoc entry is allowed per argument.",
 
  366 return MaybeLoc.takeError();
 
  369 // If we already have a string, error out. 
  371 return error(
"only one string entry is allowed per argument.", ArgEntry);
 
  373 // Try to parse the value. 
  375 ValueStr = *MaybeStr;
 
  377 return MaybeStr.takeError();
 
  379 // Keep the key from the string. 
  384 return error(
"argument key is missing.", *ArgMap);
 
  386 return error(
"argument value is missing.", *ArgMap);
 
 
  401 // Avoid garbage input, set the iterator to the end. 
  408 return std::move(*MaybeResult);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static Version parseVersion(StringRef Name)
 
This file defines the SmallString class.
 
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
 
Represents either an error or a value T.
 
std::error_code getError() const
 
Lightweight error class with error context and mandatory checking.
 
static ErrorSuccess success()
Create a success value.
 
Tagged union holding either a T or a Error.
 
Error takeError()
Take ownership of the stored error.
 
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
 
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
 
LLVM_ABI void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true, bool ShowLocation=true) const
 
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
 
void * getDiagContext() const
 
DiagHandlerTy getDiagHandler() const
 
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
 
StringRef - Represent a constant reference to a string, i.e.
 
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
 
constexpr bool empty() const
empty - Check if the string is empty.
 
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
 
constexpr size_t size() const
size - Get the string size.
 
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
 
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
 
A switch()-like statement whose cases are string literals.
 
StringSwitch & Case(StringLiteral S, T Value)
 
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
 
LLVM Value Representation.
 
A raw_ostream that writes to an std::string.
 
A block scalar node is an opaque datum that can be presented as a series of zero or more Unicode scal...
 
StringRef getValue() const
Gets the value of this node as a StringRef.
 
A YAML Stream is a sequence of Documents.
 
Node * getRoot()
Parse and return the root level node.
 
Represents a YAML map created from either a block map for a flow map.
 
Abstract base class for all Nodes.
 
This class represents a YAML stream potentially containing multiple documents.
 
LLVM_ABI void printError(Node *N, const Twine &Msg, SourceMgr::DiagKind Kind=SourceMgr::DK_Error)
 
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
 
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
 
This is an optimization pass for GlobalISel generic memory operations.
 
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
 
FunctionAddr VTableAddr uintptr_t uintptr_t Version
 
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
 
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.