LLVM 23.0.0git
LVReader.cpp
Go to the documentation of this file.
1//===-- LVReader.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 implements the LVReader class.
10//
11//===----------------------------------------------------------------------===//
12
18#include <tuple>
19
20using namespace llvm;
21using namespace llvm::logicalview;
22
23#define DEBUG_TYPE "Reader"
24
25// Traverse all the logical elements and print their basic information.
27 std::function<void(LVScope * Parent)> TraverseScope = [&](LVScope *Parent) {
28 // Print the elements.
29 auto Print = [&](const auto &Set) {
30 if (Set)
31 for (const auto &Entry : *Set)
32 Entry->printCommon(dbgs());
33 };
34
35 for (LVElement *Element : Parent->getChildren())
36 Element->print(dbgs());
37 Print(Parent->getLines());
38 Print(Parent->getRanges());
39 if (const LVScopes *Scopes = Parent->getScopes())
40 for (LVScope *Scope : *Scopes)
41 TraverseScope(Scope);
42 };
43
44 // Start traversing the scopes root.
45 dbgs() << "\n** Collected logical elements **\n";
46 Root->print(dbgs());
47 TraverseScope(Root);
48}
49
50// Detect elements that are inserted more than once at different scopes,
51// causing a crash on the reader destruction, as the element is already
52// deleted from other scope. Helper for CodeView reader.
54 using LVDuplicateEntry = std::tuple<LVElement *, LVScope *, LVScope *>;
55 using LVDuplicate = std::vector<LVDuplicateEntry>;
56 LVDuplicate Duplicate;
57
58 using LVIntegrity = std::map<LVElement *, LVScope *>;
59 LVIntegrity Integrity;
60
61 // Add the given element to the integrity map.
62 auto AddElement = [&](LVElement *Element, LVScope *Scope) {
63 LVIntegrity::iterator Iter = Integrity.find(Element);
64 if (Iter == Integrity.end())
65 Integrity.emplace(Element, Scope);
66 else
67 // We found a duplicate.
68 Duplicate.emplace_back(Element, Scope, Iter->second);
69 };
70
71 // Recursively add all the elements in the scope.
72 std::function<void(LVScope * Parent)> TraverseScope = [&](LVScope *Parent) {
73 auto Traverse = [&](const auto *Set) {
74 if (Set)
75 for (const auto &Entry : *Set)
76 AddElement(Entry, Parent);
77 };
78 if (const LVScopes *Scopes = Parent->getScopes()) {
79 for (LVScope *Scope : *Scopes) {
80 AddElement(Scope, Parent);
81 TraverseScope(Scope);
82 }
83 }
84 Traverse(Parent->getSymbols());
85 Traverse(Parent->getTypes());
86 Traverse(Parent->getLines());
87 };
88
89 // Print collected elements.
91
92 // Start traversing the scopes root and print any duplicates.
93 TraverseScope(Root);
94 bool PassIntegrity = true;
95 if (Duplicate.size()) {
96 llvm::stable_sort(Duplicate, [](const auto &l, const auto &r) {
97 return std::get<0>(l)->getID() < std::get<0>(r)->getID();
98 });
99
100 auto PrintIndex = [](unsigned Index) {
101 if (Index)
102 dbgs() << formatv("{0,8}: ", Index);
103 else
104 dbgs() << formatv("{0,8}: ", ' ');
105 };
106 auto PrintElement = [&](LVElement *Element, unsigned Index = 0) {
107 PrintIndex(Index);
108 std::string ElementName(Element->getName());
109 dbgs() << formatv("{0,15} ID={1:x8} '{2}'\n", Element->kind(),
110 Element->getID(), ElementName);
111 };
112
113 std::string RootName(Root->getName());
114 dbgs() << formatv("{0}\n", fmt_repeat('=', 72));
115 dbgs() << formatv("Root: '{0}'\nDuplicated elements: {1}\n", RootName,
116 Duplicate.size());
117 dbgs() << formatv("{0}\n", fmt_repeat('=', 72));
118
119 unsigned Index = 0;
120 for (const LVDuplicateEntry &Entry : Duplicate) {
121 LVElement *Element;
122 LVScope *First;
123 LVScope *Second;
124 std::tie(Element, First, Second) = Entry;
125 dbgs() << formatv("\n{0}\n", fmt_repeat('-', 72));
126 PrintElement(Element, ++Index);
127 PrintElement(First);
128 PrintElement(Second);
129 dbgs() << formatv("{0}\n", fmt_repeat('-', 72));
130 }
131 PassIntegrity = false;
132 }
133 return PassIntegrity;
134}
135
136//===----------------------------------------------------------------------===//
137// Class to represent a split context.
138//===----------------------------------------------------------------------===//
140 // The 'location' will represent the root directory for the output created
141 // by the context. It will contain the different CUs files, that will be
142 // extracted from a single ELF.
143 Location = std::string(Where);
144
145 // Add a trailing slash, if there is none.
146 size_t Pos = Location.find_last_of('/');
147 if (Location.length() != Pos + 1)
148 Location.append("/");
149
150 // Make sure the new directory exists, creating it if necessary.
151 if (std::error_code EC = llvm::sys::fs::create_directories(Location))
152 return createStringError(EC, "Error: could not create directory %s",
153 Location.c_str());
154
155 return Error::success();
156}
157
158std::error_code LVSplitContext::open(std::string ContextName,
159 std::string Extension, raw_ostream &OS) {
160 assert(OutputFile == nullptr && "OutputFile already set.");
161
162 // Transforms '/', '\', '.', ':' into '_'.
163 std::string Name(flattenedFilePath(ContextName));
164 Name.append(Extension);
165 // Add the split context location folder name.
166 if (!Location.empty())
167 Name.insert(0, Location);
168
169 std::error_code EC;
170 OutputFile = std::make_unique<ToolOutputFile>(Name, EC, sys::fs::OF_None);
171 if (EC)
172 return EC;
173
174 // Don't remove output file.
175 OutputFile->keep();
176 return std::error_code();
177}
178
179static LVReader *CurrentReader = nullptr;
181 if (CurrentReader)
182 return *CurrentReader;
183 outs() << "Invalid instance reader.\n";
184 llvm_unreachable("Invalid instance reader.");
185}
187
188Error LVReader::createSplitFolder() {
189 if (OutputSplit) {
190 // If the '--output=split' was specified, but no '--split-folder'
191 // option, use the input file as base for the split location.
192 if (options().getOutputFolder().empty())
193 options().setOutputFolder(getFilename().str() + "_cus");
194
195 SmallString<128> SplitFolder;
196 SplitFolder = options().getOutputFolder();
197 sys::fs::make_absolute(SplitFolder);
198
199 // Return error if unable to create a split context location.
200 if (Error Err = SplitContext.createSplitFolder(SplitFolder))
201 return Err;
202
203 OS << "\nSplit View Location: '" << SplitContext.getLocation() << "'\n";
204 }
205
206 return Error::success();
207}
208
209// Get the filename for given object.
210StringRef LVReader::getFilename(LVObject *Object, size_t Index) const {
211 // TODO: The current CodeView Reader implementation does not have support
212 // for multiple compile units. Until we have a proper offset calculation,
213 // check only in the current compile unit.
214 if (CompileUnits.size()) {
215 // Get Compile Unit for the given object.
216 LVCompileUnits::const_iterator Iter =
217 std::prev(CompileUnits.lower_bound(Object->getOffset()));
218 if (Iter != CompileUnits.end())
219 return Iter->second->getFilename(Index);
220 }
221
222 return CompileUnit ? CompileUnit->getFilename(Index) : StringRef();
223}
224
226 LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
227 ScopesWithRanges->addEntry(Scope);
228}
229
231 LVAddress LowerAddress, LVAddress UpperAddress) {
232 LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
233 ScopesWithRanges->addEntry(Scope, LowerAddress, UpperAddress);
234}
235
237 // Check if we already have a mapping for this section index.
238 LVSectionRanges::iterator IterSection = SectionRanges.find(SectionIndex);
239 if (IterSection == SectionRanges.end())
240 IterSection =
241 SectionRanges.emplace(SectionIndex, std::make_unique<LVRange>()).first;
242 LVRange *Range = IterSection->second.get();
243 assert(Range && "Range is null.");
244 return Range;
245}
246
248 CurrentScope = nullptr;
249 CurrentSymbol = nullptr;
250 CurrentType = nullptr;
251 CurrentRanges.clear();
252
254 { dbgs() << "\n[createElement] " << dwarf::TagString(Tag) << "\n"; });
255
256 if (!options().getPrintSymbols()) {
257 switch (Tag) {
258 // As the command line options did not specify a request to print
259 // logical symbols (--print=symbols or --print=all or --print=elements),
260 // skip its creation.
261 case dwarf::DW_TAG_formal_parameter:
262 case dwarf::DW_TAG_unspecified_parameters:
263 case dwarf::DW_TAG_member:
264 case dwarf::DW_TAG_variable:
265 case dwarf::DW_TAG_inheritance:
266 case dwarf::DW_TAG_constant:
267 case dwarf::DW_TAG_call_site_parameter:
268 case dwarf::DW_TAG_GNU_call_site_parameter:
269 return nullptr;
270 default:
271 break;
272 }
273 }
274
275 switch (Tag) {
276 // Types.
277 case dwarf::DW_TAG_base_type:
278 CurrentType = createType();
279 CurrentType->setIsBase();
280 if (options().getAttributeBase())
281 CurrentType->setIncludeInPrint();
282 return CurrentType;
283 case dwarf::DW_TAG_const_type:
284 CurrentType = createType();
285 CurrentType->setIsConst();
286 CurrentType->setName("const");
287 return CurrentType;
288 case dwarf::DW_TAG_enumerator:
289 CurrentType = createTypeEnumerator();
290 return CurrentType;
291 case dwarf::DW_TAG_imported_declaration:
292 CurrentType = createTypeImport();
293 CurrentType->setIsImportDeclaration();
294 return CurrentType;
295 case dwarf::DW_TAG_imported_module:
296 CurrentType = createTypeImport();
297 CurrentType->setIsImportModule();
298 return CurrentType;
299 case dwarf::DW_TAG_pointer_type:
300 CurrentType = createType();
301 CurrentType->setIsPointer();
302 CurrentType->setName("*");
303 return CurrentType;
304 case dwarf::DW_TAG_ptr_to_member_type:
305 CurrentType = createType();
306 CurrentType->setIsPointerMember();
307 CurrentType->setName("*");
308 return CurrentType;
309 case dwarf::DW_TAG_reference_type:
310 CurrentType = createType();
311 CurrentType->setIsReference();
312 CurrentType->setName("&");
313 return CurrentType;
314 case dwarf::DW_TAG_restrict_type:
315 CurrentType = createType();
316 CurrentType->setIsRestrict();
317 CurrentType->setName("restrict");
318 return CurrentType;
319 case dwarf::DW_TAG_rvalue_reference_type:
320 CurrentType = createType();
321 CurrentType->setIsRvalueReference();
322 CurrentType->setName("&&");
323 return CurrentType;
324 case dwarf::DW_TAG_subrange_type:
325 CurrentType = createTypeSubrange();
326 return CurrentType;
327 case dwarf::DW_TAG_template_value_parameter:
328 CurrentType = createTypeParam();
329 CurrentType->setIsTemplateValueParam();
330 return CurrentType;
331 case dwarf::DW_TAG_template_type_parameter:
332 CurrentType = createTypeParam();
333 CurrentType->setIsTemplateTypeParam();
334 return CurrentType;
335 case dwarf::DW_TAG_GNU_template_template_param:
336 CurrentType = createTypeParam();
337 CurrentType->setIsTemplateTemplateParam();
338 return CurrentType;
339 case dwarf::DW_TAG_typedef:
340 CurrentType = createTypeDefinition();
341 return CurrentType;
342 case dwarf::DW_TAG_unspecified_type:
343 CurrentType = createType();
344 CurrentType->setIsUnspecified();
345 return CurrentType;
346 case dwarf::DW_TAG_volatile_type:
347 CurrentType = createType();
348 CurrentType->setIsVolatile();
349 CurrentType->setName("volatile");
350 return CurrentType;
351
352 // Symbols.
353 case dwarf::DW_TAG_formal_parameter:
354 CurrentSymbol = createSymbol();
355 CurrentSymbol->setIsParameter();
356 return CurrentSymbol;
357 case dwarf::DW_TAG_unspecified_parameters:
358 CurrentSymbol = createSymbol();
359 CurrentSymbol->setIsUnspecified();
360 CurrentSymbol->setName("...");
361 return CurrentSymbol;
362 case dwarf::DW_TAG_member:
363 CurrentSymbol = createSymbol();
364 CurrentSymbol->setIsMember();
365 return CurrentSymbol;
366 case dwarf::DW_TAG_variable:
367 CurrentSymbol = createSymbol();
368 CurrentSymbol->setIsVariable();
369 return CurrentSymbol;
370 case dwarf::DW_TAG_inheritance:
371 CurrentSymbol = createSymbol();
372 CurrentSymbol->setIsInheritance();
373 return CurrentSymbol;
374 case dwarf::DW_TAG_call_site_parameter:
375 case dwarf::DW_TAG_GNU_call_site_parameter:
376 CurrentSymbol = createSymbol();
377 CurrentSymbol->setIsCallSiteParameter();
378 return CurrentSymbol;
379 case dwarf::DW_TAG_constant:
380 CurrentSymbol = createSymbol();
381 CurrentSymbol->setIsConstant();
382 return CurrentSymbol;
383
384 // Scopes.
385 case dwarf::DW_TAG_catch_block:
386 CurrentScope = createScope();
387 CurrentScope->setIsCatchBlock();
388 return CurrentScope;
389 case dwarf::DW_TAG_lexical_block:
390 CurrentScope = createScope();
391 CurrentScope->setIsLexicalBlock();
392 return CurrentScope;
393 case dwarf::DW_TAG_try_block:
394 CurrentScope = createScope();
395 CurrentScope->setIsTryBlock();
396 return CurrentScope;
397 case dwarf::DW_TAG_compile_unit:
398 case dwarf::DW_TAG_skeleton_unit:
399 CurrentScope = createScopeCompileUnit();
401 return CurrentScope;
402 case dwarf::DW_TAG_inlined_subroutine:
403 CurrentScope = createScopeFunctionInlined();
404 return CurrentScope;
405 case dwarf::DW_TAG_namespace:
406 CurrentScope = createScopeNamespace();
407 return CurrentScope;
408 case dwarf::DW_TAG_template_alias:
409 CurrentScope = createScopeAlias();
410 return CurrentScope;
411 case dwarf::DW_TAG_array_type:
412 CurrentScope = createScopeArray();
413 return CurrentScope;
414 case dwarf::DW_TAG_call_site:
415 case dwarf::DW_TAG_GNU_call_site:
416 CurrentScope = createScopeFunction();
417 CurrentScope->setIsCallSite();
418 return CurrentScope;
419 case dwarf::DW_TAG_entry_point:
420 CurrentScope = createScopeFunction();
421 CurrentScope->setIsEntryPoint();
422 return CurrentScope;
423 case dwarf::DW_TAG_subprogram:
424 CurrentScope = createScopeFunction();
425 CurrentScope->setIsSubprogram();
426 return CurrentScope;
427 case dwarf::DW_TAG_subroutine_type:
428 CurrentScope = createScopeFunctionType();
429 return CurrentScope;
430 case dwarf::DW_TAG_label:
431 CurrentScope = createScopeFunction();
432 CurrentScope->setIsLabel();
433 return CurrentScope;
434 case dwarf::DW_TAG_class_type:
435 CurrentScope = createScopeAggregate();
436 CurrentScope->setIsClass();
437 return CurrentScope;
438 case dwarf::DW_TAG_structure_type:
439 CurrentScope = createScopeAggregate();
440 CurrentScope->setIsStructure();
441 return CurrentScope;
442 case dwarf::DW_TAG_union_type:
443 CurrentScope = createScopeAggregate();
444 CurrentScope->setIsUnion();
445 return CurrentScope;
446 case dwarf::DW_TAG_enumeration_type:
447 CurrentScope = createScopeEnumeration();
448 return CurrentScope;
449 case dwarf::DW_TAG_GNU_formal_parameter_pack:
450 CurrentScope = createScopeFormalPack();
451 return CurrentScope;
452 case dwarf::DW_TAG_GNU_template_parameter_pack:
453 CurrentScope = createScopeTemplatePack();
454 return CurrentScope;
455 case dwarf::DW_TAG_module:
456 CurrentScope = createScopeModule();
457 return CurrentScope;
458 default:
459 // Collect TAGs not implemented.
460 if (options().getInternalTag() && Tag)
461 CompileUnit->addDebugTag(Tag, CurrentOffset);
462 break;
463 }
464
465 LLVM_DEBUG({
466 dbgs() << "DWARF Tag not implemented: " << dwarf::TagString(Tag) << "\n";
467 });
468
469 return nullptr;
470}
471
472// The Reader is the module that creates the logical view using the debug
473// information contained in the binary file specified in the command line.
474// This is the main entry point for the Reader and performs the following
475// steps:
476// - Process any patterns collected from the '--select' options.
477// - For each compile unit in the debug information:
478// * Create the logical elements (scopes, symbols, types, lines).
479// * Collect debug ranges and debug locations.
480// * Move the collected logical lines to their associated scopes.
481// - Once all the compile units have been processed, traverse the scopes
482// tree in order to:
483// * Calculate symbol coverage.
484// * Detect invalid ranges and locations.
485// * "resolve" the logical elements. During this pass, the names and
486// file information are updated, to reflect any dependency with other
487// logical elements.
489 // Set current Reader instance.
490 setInstance(this);
491
492 // Before any scopes creation, process any pattern specified by the
493 // --select and --select-offsets options.
496
497 // Add any specific element printing requests based on the element kind.
498 patterns().addRequest(options().Select.Elements);
499 patterns().addRequest(options().Select.Lines);
500 patterns().addRequest(options().Select.Scopes);
501 patterns().addRequest(options().Select.Symbols);
502 patterns().addRequest(options().Select.Types);
503
504 // Once we have processed the requests for any particular kind of elements,
505 // we need to update the report options, in order to have a default value.
507
508 // Delegate the scope tree creation to the specific reader.
509 if (Error Err = createScopes())
510 return Err;
511
512 if (options().getInternalIntegrity() && !checkIntegrityScopesTree(Root))
513 return llvm::make_error<StringError>("Duplicated elements in Scopes Tree",
515
516 // Calculate symbol coverage and detect invalid debug locations and ranges.
517 Root->processRangeInformation();
518
519 // As the elements can depend on elements from a different compile unit,
520 // information such as name and file/line source information needs to be
521 // updated.
522 Root->resolveElements();
523
524 sortScopes();
525 return Error::success();
526}
527
528// Default handler for a generic reader.
530 // Set current Reader instance.
531 setInstance(this);
532
533 // Check for any '--report' request.
534 if (options().getReportExecute()) {
535 // Requested details.
536 if (options().getReportList())
537 if (Error Err = printMatchedElements(/*UseMatchedElements=*/true))
538 return Err;
539 // Requested only children.
540 if (options().getReportChildren() && !options().getReportParents())
541 if (Error Err = printMatchedElements(/*UseMatchedElements=*/false))
542 return Err;
543 // Requested (parents) or (parents and children).
544 if (options().getReportParents() || options().getReportView())
545 if (Error Err = printScopes())
546 return Err;
547
548 return Error::success();
549 }
550
551 return printScopes();
552}
553
555 if (bool DoPrint =
556 (options().getPrintExecute() || options().getComparePrint())) {
557 if (Error Err = createSplitFolder())
558 return Err;
559
560 // Start printing from the root.
561 bool DoMatch = options().getSelectGenericPattern() ||
562 options().getSelectGenericKind() ||
563 options().getSelectOffsetPattern();
564 return Root->doPrint(OutputSplit, DoMatch, DoPrint, OS);
565 }
566
567 return Error::success();
568}
569
570Error LVReader::printMatchedElements(bool UseMatchedElements) {
571 if (Error Err = createSplitFolder())
572 return Err;
573
574 return Root->doPrintMatches(OutputSplit, OS, UseMatchedElements);
575}
576
578 OS << "LVReader\n";
579 LLVM_DEBUG(dbgs() << "PrintReader\n");
580}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
static LVReader * CurrentReader
Definition LVReader.cpp:179
#define LLVM_DEBUG(...)
Definition Debug.h:119
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
StringRef getName() const override
Definition LVElement.h:192
uint32_t getID() const
Definition LVObject.h:320
virtual const char * kind() const
Definition LVObject.h:277
LLVM_ABI void addGenericPatterns(StringSet<> &Patterns)
LLVM_ABI void updateReportOptions()
LLVM_ABI void addOffsetPatterns(const LVOffsetSet &Patterns)
void addEntry(LVScope *Scope, LVAddress LowerAddress, LVAddress UpperAddress)
Definition LVRange.cpp:53
The logical reader owns of all the logical elements created during the debug information parsing.
Definition LVReader.h:61
virtual void sortScopes()
Definition LVReader.h:194
LVRange * getSectionRanges(LVSectionIndex SectionIndex)
Definition LVReader.cpp:236
void print(raw_ostream &OS) const
Definition LVReader.cpp:577
std::vector< LVAddressRange > CurrentRanges
Definition LVReader.h:142
LVElement * createElement(dwarf::Tag Tag)
Definition LVReader.cpp:247
void printCollectedElements(LVScope *Root)
Definition LVReader.cpp:26
StringRef getFilename() const
Definition LVReader.h:266
static LVReader & getInstance()
Definition LVReader.cpp:180
LVScopeCompileUnit * CompileUnit
Definition LVReader.h:149
static void setInstance(LVReader *Reader)
Definition LVReader.cpp:186
void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope)
Definition LVReader.cpp:225
virtual Error printMatchedElements(bool UseMatchedElements)
Definition LVReader.cpp:570
bool checkIntegrityScopesTree(LVScope *Root)
Definition LVReader.cpp:53
virtual Error printScopes()
Definition LVReader.cpp:554
virtual Error createScopes()
Definition LVReader.h:167
const LVLines * getLines() const
Definition LVScope.h:208
const LVScopes * getScopes() const
Definition LVScope.h:210
LVElementsView getChildren() const
Definition LVScope.h:220
const LVSymbols * getSymbols() const
Definition LVScope.h:211
const LVTypes * getTypes() const
Definition LVScope.h:212
const LVLocations * getRanges() const
Definition LVScope.h:209
std::string getLocation() const
Definition LVReader.h:54
LLVM_ABI Error createSplitFolder(StringRef Where)
Definition LVReader.cpp:139
LLVM_ABI std::error_code open(std::string Name, std::string Extension, raw_ostream &OS)
Definition LVReader.cpp:158
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
LLVM_ABI StringRef TagString(unsigned Tag)
Definition Dwarf.cpp:21
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LVPatterns & patterns()
Definition LVOptions.h:645
SmallVector< LVScope *, 8 > LVScopes
Definition LVObject.h:80
LLVM_ABI std::string flattenedFilePath(StringRef Path)
Definition LVSupport.cpp:48
uint64_t LVSectionIndex
Definition LVObject.h:35
uint64_t LVAddress
Definition LVObject.h:36
LVOptions & options()
Definition LVOptions.h:448
LLVM_ABI std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
Definition Path.cpp:993
LLVM_ABI std::error_code make_absolute(SmallVectorImpl< char > &path)
Make path an absolute path.
Definition Path.cpp:979
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
Definition STLExtras.h:2116
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)