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 #include "llvm/Support/Path.h"
19 
20 using namespace llvm;
21 using namespace llvm::remarks;
22 
23 static Error unknownRecord(const char *BlockName, unsigned RecordID) {
24  return createStringError(
25  std::make_error_code(std::errc::illegal_byte_sequence),
26  "Error while parsing %s: unknown record entry (%lu).", BlockName,
27  RecordID);
28 }
29 
30 static Error malformedRecord(const char *BlockName, const char *RecordName) {
31  return createStringError(
32  std::make_error_code(std::errc::illegal_byte_sequence),
33  "Error while parsing %s: malformed record entry (%s).", BlockName,
34  RecordName);
35 }
36 
38  BitstreamCursor &Stream, BitstreamBlockInfo &BlockInfo)
39  : Stream(Stream), BlockInfo(BlockInfo) {}
40 
41 /// Parse a record and fill in the fields in the parser.
42 static Error parseRecord(BitstreamMetaParserHelper &Parser, unsigned Code) {
43  BitstreamCursor &Stream = Parser.Stream;
44  // Note: 2 is used here because it's the max number of fields we have per
45  // record.
47  StringRef Blob;
48  Expected<unsigned> RecordID = Stream.readRecord(Code, Record, &Blob);
49  if (!RecordID)
50  return RecordID.takeError();
51 
52  switch (*RecordID) {
54  if (Record.size() != 2)
55  return malformedRecord("BLOCK_META", "RECORD_META_CONTAINER_INFO");
56  Parser.ContainerVersion = Record[0];
57  Parser.ContainerType = Record[1];
58  break;
59  }
61  if (Record.size() != 1)
62  return malformedRecord("BLOCK_META", "RECORD_META_REMARK_VERSION");
63  Parser.RemarkVersion = Record[0];
64  break;
65  }
66  case RECORD_META_STRTAB: {
67  if (Record.size() != 0)
68  return malformedRecord("BLOCK_META", "RECORD_META_STRTAB");
69  Parser.StrTabBuf = Blob;
70  break;
71  }
73  if (Record.size() != 0)
74  return malformedRecord("BLOCK_META", "RECORD_META_EXTERNAL_FILE");
75  Parser.ExternalFilePath = Blob;
76  break;
77  }
78  default:
79  return unknownRecord("BLOCK_META", *RecordID);
80  }
81  return Error::success();
82 }
83 
86  : Stream(Stream) {}
87 
88 /// Parse a record and fill in the fields in the parser.
89 static Error parseRecord(BitstreamRemarkParserHelper &Parser, unsigned Code) {
90  BitstreamCursor &Stream = Parser.Stream;
91  // Note: 5 is used here because it's the max number of fields we have per
92  // record.
94  StringRef Blob;
95  Expected<unsigned> RecordID = Stream.readRecord(Code, Record, &Blob);
96  if (!RecordID)
97  return RecordID.takeError();
98 
99  switch (*RecordID) {
100  case RECORD_REMARK_HEADER: {
101  if (Record.size() != 4)
102  return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_HEADER");
103  Parser.Type = Record[0];
104  Parser.RemarkNameIdx = Record[1];
105  Parser.PassNameIdx = Record[2];
106  Parser.FunctionNameIdx = Record[3];
107  break;
108  }
110  if (Record.size() != 3)
111  return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_DEBUG_LOC");
112  Parser.SourceFileNameIdx = Record[0];
113  Parser.SourceLine = Record[1];
114  Parser.SourceColumn = Record[2];
115  break;
116  }
117  case RECORD_REMARK_HOTNESS: {
118  if (Record.size() != 1)
119  return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_HOTNESS");
120  Parser.Hotness = Record[0];
121  break;
122  }
124  if (Record.size() != 5)
125  return malformedRecord("BLOCK_REMARK", "RECORD_REMARK_ARG_WITH_DEBUGLOC");
126  // Create a temporary argument. Use that as a valid memory location for this
127  // argument entry.
128  Parser.TmpArgs.emplace_back();
129  Parser.TmpArgs.back().KeyIdx = Record[0];
130  Parser.TmpArgs.back().ValueIdx = Record[1];
131  Parser.TmpArgs.back().SourceFileNameIdx = Record[2];
132  Parser.TmpArgs.back().SourceLine = Record[3];
133  Parser.TmpArgs.back().SourceColumn = Record[4];
134  Parser.Args =
136  break;
137  }
139  if (Record.size() != 2)
140  return malformedRecord("BLOCK_REMARK",
141  "RECORD_REMARK_ARG_WITHOUT_DEBUGLOC");
142  // Create a temporary argument. Use that as a valid memory location for this
143  // argument entry.
144  Parser.TmpArgs.emplace_back();
145  Parser.TmpArgs.back().KeyIdx = Record[0];
146  Parser.TmpArgs.back().ValueIdx = Record[1];
147  Parser.Args =
149  break;
150  }
151  default:
152  return unknownRecord("BLOCK_REMARK", *RecordID);
153  }
154  return Error::success();
155 }
156 
157 template <typename T>
158 static Error parseBlock(T &ParserHelper, unsigned BlockID,
159  const char *BlockName) {
160  BitstreamCursor &Stream = ParserHelper.Stream;
161  Expected<BitstreamEntry> Next = Stream.advance();
162  if (!Next)
163  return Next.takeError();
164  if (Next->Kind != BitstreamEntry::SubBlock || Next->ID != BlockID)
165  return createStringError(
166  std::make_error_code(std::errc::illegal_byte_sequence),
167  "Error while parsing %s: expecting [ENTER_SUBBLOCK, %s, ...].",
168  BlockName, BlockName);
169  if (Stream.EnterSubBlock(BlockID))
170  return createStringError(
171  std::make_error_code(std::errc::illegal_byte_sequence),
172  "Error while entering %s.", BlockName);
173 
174  // Stop when there is nothing to read anymore or when we encounter an
175  // END_BLOCK.
176  while (!Stream.AtEndOfStream()) {
177  Expected<BitstreamEntry> Next = Stream.advance();
178  if (!Next)
179  return Next.takeError();
180  switch (Next->Kind) {
182  return Error::success();
185  return createStringError(
186  std::make_error_code(std::errc::illegal_byte_sequence),
187  "Error while parsing %s: expecting records.", BlockName);
189  if (Error E = parseRecord(ParserHelper, Next->ID))
190  return E;
191  continue;
192  }
193  }
194  // If we're here, it means we didn't get an END_BLOCK yet, but we're at the
195  // end of the stream. In this case, error.
196  return createStringError(
197  std::make_error_code(std::errc::illegal_byte_sequence),
198  "Error while parsing %s: unterminated block.", BlockName);
199 }
200 
202  return parseBlock(*this, META_BLOCK_ID, "META_BLOCK");
203 }
204 
206  return parseBlock(*this, REMARK_BLOCK_ID, "REMARK_BLOCK");
207 }
208 
210  : Stream(Buffer) {}
211 
213  std::array<char, 4> Result;
214  for (unsigned i = 0; i < 4; ++i)
215  if (Expected<unsigned> R = Stream.Read(8))
216  Result[i] = *R;
217  else
218  return R.takeError();
219  return Result;
220 }
221 
224  if (!Next)
225  return Next.takeError();
226  if (Next->Kind != BitstreamEntry::SubBlock ||
227  Next->ID != llvm::bitc::BLOCKINFO_BLOCK_ID)
228  return createStringError(
229  std::make_error_code(std::errc::illegal_byte_sequence),
230  "Error while parsing BLOCKINFO_BLOCK: expecting [ENTER_SUBBLOCK, "
231  "BLOCKINFO_BLOCK, ...].");
232 
233  Expected<Optional<BitstreamBlockInfo>> MaybeBlockInfo =
235  if (!MaybeBlockInfo)
236  return MaybeBlockInfo.takeError();
237 
238  if (!*MaybeBlockInfo)
239  return createStringError(
240  std::make_error_code(std::errc::illegal_byte_sequence),
241  "Error while parsing BLOCKINFO_BLOCK.");
242 
243  BlockInfo = **MaybeBlockInfo;
244 
246  return Error::success();
247 }
248 
249 static Expected<bool> isBlock(BitstreamCursor &Stream, unsigned BlockID) {
250  bool Result = false;
251  uint64_t PreviousBitNo = Stream.GetCurrentBitNo();
252  Expected<BitstreamEntry> Next = Stream.advance();
253  if (!Next)
254  return Next.takeError();
255  switch (Next->Kind) {
257  // Check for the block id.
258  Result = Next->ID == BlockID;
259  break;
261  return createStringError(
262  std::make_error_code(std::errc::illegal_byte_sequence),
263  "Unexpected error while parsing bitstream.");
264  default:
265  Result = false;
266  break;
267  }
268  if (Error E = Stream.JumpToBit(PreviousBitNo))
269  return std::move(E);
270  return Result;
271 }
272 
274  return isBlock(Stream, META_BLOCK_ID);
275 }
276 
278  return isBlock(Stream, META_BLOCK_ID);
279 }
280 
282  if (Magic != remarks::ContainerMagic)
283  return createStringError(std::make_error_code(std::errc::invalid_argument),
284  "Unknown magic number: expecting %s, got %.4s.",
285  remarks::ContainerMagic.data(), Magic.data());
286  return Error::success();
287 }
288 
291  if (!Magic)
292  return Magic.takeError();
293  if (Error E = validateMagicNumber(StringRef(Magic->data(), Magic->size())))
294  return E;
295  if (Error E = Helper.parseBlockInfoBlock())
296  return E;
298  if (!isMetaBlock)
299  return isMetaBlock.takeError();
300  if (!*isMetaBlock)
301  return createStringError(
302  std::make_error_code(std::errc::illegal_byte_sequence),
303  "Expecting META_BLOCK after the BLOCKINFO_BLOCK.");
304  return Error::success();
305 }
306 
310  Optional<StringRef> ExternalFilePrependPath) {
311  BitstreamParserHelper Helper(Buf);
313  if (!Magic)
314  return Magic.takeError();
315 
316  if (Error E = validateMagicNumber(StringRef(Magic->data(), Magic->size())))
317  return std::move(E);
318 
319  auto Parser =
320  StrTab ? std::make_unique<BitstreamRemarkParser>(Buf, std::move(*StrTab))
321  : std::make_unique<BitstreamRemarkParser>(Buf);
322 
323  if (ExternalFilePrependPath)
324  Parser->ExternalFilePrependPath = *ExternalFilePrependPath;
325 
326  return std::move(Parser);
327 }
328 
330  if (ParserHelper.atEndOfStream())
331  return make_error<EndOfFileError>();
332 
333  if (!ReadyToParseRemarks) {
334  if (Error E = parseMeta())
335  return std::move(E);
336  ReadyToParseRemarks = true;
337  }
338 
339  return parseRemark();
340 }
341 
343  // Advance and to the meta block.
344  if (Error E = advanceToMetaBlock(ParserHelper))
345  return E;
346 
347  BitstreamMetaParserHelper MetaHelper(ParserHelper.Stream,
348  ParserHelper.BlockInfo);
349  if (Error E = MetaHelper.parse())
350  return E;
351 
352  if (Error E = processCommonMeta(MetaHelper))
353  return E;
354 
355  switch (ContainerType) {
357  return processStandaloneMeta(MetaHelper);
359  return processSeparateRemarksFileMeta(MetaHelper);
361  return processSeparateRemarksMetaMeta(MetaHelper);
362  }
363  llvm_unreachable("Unknown BitstreamRemarkContainerType enum");
364 }
365 
366 Error BitstreamRemarkParser::processCommonMeta(
367  BitstreamMetaParserHelper &MetaHelper) {
369  ContainerVersion = *Version;
370  else
371  return createStringError(
372  std::make_error_code(std::errc::illegal_byte_sequence),
373  "Error while parsing BLOCK_META: missing container version.");
374 
375  if (Optional<uint8_t> Type = MetaHelper.ContainerType) {
376  // Always >= BitstreamRemarkContainerType::First since it's unsigned.
377  if (*Type > static_cast<uint8_t>(BitstreamRemarkContainerType::Last))
378  return createStringError(
379  std::make_error_code(std::errc::illegal_byte_sequence),
380  "Error while parsing BLOCK_META: invalid container type.");
381 
382  ContainerType = static_cast<BitstreamRemarkContainerType>(*Type);
383  } else
384  return createStringError(
385  std::make_error_code(std::errc::illegal_byte_sequence),
386  "Error while parsing BLOCK_META: missing container type.");
387 
388  return Error::success();
389 }
390 
392  Optional<StringRef> StrTabBuf) {
393  if (!StrTabBuf)
394  return createStringError(
395  std::make_error_code(std::errc::illegal_byte_sequence),
396  "Error while parsing BLOCK_META: missing string table.");
397  // Parse and assign the string table.
398  P.StrTab.emplace(*StrTabBuf);
399  return Error::success();
400 }
401 
403  Optional<uint64_t> RemarkVersion) {
404  if (!RemarkVersion)
405  return createStringError(
406  std::make_error_code(std::errc::illegal_byte_sequence),
407  "Error while parsing BLOCK_META: missing remark version.");
408  P.RemarkVersion = *RemarkVersion;
409  return Error::success();
410 }
411 
412 Error BitstreamRemarkParser::processExternalFilePath(
413  Optional<StringRef> ExternalFilePath) {
414  if (!ExternalFilePath)
415  return createStringError(
416  std::make_error_code(std::errc::illegal_byte_sequence),
417  "Error while parsing BLOCK_META: missing external file path.");
418 
419  SmallString<80> FullPath(ExternalFilePrependPath);
420  sys::path::append(FullPath, *ExternalFilePath);
421 
422  // External file: open the external file, parse it, check if its metadata
423  // matches the one from the separate metadata, then replace the current parser
424  // with the one parsing the remarks.
426  MemoryBuffer::getFile(FullPath);
427  if (std::error_code EC = BufferOrErr.getError())
428  return createFileError(FullPath, EC);
429  TmpRemarkBuffer = std::move(*BufferOrErr);
430 
431  // Create a separate parser used for parsing the separate file.
432  ParserHelper = BitstreamParserHelper(TmpRemarkBuffer->getBuffer());
433  // Advance and check until we can parse the meta block.
434  if (Error E = advanceToMetaBlock(ParserHelper))
435  return E;
436  // Parse the meta from the separate file.
437  // Note: here we overwrite the BlockInfo with the one from the file. This will
438  // be used to parse the rest of the file.
439  BitstreamMetaParserHelper SeparateMetaHelper(ParserHelper.Stream,
440  ParserHelper.BlockInfo);
441  if (Error E = SeparateMetaHelper.parse())
442  return E;
443 
444  uint64_t PreviousContainerVersion = ContainerVersion;
445  if (Error E = processCommonMeta(SeparateMetaHelper))
446  return E;
447 
449  return createStringError(
450  std::make_error_code(std::errc::illegal_byte_sequence),
451  "Error while parsing external file's BLOCK_META: wrong container "
452  "type.");
453 
454  if (PreviousContainerVersion != ContainerVersion)
455  return createStringError(
456  std::make_error_code(std::errc::illegal_byte_sequence),
457  "Error while parsing external file's BLOCK_META: mismatching versions: "
458  "original meta: %lu, external file meta: %lu.",
459  PreviousContainerVersion, ContainerVersion);
460 
461  // Process the meta from the separate file.
462  return processSeparateRemarksFileMeta(SeparateMetaHelper);
463 }
464 
465 Error BitstreamRemarkParser::processStandaloneMeta(
466  BitstreamMetaParserHelper &Helper) {
467  if (Error E = processStrTab(*this, Helper.StrTabBuf))
468  return E;
469  return processRemarkVersion(*this, Helper.RemarkVersion);
470 }
471 
472 Error BitstreamRemarkParser::processSeparateRemarksFileMeta(
473  BitstreamMetaParserHelper &Helper) {
474  return processRemarkVersion(*this, Helper.RemarkVersion);
475 }
476 
477 Error BitstreamRemarkParser::processSeparateRemarksMetaMeta(
478  BitstreamMetaParserHelper &Helper) {
479  if (Error E = processStrTab(*this, Helper.StrTabBuf))
480  return E;
481  return processExternalFilePath(Helper.ExternalFilePath);
482 }
483 
485  BitstreamRemarkParserHelper RemarkHelper(ParserHelper.Stream);
486  if (Error E = RemarkHelper.parse())
487  return std::move(E);
488 
489  return processRemark(RemarkHelper);
490 }
491 
493 BitstreamRemarkParser::processRemark(BitstreamRemarkParserHelper &Helper) {
494  std::unique_ptr<Remark> Result = std::make_unique<Remark>();
495  Remark &R = *Result;
496 
497  if (StrTab == None)
498  return createStringError(
499  std::make_error_code(std::errc::invalid_argument),
500  "Error while parsing BLOCK_REMARK: missing string table.");
501 
502  if (!Helper.Type)
503  return createStringError(
504  std::make_error_code(std::errc::illegal_byte_sequence),
505  "Error while parsing BLOCK_REMARK: missing remark type.");
506 
507  // Always >= Type::First since it's unsigned.
508  if (*Helper.Type > static_cast<uint8_t>(Type::Last))
509  return createStringError(
510  std::make_error_code(std::errc::illegal_byte_sequence),
511  "Error while parsing BLOCK_REMARK: unknown remark type.");
512 
513  R.RemarkType = static_cast<Type>(*Helper.Type);
514 
515  if (!Helper.RemarkNameIdx)
516  return createStringError(
517  std::make_error_code(std::errc::illegal_byte_sequence),
518  "Error while parsing BLOCK_REMARK: missing remark name.");
519 
520  if (Expected<StringRef> RemarkName = (*StrTab)[*Helper.RemarkNameIdx])
521  R.RemarkName = *RemarkName;
522  else
523  return RemarkName.takeError();
524 
525  if (!Helper.PassNameIdx)
526  return createStringError(
527  std::make_error_code(std::errc::illegal_byte_sequence),
528  "Error while parsing BLOCK_REMARK: missing remark pass.");
529 
530  if (Expected<StringRef> PassName = (*StrTab)[*Helper.PassNameIdx])
531  R.PassName = *PassName;
532  else
533  return PassName.takeError();
534 
535  if (!Helper.FunctionNameIdx)
536  return createStringError(
537  std::make_error_code(std::errc::illegal_byte_sequence),
538  "Error while parsing BLOCK_REMARK: missing remark function name.");
539  if (Expected<StringRef> FunctionName = (*StrTab)[*Helper.FunctionNameIdx])
540  R.FunctionName = *FunctionName;
541  else
542  return FunctionName.takeError();
543 
544  if (Helper.SourceFileNameIdx && Helper.SourceLine && Helper.SourceColumn) {
545  Expected<StringRef> SourceFileName = (*StrTab)[*Helper.SourceFileNameIdx];
546  if (!SourceFileName)
547  return SourceFileName.takeError();
548  R.Loc.emplace();
549  R.Loc->SourceFilePath = *SourceFileName;
550  R.Loc->SourceLine = *Helper.SourceLine;
551  R.Loc->SourceColumn = *Helper.SourceColumn;
552  }
553 
554  if (Helper.Hotness)
555  R.Hotness = *Helper.Hotness;
556 
557  if (!Helper.Args)
558  return std::move(Result);
559 
560  for (const BitstreamRemarkParserHelper::Argument &Arg : *Helper.Args) {
561  if (!Arg.KeyIdx)
562  return createStringError(
563  std::make_error_code(std::errc::illegal_byte_sequence),
564  "Error while parsing BLOCK_REMARK: missing key in remark argument.");
565  if (!Arg.ValueIdx)
566  return createStringError(
567  std::make_error_code(std::errc::illegal_byte_sequence),
568  "Error while parsing BLOCK_REMARK: missing value in remark "
569  "argument.");
570 
571  // We have at least a key and a value, create an entry.
572  R.Args.emplace_back();
573 
574  if (Expected<StringRef> Key = (*StrTab)[*Arg.KeyIdx])
575  R.Args.back().Key = *Key;
576  else
577  return Key.takeError();
578 
579  if (Expected<StringRef> Value = (*StrTab)[*Arg.ValueIdx])
580  R.Args.back().Val = *Value;
581  else
582  return Value.takeError();
583 
584  if (Arg.SourceFileNameIdx && Arg.SourceLine && Arg.SourceColumn) {
585  if (Expected<StringRef> SourceFileName =
586  (*StrTab)[*Arg.SourceFileNameIdx]) {
587  R.Args.back().Loc.emplace();
588  R.Args.back().Loc->SourceFilePath = *SourceFileName;
589  R.Args.back().Loc->SourceLine = *Arg.SourceLine;
590  R.Args.back().Loc->SourceColumn = *Arg.SourceColumn;
591  } else
592  return SourceFileName.takeError();
593  }
594  }
595 
596  return std::move(Result);
597 }
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)
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:455
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
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:25
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")
This represents a position within a bitcode file, implemented on top of a SimpleBitstreamCursor.
Expected< std::unique_ptr< BitstreamRemarkParser > > createBitstreamParserFromMeta(StringRef Buf, Optional< ParsedStringTable > StrTab=None, Optional< StringRef > ExternalFilePrependPath=None)
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
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition: Error.h:1265
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:1197