LLVM  10.0.0svn
BitstreamRemarkParser.cpp
Go to the documentation of this file.
1 //===- BitstreamRemarkParser.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"
18 
19 using namespace llvm;
20 using namespace llvm::remarks;
21 
22 static Error unknownRecord(const char *BlockName, unsigned RecordID) {
23  return createStringError(
24  std::make_error_code(std::errc::illegal_byte_sequence),
25  "Error while parsing %s: unknown record entry (%lu).", BlockName,
26  RecordID);
27 }
28 
29 static Error malformedRecord(const char *BlockName, const char *RecordName) {
30  return createStringError(
31  std::make_error_code(std::errc::illegal_byte_sequence),
32  "Error while parsing %s: malformed record entry (%s).", BlockName,
33  RecordName);
34 }
35 
37  BitstreamCursor &Stream, BitstreamBlockInfo &BlockInfo)
38  : Stream(Stream), BlockInfo(BlockInfo) {}
39 
40 /// Parse a record and fill in the fields in the parser.
41 static Error parseRecord(BitstreamMetaParserHelper &Parser, unsigned Code) {
42  BitstreamCursor &Stream = Parser.Stream;
43  // Note: 2 is used here because it's the max number of fields we have per
44  // record.
46  StringRef Blob;
47  Expected<unsigned> RecordID = Stream.readRecord(Code, Record, &Blob);
48  if (!RecordID)
49  return RecordID.takeError();
50 
51  switch (*RecordID) {
53  if (Record.size() != 2)
54  return malformedRecord("BLOCK_META", "RECORD_META_CONTAINER_INFO");
55  Parser.ContainerVersion = Record[0];
56  Parser.ContainerType = Record[1];
57  break;
58  }
60  if (Record.size() != 1)
61  return malformedRecord("BLOCK_META", "RECORD_META_REMARK_VERSION");
62  Parser.RemarkVersion = Record[0];
63  break;
64  }
65  case RECORD_META_STRTAB: {
66  if (Record.size() != 0)
67  return malformedRecord("BLOCK_META", "RECORD_META_STRTAB");
68  Parser.StrTabBuf = Blob;
69  break;
70  }
72  if (Record.size() != 0)
73  return malformedRecord("BLOCK_META", "RECORD_META_EXTERNAL_FILE");
74  Parser.ExternalFilePath = Blob;
75  break;
76  }
77  default:
78  return unknownRecord("BLOCK_META", *RecordID);
79  }
80  return Error::success();
81 }
82 
85  : Stream(Stream) {}
86 
87 /// Parse a record and fill in the fields in the parser.
88 static Error parseRecord(BitstreamRemarkParserHelper &Parser, unsigned Code) {
89  BitstreamCursor &Stream = Parser.Stream;
90  // Note: 5 is used here because it's the max number of fields we have per
91  // record.
93  StringRef Blob;
94  Expected<unsigned> RecordID = Stream.readRecord(Code, Record, &Blob);
95  if (!RecordID)
96  return RecordID.takeError();
97 
98  switch (*RecordID) {
99  case RECORD_REMARK_HEADER: {
100  if (Record.size() != 4)
101  return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_HEADER");
102  Parser.Type = Record[0];
103  Parser.RemarkNameIdx = Record[1];
104  Parser.PassNameIdx = Record[2];
105  Parser.FunctionNameIdx = Record[3];
106  break;
107  }
109  if (Record.size() != 3)
110  return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_DEBUG_LOC");
111  Parser.SourceFileNameIdx = Record[0];
112  Parser.SourceLine = Record[1];
113  Parser.SourceColumn = Record[2];
114  break;
115  }
116  case RECORD_REMARK_HOTNESS: {
117  if (Record.size() != 1)
118  return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_HOTNESS");
119  Parser.Hotness = Record[0];
120  break;
121  }
123  if (Record.size() != 5)
124  return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_ARG_WITH_DEBUGLOC");
125  // Create a temporary argument. Use that as a valid memory location for this
126  // argument entry.
127  Parser.TmpArgs.emplace_back();
128  Parser.TmpArgs.back().KeyIdx = Record[0];
129  Parser.TmpArgs.back().ValueIdx = Record[1];
130  Parser.TmpArgs.back().SourceFileNameIdx = Record[2];
131  Parser.TmpArgs.back().SourceLine = Record[3];
132  Parser.TmpArgs.back().SourceColumn = Record[4];
133  Parser.Args =
135  break;
136  }
138  if (Record.size() != 2)
139  return malformedRecord("BLOCK_REMARK",
140  "RECORD_REMARK_ARG_WITHOUT_DEBUGLOC");
141  // Create a temporary argument. Use that as a valid memory location for this
142  // argument entry.
143  Parser.TmpArgs.emplace_back();
144  Parser.TmpArgs.back().KeyIdx = Record[0];
145  Parser.TmpArgs.back().ValueIdx = Record[1];
146  Parser.Args =
148  break;
149  }
150  default:
151  return unknownRecord("BLOCK_REMARK", *RecordID);
152  }
153  return Error::success();
154 }
155 
156 template <typename T>
157 static Error parseBlock(T &ParserHelper, unsigned BlockID,
158  const char *BlockName) {
159  BitstreamCursor &Stream = ParserHelper.Stream;
160  Expected<BitstreamEntry> Next = Stream.advance();
161  if (!Next)
162  return Next.takeError();
163  if (Next->Kind != BitstreamEntry::SubBlock || Next->ID != BlockID)
164  return createStringError(
165  std::make_error_code(std::errc::illegal_byte_sequence),
166  "Error while parsing %s: expecting [ENTER_SUBBLOCK, %s, ...].",
167  BlockName, BlockName);
168  if (Stream.EnterSubBlock(BlockID))
169  return createStringError(
170  std::make_error_code(std::errc::illegal_byte_sequence),
171  "Error while entering %s.", BlockName);
172 
173  // Stop when there is nothing to read anymore or when we encounter an
174  // END_BLOCK.
175  while (!Stream.AtEndOfStream()) {
176  Expected<BitstreamEntry> Next = Stream.advance();
177  if (!Next)
178  return Next.takeError();
179  switch (Next->Kind) {
181  return Error::success();
184  return createStringError(
185  std::make_error_code(std::errc::illegal_byte_sequence),
186  "Error while parsing %s: expecting records.", BlockName);
188  if (Error E = parseRecord(ParserHelper, Next->ID))
189  return E;
190  continue;
191  }
192  }
193  // If we're here, it means we didn't get an END_BLOCK yet, but we're at the
194  // end of the stream. In this case, error.
195  return createStringError(
196  std::make_error_code(std::errc::illegal_byte_sequence),
197  "Error while parsing %s: unterminated block.", BlockName);
198 }
199 
201  return parseBlock(*this, META_BLOCK_ID, "META_BLOCK");
202 }
203 
205  return parseBlock(*this, REMARK_BLOCK_ID, "REMARK_BLOCK");
206 }
207 
209  : Stream(Buffer) {}
210 
212  std::array<char, 4> Result;
213  for (unsigned i = 0; i < 4; ++i)
214  if (Expected<unsigned> R = Stream.Read(8))
215  Result[i] = *R;
216  else
217  return R.takeError();
218  return Result;
219 }
220 
223  if (!Next)
224  return Next.takeError();
225  if (Next->Kind != BitstreamEntry::SubBlock ||
226  Next->ID != llvm::bitc::BLOCKINFO_BLOCK_ID)
227  return createStringError(
228  std::make_error_code(std::errc::illegal_byte_sequence),
229  "Error while parsing BLOCKINFO_BLOCK: expecting [ENTER_SUBBLOCK, "
230  "BLOCKINFO_BLOCK, ...].");
231 
232  Expected<Optional<BitstreamBlockInfo>> MaybeBlockInfo =
234  if (!MaybeBlockInfo)
235  return MaybeBlockInfo.takeError();
236 
237  if (!*MaybeBlockInfo)
238  return createStringError(
239  std::make_error_code(std::errc::illegal_byte_sequence),
240  "Error while parsing BLOCKINFO_BLOCK.");
241 
242  BlockInfo = **MaybeBlockInfo;
243 
245  return Error::success();
246 }
247 
248 static Expected<bool> isBlock(BitstreamCursor &Stream, unsigned BlockID) {
249  bool Result = false;
250  uint64_t PreviousBitNo = Stream.GetCurrentBitNo();
251  Expected<BitstreamEntry> Next = Stream.advance();
252  if (!Next)
253  return Next.takeError();
254  switch (Next->Kind) {
256  // Check for the block id.
257  Result = Next->ID == BlockID;
258  break;
260  return createStringError(
261  std::make_error_code(std::errc::illegal_byte_sequence),
262  "Unexpected error while parsing bitstream.");
263  default:
264  Result = false;
265  break;
266  }
267  if (Error E = Stream.JumpToBit(PreviousBitNo))
268  return std::move(E);
269  return Result;
270 }
271 
273  return isBlock(Stream, META_BLOCK_ID);
274 }
275 
277  return isBlock(Stream, META_BLOCK_ID);
278 }
279 
281  if (Magic != remarks::ContainerMagic)
282  return createStringError(std::make_error_code(std::errc::invalid_argument),
283  "Unknown magic number: expecting %s, got %.4s.",
284  remarks::ContainerMagic.data(), Magic.data());
285  return Error::success();
286 }
287 
290  if (!Magic)
291  return Magic.takeError();
292  if (Error E = validateMagicNumber(StringRef(Magic->data(), Magic->size())))
293  return E;
294  if (Error E = Helper.parseBlockInfoBlock())
295  return E;
297  if (!isMetaBlock)
298  return isMetaBlock.takeError();
299  if (!*isMetaBlock)
300  return createStringError(
301  std::make_error_code(std::errc::illegal_byte_sequence),
302  "Expecting META_BLOCK after the BLOCKINFO_BLOCK.");
303  return Error::success();
304 }
305 
309  BitstreamParserHelper Helper(Buf);
311  if (!Magic)
312  return Magic.takeError();
313 
314  if (Error E = validateMagicNumber(StringRef(Magic->data(), Magic->size())))
315  return std::move(E);
316 
317  return StrTab
318  ? std::make_unique<BitstreamRemarkParser>(Buf, std::move(*StrTab))
319  : std::make_unique<BitstreamRemarkParser>(Buf);
320 }
321 
323  if (ParserHelper.atEndOfStream())
324  return make_error<EndOfFileError>();
325 
326  if (!ReadyToParseRemarks) {
327  if (Error E = parseMeta())
328  return std::move(E);
329  ReadyToParseRemarks = true;
330  }
331 
332  return parseRemark();
333 }
334 
336  // Advance and to the meta block.
337  if (Error E = advanceToMetaBlock(ParserHelper))
338  return E;
339 
340  BitstreamMetaParserHelper MetaHelper(ParserHelper.Stream,
341  ParserHelper.BlockInfo);
342  if (Error E = MetaHelper.parse())
343  return E;
344 
345  if (Error E = processCommonMeta(MetaHelper))
346  return E;
347 
348  switch (ContainerType) {
350  return processStandaloneMeta(MetaHelper);
352  return processSeparateRemarksFileMeta(MetaHelper);
354  return processSeparateRemarksMetaMeta(MetaHelper);
355  }
356  llvm_unreachable("Unknown BitstreamRemarkContainerType enum");
357 }
358 
359 Error BitstreamRemarkParser::processCommonMeta(
360  BitstreamMetaParserHelper &MetaHelper) {
362  ContainerVersion = *Version;
363  else
364  return createStringError(
365  std::make_error_code(std::errc::illegal_byte_sequence),
366  "Error while parsing BLOCK_META: missing container version.");
367 
368  if (Optional<uint8_t> Type = MetaHelper.ContainerType) {
369  // Always >= BitstreamRemarkContainerType::First since it's unsigned.
370  if (*Type > static_cast<uint8_t>(BitstreamRemarkContainerType::Last))
371  return createStringError(
372  std::make_error_code(std::errc::illegal_byte_sequence),
373  "Error while parsing BLOCK_META: invalid container type.");
374 
375  ContainerType = static_cast<BitstreamRemarkContainerType>(*Type);
376  } else
377  return createStringError(
378  std::make_error_code(std::errc::illegal_byte_sequence),
379  "Error while parsing BLOCK_META: missing container type.");
380 
381  return Error::success();
382 }
383 
385  Optional<StringRef> StrTabBuf) {
386  if (!StrTabBuf)
387  return createStringError(
388  std::make_error_code(std::errc::illegal_byte_sequence),
389  "Error while parsing BLOCK_META: missing string table.");
390  // Parse and assign the string table.
391  P.StrTab.emplace(*StrTabBuf);
392  return Error::success();
393 }
394 
396  Optional<uint64_t> RemarkVersion) {
397  if (!RemarkVersion)
398  return createStringError(
399  std::make_error_code(std::errc::illegal_byte_sequence),
400  "Error while parsing BLOCK_META: missing remark version.");
401  P.RemarkVersion = *RemarkVersion;
402  return Error::success();
403 }
404 
405 Error BitstreamRemarkParser::processExternalFilePath(
406  Optional<StringRef> ExternalFilePath) {
407  if (!ExternalFilePath)
408  return createStringError(
409  std::make_error_code(std::errc::illegal_byte_sequence),
410  "Error while parsing BLOCK_META: missing external file path.");
411 
412  // External file: open the external file, parse it, check if its metadata
413  // matches the one from the separate metadata, then replace the current parser
414  // with the one parsing the remarks.
416  MemoryBuffer::getFile(*ExternalFilePath);
417  if (std::error_code EC = BufferOrErr.getError())
418  return errorCodeToError(EC);
419  TmpRemarkBuffer = std::move(*BufferOrErr);
420 
421  // Create a separate parser used for parsing the separate file.
422  ParserHelper = BitstreamParserHelper(TmpRemarkBuffer->getBuffer());
423  // Advance and check until we can parse the meta block.
424  if (Error E = advanceToMetaBlock(ParserHelper))
425  return E;
426  // Parse the meta from the separate file.
427  // Note: here we overwrite the BlockInfo with the one from the file. This will
428  // be used to parse the rest of the file.
429  BitstreamMetaParserHelper SeparateMetaHelper(ParserHelper.Stream,
430  ParserHelper.BlockInfo);
431  if (Error E = SeparateMetaHelper.parse())
432  return E;
433 
434  uint64_t PreviousContainerVersion = ContainerVersion;
435  if (Error E = processCommonMeta(SeparateMetaHelper))
436  return E;
437 
439  return createStringError(
440  std::make_error_code(std::errc::illegal_byte_sequence),
441  "Error while parsing external file's BLOCK_META: wrong container "
442  "type.");
443 
444  if (PreviousContainerVersion != ContainerVersion)
445  return createStringError(
446  std::make_error_code(std::errc::illegal_byte_sequence),
447  "Error while parsing external file's BLOCK_META: mismatching versions: "
448  "original meta: %lu, external file meta: %lu.",
449  PreviousContainerVersion, ContainerVersion);
450 
451  // Process the meta from the separate file.
452  return processSeparateRemarksFileMeta(SeparateMetaHelper);
453 }
454 
455 Error BitstreamRemarkParser::processStandaloneMeta(
456  BitstreamMetaParserHelper &Helper) {
457  if (Error E = processStrTab(*this, Helper.StrTabBuf))
458  return E;
459  return processRemarkVersion(*this, Helper.RemarkVersion);
460 }
461 
462 Error BitstreamRemarkParser::processSeparateRemarksFileMeta(
463  BitstreamMetaParserHelper &Helper) {
464  return processRemarkVersion(*this, Helper.RemarkVersion);
465 }
466 
467 Error BitstreamRemarkParser::processSeparateRemarksMetaMeta(
468  BitstreamMetaParserHelper &Helper) {
469  if (Error E = processStrTab(*this, Helper.StrTabBuf))
470  return E;
471  return processExternalFilePath(Helper.ExternalFilePath);
472 }
473 
475  BitstreamRemarkParserHelper RemarkHelper(ParserHelper.Stream);
476  if (Error E = RemarkHelper.parse())
477  return std::move(E);
478 
479  return processRemark(RemarkHelper);
480 }
481 
483 BitstreamRemarkParser::processRemark(BitstreamRemarkParserHelper &Helper) {
484  std::unique_ptr<Remark> Result = std::make_unique<Remark>();
485  Remark &R = *Result;
486 
487  if (StrTab == None)
488  return createStringError(
489  std::make_error_code(std::errc::invalid_argument),
490  "Error while parsing BLOCK_REMARK: missing string table.");
491 
492  if (!Helper.Type)
493  return createStringError(
494  std::make_error_code(std::errc::illegal_byte_sequence),
495  "Error while parsing BLOCK_REMARK: missing remark type.");
496 
497  // Always >= Type::First since it's unsigned.
498  if (*Helper.Type > static_cast<uint8_t>(Type::Last))
499  return createStringError(
500  std::make_error_code(std::errc::illegal_byte_sequence),
501  "Error while parsing BLOCK_REMARK: unknown remark type.");
502 
503  R.RemarkType = static_cast<Type>(*Helper.Type);
504 
505  if (!Helper.RemarkNameIdx)
506  return createStringError(
507  std::make_error_code(std::errc::illegal_byte_sequence),
508  "Error while parsing BLOCK_REMARK: missing remark name.");
509 
510  if (Expected<StringRef> RemarkName = (*StrTab)[*Helper.RemarkNameIdx])
511  R.RemarkName = *RemarkName;
512  else
513  return RemarkName.takeError();
514 
515  if (!Helper.PassNameIdx)
516  return createStringError(
517  std::make_error_code(std::errc::illegal_byte_sequence),
518  "Error while parsing BLOCK_REMARK: missing remark pass.");
519 
520  if (Expected<StringRef> PassName = (*StrTab)[*Helper.PassNameIdx])
521  R.PassName = *PassName;
522  else
523  return PassName.takeError();
524 
525  if (!Helper.FunctionNameIdx)
526  return createStringError(
527  std::make_error_code(std::errc::illegal_byte_sequence),
528  "Error while parsing BLOCK_REMARK: missing remark function name.");
529  if (Expected<StringRef> FunctionName = (*StrTab)[*Helper.FunctionNameIdx])
530  R.FunctionName = *FunctionName;
531  else
532  return FunctionName.takeError();
533 
534  if (Helper.SourceFileNameIdx && Helper.SourceLine && Helper.SourceColumn) {
535  Expected<StringRef> SourceFileName = (*StrTab)[*Helper.SourceFileNameIdx];
536  if (!SourceFileName)
537  return SourceFileName.takeError();
538  R.Loc.emplace();
539  R.Loc->SourceFilePath = *SourceFileName;
540  R.Loc->SourceLine = *Helper.SourceLine;
541  R.Loc->SourceColumn = *Helper.SourceColumn;
542  }
543 
544  if (Helper.Hotness)
545  R.Hotness = *Helper.Hotness;
546 
547  if (!Helper.Args)
548  return std::move(Result);
549 
550  for (const BitstreamRemarkParserHelper::Argument &Arg : *Helper.Args) {
551  if (!Arg.KeyIdx)
552  return createStringError(
553  std::make_error_code(std::errc::illegal_byte_sequence),
554  "Error while parsing BLOCK_REMARK: missing key in remark argument.");
555  if (!Arg.ValueIdx)
556  return createStringError(
557  std::make_error_code(std::errc::illegal_byte_sequence),
558  "Error while parsing BLOCK_REMARK: missing value in remark "
559  "argument.");
560 
561  // We have at least a key and a value, create an entry.
562  R.Args.emplace_back();
563 
564  if (Expected<StringRef> Key = (*StrTab)[*Arg.KeyIdx])
565  R.Args.back().Key = *Key;
566  else
567  return Key.takeError();
568 
569  if (Expected<StringRef> Value = (*StrTab)[*Arg.ValueIdx])
570  R.Args.back().Val = *Value;
571  else
572  return Value.takeError();
573 
574  if (Arg.SourceFileNameIdx && Arg.SourceLine && Arg.SourceColumn) {
575  if (Expected<StringRef> SourceFileName =
576  (*StrTab)[*Arg.SourceFileNameIdx]) {
577  R.Args.back().Loc.emplace();
578  R.Args.back().Loc->SourceFilePath = *SourceFileName;
579  R.Args.back().Loc->SourceLine = *Arg.SourceLine;
580  R.Args.back().Loc->SourceColumn = *Arg.SourceColumn;
581  } else
582  return SourceFileName.takeError();
583  }
584  }
585 
586  return std::move(Result);
587 }
const NoneType None
Definition: None.h:23
Represents either an error or a value T.
Definition: ErrorOr.h:56
BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...
Definition: BitCodes.h:70
Helper to parse any bitstream remark container.
static Error advanceToMetaBlock(BitstreamParserHelper &Helper)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
uint64_t GetCurrentBitNo() const
Return the bit # of the bit we are reading.
Error parse()
Parse the REMARK_BLOCK and fill the available entries.
Error parseMeta()
Parse and process the metadata of the buffer.
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
Helper to parse a META_BLOCK for a bitstream remark container.
void setBlockInfo(BitstreamBlockInfo *BI)
Set the block info to be used by this BitstreamCursor to interpret abbreviated records.
static Error parseBlock(T &ParserHelper, unsigned BlockID, const char *BlockName)
Helper to parse a REMARK_BLOCK for a bitstream remark container.
Expected< BitstreamEntry > advance(unsigned Flags=0)
Advance the current bitstream, returning the next entry in the stream.
A remark type used for both emission and parsing.
Definition: Remark.h:67
BitstreamParserHelper(StringRef Buffer)
Start parsing at Buffer.
std::error_code make_error_code(BitcodeError E)
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
Key
PAL metadata keys.
Optional< uint8_t > Type
The parsed content: depending on the remark, some fields might be empty.
SmallVector< Argument, 8 > TmpArgs
Avoid re-allocating a vector every time.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
Expected< std::unique_ptr< BitstreamRemarkParser > > createBitstreamParserFromMeta(StringRef Buf, Optional< ParsedStringTable > StrTab=None)
BitstreamCursor & Stream
The Bitstream reader.
constexpr StringLiteral Magic("REMARKS")
static Error unknownRecord(const char *BlockName, unsigned RecordID)
BitstreamCursor & Stream
The Bitstream reader.
static Error validateMagicNumber(StringRef Magic)
Type
The type of the remark.
Definition: Remark.h:54
Error parseBlockInfoBlock()
Parse the block info block containing all the abbrevs.
#define P(N)
Optional< uint64_t > ContainerVersion
The parsed content: depending on the container type, some fields might be empty.
BitstreamBlockInfo BlockInfo
The block info block.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:87
This represents a position within a bitcode file, implemented on top of a SimpleBitstreamCursor.
std::error_code getError() const
Definition: ErrorOr.h:159
Expected< Optional< BitstreamBlockInfo > > ReadBlockInfoBlock(bool ReadBlockInfoNames=false)
Read and return a block info block from the bitstream.
static Error processStrTab(BitstreamRemarkParser &P, Optional< StringRef > StrTabBuf)
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
One remark entry is represented using a REMARK_BLOCK.
size_t size() const
Definition: SmallVector.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Error JumpToBit(uint64_t BitNo)
Reset the stream to the specified bit number.
Expected< unsigned > readRecord(unsigned AbbrevID, SmallVectorImpl< uint64_t > &Vals, StringRef *Blob=nullptr)
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
constexpr StringLiteral ContainerMagic("RMRK")
The magic number used for identifying remark blocks.
static Error malformedRecord(const char *BlockName, const char *RecordName)
BitstreamRemarkParserHelper(BitstreamCursor &Stream)
Continue parsing with Stream.
Expected< std::unique_ptr< Remark > > next() override
If no error occurs, this returns a valid Remark object.
Expected< std::unique_ptr< Remark > > parseRemark()
Parse a Bitstream remark.
BitstreamCursor Stream
The Bitstream reader.
The metadata block is mandatory.
This class maintains the abbreviations read from a block info block.
Expected< bool > isMetaBlock()
Return true if the next block is a META_BLOCK.
static Error parseRecord(BitstreamMetaParserHelper &Parser, unsigned Code)
Parse a record and fill in the fields in the parser.
Error EnterSubBlock(unsigned BlockID, unsigned *NumWordsP=nullptr)
Having read the ENTER_SUBBLOCK abbrevid, and enter the block.
Optional< ParsedStringTable > StrTab
The string table used for parsing strings.
BitstreamMetaParserHelper(BitstreamCursor &Stream, BitstreamBlockInfo &BlockInfo)
Continue parsing with Stream.
Parses and holds the state of the latest parsed remark.
Expected< bool > isRemarkBlock()
Return true if the next block is a REMARK_BLOCK.
Expected< std::array< char, 4 > > parseMagic()
Parse the magic number.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:136
static Expected< bool > isBlock(BitstreamCursor &Stream, unsigned BlockID)
Error parse()
Parse the META_BLOCK and fill the available entries.
LLVM Value Representation.
Definition: Value.h:74
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
BitstreamRemarkContainerType
Type of the remark container.
Expected< word_t > Read(unsigned NumBits)
static Error processRemarkVersion(BitstreamRemarkParser &P, Optional< uint64_t > RemarkVersion)
const uint64_t Version
Definition: InstrProf.h:980
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1177