LLVM: lib/Remarks/BitstreamRemarkParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
17#include
18
19using namespace llvm;
21
22namespace {
23
24template <typename... Ts> Error error(char const *Fmt, const Ts &...Vals) {
25 std::string Buffer;
27 OS << formatv(Fmt, Vals...);
29 std::move(Buffer),
30 std::make_error_code(std::errc::illegal_byte_sequence));
31}
32
33}
34
36 return error("Unknown record entry ({}).", AbbrevID);
37}
38
40 return error("Unexpected record entry ({}).", RecordName);
41}
42
44 return error("Malformed record entry ({}).", RecordName);
45}
46
48 return error("Unexpected subblock ({}).", Code);
49}
50
54 return Next.takeError();
55 switch (Next->Kind) {
57 return Next->ID;
60 return error("Expected subblock, but got unexpected record.");
62 return error("Expected subblock, but got unexpected end of bitstream.");
63 }
65}
66
69 if (!MaybeBlockID)
70 return MaybeBlockID.takeError();
71 if (*MaybeBlockID != BlockID)
72 return error("Expected {} block, but got unexpected block ({}).", BlockName,
73 *MaybeBlockID);
75}
76
82
84
85
89 if (!RecordID)
91
92 switch (*RecordID) {
94 if (Record.size() != 2)
97
98
100 return ::error(
101 "Unsupported remark container version (expected: {}, read: {}). "
102 "Please upgrade/downgrade your toolchain to read this container.",
104 }
105 break;
106 }
108 if (Record.size() != 1)
111
112
114 return ::error(
115 "Unsupported remark version in container (expected: {}, read: {}). "
116 "Please upgrade/downgrade your toolchain to read this container.",
118 }
119 break;
120 }
122 if (Record.size() != 0)
125 break;
126 }
128 if (Record.size() != 0)
131 break;
132 }
133 default:
135 }
137}
138
143 if (!MaybeRecordID)
144 return MaybeRecordID.takeError();
147}
148
152 if (Record.size() != 4)
158 break;
159 }
161 if (Record.size() != 3)
164 break;
165 }
167 if (Record.size() != 1)
170 break;
171 }
173 if (Record.size() != 5)
177 break;
178 }
180 if (Record.size() != 2)
183 break;
184 }
185 default:
187 }
189}
190
192 Type.reset();
197 Loc.reset();
198 Args.clear();
199
201}
202
204 std::array<char, 4> Result;
205 for (unsigned I = 0; I < 4; ++I)
207 Result[I] = *R;
208 else
209 return R.takeError();
210
213 return error("Unknown magic number: expecting {}, got {}.",
216}
217
221 return Next.takeError();
225 "Error while parsing BLOCKINFO_BLOCK: expecting [ENTER_SUBBLOCK, "
226 "BLOCKINFO_BLOCK, ...].");
227
229 Stream.ReadBlockInfoBlock();
230 if (!MaybeBlockInfo)
231 return MaybeBlockInfo.takeError();
232
233 if (!*MaybeBlockInfo)
234 return error("Missing BLOCKINFO_BLOCK.");
235
237
240}
241
244 return E;
246 return E;
247
248
250 return E;
252 return E;
253
254
255 while (.AtEndOfStream()) {
257 if (!MaybeBlockID)
258 return MaybeBlockID.takeError();
260 break;
262 return error("Unexpected block between meta blocks.");
263
267 return E;
268 }
269
270
271 if (Stream.AtEndOfStream())
273
274
276 return E;
278}
279
283 } else {
285 if (!MaybeBlockID)
286 return MaybeBlockID.takeError();
289 }
291}
292
295 StringRef Buf, std::optional ExternalFilePrependPath) {
296 auto Parser = std::make_unique(Buf);
297
298 if (ExternalFilePrependPath)
299 Parser->ExternalFilePrependPath = std::string(*ExternalFilePrependPath);
300
301 return std::move(Parser);
302}
303
306
309
312
314 return std::move(E);
316
317
320 "Container is non-empty, but does not contain any remarks blocks.");
321
324 return std::move(E);
326 }
327
329 return std::move(E);
330 return processRemark();
331}
332
335 return E;
336 if (Error E = processCommonMeta())
337 return E;
338
341 return processExternalFilePath();
343 return processFileContainerMeta();
344 }
345 llvm_unreachable("Unknown BitstreamRemarkContainerType enum");
346}
347
348Error BitstreamRemarkParser::processCommonMeta() {
350 if (!Helper.Container)
351 return Helper.error("Missing container info.");
352 auto &Container = *Helper.Container;
354
356 return Helper.error("Invalid container type.");
359}
360
361Error BitstreamRemarkParser::processFileContainerMeta() {
362 if (Error E = processRemarkVersion())
363 return E;
364 if (Error E = processStrTab())
365 return E;
367}
368
369Error BitstreamRemarkParser::processStrTab() {
371 if (!Helper.StrTabBuf)
372 return Helper.error("Missing string table.");
373
374 StrTab.emplace(*Helper.StrTabBuf);
376}
377
378Error BitstreamRemarkParser::processRemarkVersion() {
380 if (!Helper.RemarkVersion)
381 return Helper.error("Missing remark version.");
384}
385
386Error BitstreamRemarkParser::processExternalFilePath() {
388 if (!Helper.ExternalFilePath)
389 return Helper.error("Missing external file path.");
390
393
394
395
396
397 ErrorOr<std::unique_ptr> BufferOrErr =
399 if (std::error_code EC = BufferOrErr.getError())
401
403
404
407
408
411 return E;
412
415 "Wrong container type in external file.");
416
418}
419
420Expected<std::unique_ptr> BitstreamRemarkParser::processRemark() {
422 std::unique_ptr Result = std::make_unique();
424
426 return Helper.error("Missing string table.");
427
428 if (!Helper.Type)
429 return Helper.error("Missing remark type.");
430
431
432 if (*Helper.Type > static_cast<uint8_t>(Type::Last))
433 return Helper.error("Unknown remark type.");
434
435 R.RemarkType = static_cast<Type>(*Helper.Type);
436
437 if (!Helper.RemarkNameIdx)
438 return Helper.error("Missing remark name.");
439
440 if (Expected RemarkName = (*StrTab)[*Helper.RemarkNameIdx])
441 R.RemarkName = *RemarkName;
442 else
443 return RemarkName.takeError();
444
445 if (!Helper.PassNameIdx)
446 return Helper.error("Missing remark pass.");
447
448 if (Expected PassName = (*StrTab)[*Helper.PassNameIdx])
450 else
452
453 if (!Helper.FunctionNameIdx)
454 return Helper.error("Missing remark function name.");
455
456 if (Expected FunctionName = (*StrTab)[*Helper.FunctionNameIdx])
457 R.FunctionName = *FunctionName;
458 else
459 return FunctionName.takeError();
460
461 if (Helper.Loc) {
462 Expected SourceFileName =
463 (*StrTab)[Helper.Loc->SourceFileNameIdx];
464 if (!SourceFileName)
465 return SourceFileName.takeError();
466 R.Loc.emplace();
467 R.Loc->SourceFilePath = *SourceFileName;
468 R.Loc->SourceLine = Helper.Loc->SourceLine;
469 R.Loc->SourceColumn = Helper.Loc->SourceColumn;
470 }
471
472 if (Helper.Hotness)
473 R.Hotness = *Helper.Hotness;
474
475 for (const BitstreamRemarkParserHelper::Argument &Arg : Helper.Args) {
477 return Helper.error("Missing key in remark argument.");
479 return Helper.error("Missing value in remark argument.");
480
481
482 auto &RArg = R.Args.emplace_back();
483
485 RArg.Key = *Key;
486 else
487 return Key.takeError();
488
490 RArg.Val = *Value;
491 else
492 return Value.takeError();
493
494 if (Arg.Loc) {
495 if (Expected SourceFileName =
496 (*StrTab)[Arg.Loc->SourceFileNameIdx]) {
497 RArg.Loc.emplace();
498 RArg.Loc->SourceFilePath = *SourceFileName;
499 RArg.Loc->SourceLine = Arg.Loc->SourceLine;
500 RArg.Loc->SourceColumn = Arg.Loc->SourceColumn;
501 } else
502 return SourceFileName.takeError();
503 }
504 }
505
506 return std::move(Result);
507}
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static const char PassName[]
This represents a position within a bitcode file, implemented on top of a SimpleBitstreamCursor.
Expected< BitstreamEntry > advance(unsigned Flags=0)
Advance the current bitstream, returning the next entry in the stream.
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,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BLOCKINFO_BLOCK_ID
BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...
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.
FunctionAddr VTableAddr Value
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
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.
FunctionAddr VTableAddr Next