LLVM 24.0.0git
LibDriver.cpp
Go to the documentation of this file.
1//===- LibDriver.cpp - lib.exe-compatible driver --------------------------===//
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// Defines an interface to a lib.exe-compatible driver that also understands
10// bitcode files. Used by llvm-lib and lld-link /lib.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/StringSet.h"
21#include "llvm/Object/COFF.h"
24#include "llvm/Option/Arg.h"
25#include "llvm/Option/ArgList.h"
27#include "llvm/Option/Option.h"
29#include "llvm/Support/Path.h"
33#include <optional>
34
35using namespace llvm;
36using namespace llvm::object;
37
38namespace {
39
40enum {
41 OPT_INVALID = 0,
42#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
43#include "Options.inc"
44#undef OPTION
45};
46
47using namespace llvm::opt;
48#define OPTTABLE_CODE
49#include "Options.inc"
50
51class LibOptTable : public opt::OptTable {
52public:
53 LibOptTable() : opt::OptTable(optionTables(), true) {}
54};
55} // namespace
56
57static std::string getDefaultOutputPath(const NewArchiveMember &FirstMember) {
58 SmallString<128> Val = StringRef(FirstMember.Buf->getBufferIdentifier());
60 return std::string(Val);
61}
62
63static std::vector<StringRef> getSearchPaths(opt::InputArgList *Args,
64 StringSaver &Saver) {
65 std::vector<StringRef> Ret;
66 // Add current directory as first item of the search path.
67 Ret.push_back("");
68
69 // Add /libpath flags.
70 for (auto *Arg : Args->filtered(OPT_libpath))
71 Ret.push_back(Arg->getValue());
72
73 // Add $LIB.
74 std::optional<std::string> EnvOpt = sys::Process::GetEnv("LIB");
75 if (!EnvOpt)
76 return Ret;
77 StringRef Env = Saver.save(*EnvOpt);
78 while (!Env.empty()) {
79 StringRef Path;
80 std::tie(Path, Env) = Env.split(';');
81 Ret.push_back(Path);
82 }
83 return Ret;
84}
85
86// Opens a file. Path has to be resolved already. (used for def file)
87std::unique_ptr<MemoryBuffer> openFile(const Twine &Path) {
89 MemoryBuffer::getFile(Path, /*IsText=*/true);
90
91 if (std::error_code EC = MB.getError()) {
92 llvm::errs() << "cannot open file " << Path << ": " << EC.message() << "\n";
93 return nullptr;
94 }
95
96 return std::move(*MB);
97}
98
99static std::string findInputFile(StringRef File, ArrayRef<StringRef> Paths) {
100 for (StringRef Dir : Paths) {
101 SmallString<128> Path = Dir;
102 sys::path::append(Path, File);
103 if (sys::fs::exists(Path))
104 return std::string(Path);
105 }
106 return "";
107}
108
109static void fatalOpenError(llvm::Error E, Twine File) {
110 if (!E)
111 return;
112 handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
113 llvm::errs() << "error opening '" << File << "': " << EIB.message() << '\n';
114 exit(1);
115 });
116}
117
118static void doList(opt::InputArgList &Args) {
119 // lib.exe prints the contents of the first archive file.
120 std::unique_ptr<MemoryBuffer> B;
121 for (auto *Arg : Args.filtered(OPT_INPUT)) {
122 // Create or open the archive object.
124 Arg->getValue(), /*IsText=*/false, /*RequiresNullTerminator=*/false);
126
127 if (identify_magic(MaybeBuf.get()->getBuffer()) == file_magic::archive) {
128 B = std::move(MaybeBuf.get());
129 break;
130 }
131 }
132
133 // lib.exe doesn't print an error if no .lib files are passed.
134 if (!B)
135 return;
136
137 Error Err = Error::success();
138 object::Archive Archive(B->getMemBufferRef(), Err);
139 fatalOpenError(std::move(Err), B->getBufferIdentifier());
140
141 std::vector<StringRef> Names;
142 for (auto &C : Archive.children(Err)) {
143 Expected<StringRef> NameOrErr = C.getName();
144 fatalOpenError(NameOrErr.takeError(), B->getBufferIdentifier());
145 Names.push_back(NameOrErr.get());
146 }
147 for (auto Name : reverse(Names))
148 llvm::outs() << Name << '\n';
149 fatalOpenError(std::move(Err), B->getBufferIdentifier());
150}
151
153 std::error_code EC;
154 auto Obj = object::COFFObjectFile::create(MB);
155 if (!Obj)
156 return Obj.takeError();
157
158 uint16_t Machine = (*Obj)->getMachine();
164 "unknown machine: " + std::to_string(Machine));
165 }
166
167 return static_cast<COFF::MachineTypes>(Machine);
168}
169
172 if (!TripleStr)
173 return TripleStr.takeError();
174
175 Triple T(*TripleStr);
176 switch (T.getArch()) {
177 case Triple::x86:
179 case Triple::x86_64:
181 case Triple::arm:
182 case Triple::thumb:
184 case Triple::aarch64:
185 return T.isWindowsArm64EC() ? COFF::IMAGE_FILE_MACHINE_ARM64EC
187 case Triple::mipsel:
189 default:
191 "unknown arch in target triple: " + *TripleStr);
192 }
193}
194
195static bool machineMatches(COFF::MachineTypes LibMachine,
196 COFF::MachineTypes FileMachine) {
197 if (LibMachine == FileMachine)
198 return true;
199 // ARM64EC mode allows both pure ARM64, ARM64EC and X64 objects to be mixed in
200 // the archive.
201 switch (LibMachine) {
203 return FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64X;
206 return COFF::isAnyArm64(FileMachine) ||
207 FileMachine == COFF::IMAGE_FILE_MACHINE_AMD64;
208 default:
209 return false;
210 }
211}
212
213static void appendFile(std::vector<NewArchiveMember> &Members,
214 COFF::MachineTypes &LibMachine,
215 std::string &LibMachineSource, MemoryBufferRef MB) {
216 file_magic Magic = identify_magic(MB.getBuffer());
217
218 if (Magic != file_magic::coff_object && Magic != file_magic::bitcode &&
222 << ": not a COFF object, bitcode, archive, import library or "
223 "resource file\n";
224 exit(1);
225 }
226
227 // If a user attempts to add an archive to another archive, llvm-lib doesn't
228 // handle the first archive file as a single file. Instead, it extracts all
229 // members from the archive and add them to the second archive. This behavior
230 // is for compatibility with Microsoft's lib command.
231 if (Magic == file_magic::archive) {
232 Error Err = Error::success();
233 object::Archive Archive(MB, Err);
234 fatalOpenError(std::move(Err), MB.getBufferIdentifier());
235
236 for (auto &C : Archive.children(Err)) {
237 Expected<MemoryBufferRef> ChildMB = C.getMemoryBufferRef();
238 if (!ChildMB) {
239 handleAllErrors(ChildMB.takeError(), [&](const ErrorInfoBase &EIB) {
240 llvm::errs() << MB.getBufferIdentifier() << ": " << EIB.message()
241 << "\n";
242 });
243 exit(1);
244 }
245
246 appendFile(Members, LibMachine, LibMachineSource, *ChildMB);
247 }
248
249 fatalOpenError(std::move(Err), MB.getBufferIdentifier());
250 return;
251 }
252
253 // Check that all input files have the same machine type.
254 // Mixing normal objects and LTO bitcode files is fine as long as they
255 // have the same machine type.
256 // Doing this here duplicates the header parsing work that writeArchive()
257 // below does, but it's not a lot of work and it's a bit awkward to do
258 // in writeArchive() which needs to support many tools, can't assume the
259 // input is COFF, and doesn't have a good way to report errors.
260 if (Magic == file_magic::coff_object || Magic == file_magic::bitcode) {
261 Expected<COFF::MachineTypes> MaybeFileMachine =
264 if (!MaybeFileMachine) {
265 handleAllErrors(MaybeFileMachine.takeError(),
266 [&](const ErrorInfoBase &EIB) {
267 llvm::errs() << MB.getBufferIdentifier() << ": "
268 << EIB.message() << "\n";
269 });
270 exit(1);
271 }
272 COFF::MachineTypes FileMachine = *MaybeFileMachine;
273
274 // FIXME: Once lld-link rejects multiple resource .obj files:
275 // Call convertResToCOFF() on .res files and add the resulting
276 // COFF file to the .lib output instead of adding the .res file, and remove
277 // this check. See PR42180.
278 if (FileMachine != COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
279 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
280 if (FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64EC) {
281 llvm::errs() << MB.getBufferIdentifier() << ": file machine type "
282 << machineToStr(FileMachine)
283 << " conflicts with inferred library machine type,"
284 << " use /machine:arm64ec or /machine:arm64x\n";
285 exit(1);
286 }
287 LibMachine = FileMachine;
288 LibMachineSource =
289 (" (inferred from earlier file '" + MB.getBufferIdentifier() + "')")
290 .str();
291 } else if (!machineMatches(LibMachine, FileMachine)) {
292 llvm::errs() << MB.getBufferIdentifier() << ": file machine type "
293 << machineToStr(FileMachine)
294 << " conflicts with library machine type "
295 << machineToStr(LibMachine) << LibMachineSource << '\n';
296 exit(1);
297 }
298 }
299 }
300
301 Members.emplace_back(MB);
302}
303
306 StringSaver Saver(Alloc);
307
308 // Parse command line arguments.
309 SmallVector<const char *, 20> NewArgs(ArgsArr);
311 ArgsArr = NewArgs;
312
313 LibOptTable Table;
314 unsigned MissingIndex;
315 unsigned MissingCount;
316 opt::InputArgList Args =
317 Table.ParseArgs(ArgsArr.slice(1), MissingIndex, MissingCount);
318 if (MissingCount) {
319 llvm::errs() << "missing arg value for \""
320 << Args.getArgString(MissingIndex) << "\", expected "
321 << MissingCount
322 << (MissingCount == 1 ? " argument.\n" : " arguments.\n");
323 return 1;
324 }
325 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
326 llvm::errs() << "ignoring unknown argument: " << Arg->getAsString(Args)
327 << "\n";
328
329 // Handle /help
330 if (Args.hasArg(OPT_help)) {
331 Table.printHelp(outs(), "llvm-lib [options] file...", "LLVM Lib");
332 return 0;
333 }
334
335 // Parse /ignore:
336 llvm::StringSet<> IgnoredWarnings;
337 for (auto *Arg : Args.filtered(OPT_ignore))
338 IgnoredWarnings.insert(Arg->getValue());
339
340 // get output library path, if any
341 std::string OutputPath;
342 if (auto *Arg = Args.getLastArg(OPT_out)) {
343 OutputPath = Arg->getValue();
344 }
345
347 std::string LibMachineSource;
348 if (auto *Arg = Args.getLastArg(OPT_machine)) {
349 LibMachine = getMachineType(Arg->getValue());
350 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
351 llvm::errs() << "unknown /machine: arg " << Arg->getValue() << '\n';
352 return 1;
353 }
354 LibMachineSource =
355 std::string(" (from '/machine:") + Arg->getValue() + "' flag)";
356 }
357
358 // create an import library
359 if (Args.hasArg(OPT_deffile)) {
360
361 if (OutputPath.empty()) {
362 llvm::errs() << "no output path given\n";
363 return 1;
364 }
365
366 if (LibMachine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
367 llvm::errs() << "/def option requires /machine to be specified" << '\n';
368 return 1;
369 }
370
371 std::unique_ptr<MemoryBuffer> MB =
372 openFile(Args.getLastArg(OPT_deffile)->getValue());
373 if (!MB)
374 return 1;
375
376 if (!MB->getBufferSize()) {
377 llvm::errs() << "definition file empty\n";
378 return 1;
379 }
380
382 parseCOFFModuleDefinition(*MB, LibMachine, /*MingwDef=*/false);
383
384 if (!Def) {
385 llvm::errs() << "error parsing definition\n"
386 << errorToErrorCode(Def.takeError()).message();
387 return 1;
388 }
389
390 std::vector<COFFShortExport> NativeExports;
391 std::string OutputFile = Def->OutputFile;
392
393 if (isArm64EC(LibMachine) && Args.hasArg(OPT_nativedeffile)) {
394 std::unique_ptr<MemoryBuffer> NativeMB =
395 openFile(Args.getLastArg(OPT_nativedeffile)->getValue());
396 if (!NativeMB)
397 return 1;
398
399 if (!NativeMB->getBufferSize()) {
400 llvm::errs() << "native definition file empty\n";
401 return 1;
402 }
403
406
407 if (!NativeDef) {
408 llvm::errs() << "error parsing native definition\n"
409 << errorToErrorCode(NativeDef.takeError()).message();
410 return 1;
411 }
412 NativeExports = std::move(NativeDef->Exports);
413 OutputFile = std::move(NativeDef->OutputFile);
414 }
415
416 if (Error E =
417 writeImportLibrary(OutputFile, OutputPath, Def->Exports, LibMachine,
418 /*MinGW=*/false, NativeExports)) {
419 handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
420 llvm::errs() << OutputPath << ": " << EI.message() << "\n";
421 });
422 return 1;
423 }
424 return 0;
425 }
426
427 // If no input files and not told otherwise, silently do nothing to match
428 // lib.exe
429 if (!Args.hasArgNoClaim(OPT_INPUT) && !Args.hasArg(OPT_llvmlibempty)) {
430 if (!IgnoredWarnings.contains("emptyoutput")) {
431 llvm::errs() << "warning: no input files, not writing output file\n";
432 llvm::errs() << " pass /llvmlibempty to write empty .lib file,\n";
433 llvm::errs() << " pass /ignore:emptyoutput to suppress warning\n";
434 if (Args.hasFlag(OPT_WX, OPT_WX_no, false)) {
435 llvm::errs() << "treating warning as error due to /WX\n";
436 return 1;
437 }
438 }
439 return 0;
440 }
441
442 if (Args.hasArg(OPT_lst)) {
443 doList(Args);
444 return 0;
445 }
446
447 std::vector<StringRef> SearchPaths = getSearchPaths(&Args, Saver);
448
449 std::vector<std::unique_ptr<MemoryBuffer>> MBs;
450 StringSet<> Seen;
451 std::vector<NewArchiveMember> Members;
452
453 // Create a NewArchiveMember for each input file.
454 for (auto *Arg : Args.filtered(OPT_INPUT)) {
455 // Find a file
456 std::string Path = findInputFile(Arg->getValue(), SearchPaths);
457 if (Path.empty()) {
458 llvm::errs() << Arg->getValue() << ": no such file or directory\n";
459 return 1;
460 }
461
462 // Input files are uniquified by pathname. If you specify the exact same
463 // path more than once, all but the first one are ignored.
464 //
465 // Note that there's a loophole in the rule; you can prepend `.\` or
466 // something like that to a path to make it look different, and they are
467 // handled as if they were different files. This behavior is compatible with
468 // Microsoft lib.exe.
469 if (!Seen.insert(Path).second)
470 continue;
471
472 // Open a file.
474 Path, /*IsText=*/false, /*RequiresNullTerminator=*/false);
476 MemoryBufferRef MBRef = (*MOrErr)->getMemBufferRef();
477
478 // Append a file.
479 appendFile(Members, LibMachine, LibMachineSource, MBRef);
480
481 // Take the ownership of the file buffer to keep the file open.
482 MBs.push_back(std::move(*MOrErr));
483 }
484
485 // Create an archive file.
486 if (OutputPath.empty()) {
487 if (!Members.empty()) {
488 OutputPath = getDefaultOutputPath(Members[0]);
489 } else {
490 llvm::errs() << "no output path given, and cannot infer with no inputs\n";
491 return 1;
492 }
493 }
494
495 bool Thin = Args.hasArg(OPT_llvmlibthin);
496 if (Thin) {
497 for (NewArchiveMember &Member : Members) {
498 if (sys::path::is_relative(Member.MemberName)) {
499 Expected<std::string> PathOrErr =
500 computeArchiveRelativePath(OutputPath, Member.MemberName);
501 if (PathOrErr)
502 Member.MemberName = Saver.save(*PathOrErr);
503 }
504 }
505 }
506
507 // For compatibility with MSVC, reverse member vector after de-duplication.
508 std::reverse(Members.begin(), Members.end());
509
510 auto Symtab = Args.hasFlag(OPT_llvmlibindex, OPT_llvmlibindex_no,
511 /*default=*/true)
514
515 if (Error E = writeArchive(
516 OutputPath, Members, Symtab,
518 /*Deterministic=*/true, Thin, nullptr, COFF::isArm64EC(LibMachine))) {
519 handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
520 llvm::errs() << OutputPath << ": " << EI.message() << "\n";
521 });
522 return 1;
523 }
524
525 return 0;
526}
Defines the llvm::Arg class for parsed arguments.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool machineMatches(COFF::MachineTypes LibMachine, COFF::MachineTypes FileMachine)
static Expected< COFF::MachineTypes > getBitcodeFileMachine(MemoryBufferRef MB)
static Expected< COFF::MachineTypes > getCOFFFileMachine(MemoryBufferRef MB)
static std::string getDefaultOutputPath(const NewArchiveMember &FirstMember)
Definition LibDriver.cpp:57
static std::string findInputFile(StringRef File, ArrayRef< StringRef > Paths)
Definition LibDriver.cpp:99
static void doList(opt::InputArgList &Args)
static std::vector< StringRef > getSearchPaths(opt::InputArgList *Args, StringSaver &Saver)
Definition LibDriver.cpp:63
std::unique_ptr< MemoryBuffer > openFile(const Twine &Path)
Definition LibDriver.cpp:87
static void appendFile(std::vector< NewArchiveMember > &Members, COFF::MachineTypes &LibMachine, std::string &LibMachineSource, MemoryBufferRef MB)
static void fatalOpenError(llvm::Error E, Twine File)
#define T
Function const char TargetMachine * Machine
Provides a library for accessing information about this process and other processes on the operating ...
This file contains some templates that are useful if you are working with the STL at all.
StringSet - A set-like wrapper for the StringMap.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition ArrayRef.h:185
Base class for error info classes.
Definition Error.h:44
virtual std::string message() const
Return the error message as a string.
Definition Error.h:52
Represents either an error or a value T.
Definition ErrorOr.h:56
reference get()
Definition ErrorOr.h:149
std::error_code getError() const
Definition ErrorOr.h:152
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
reference get()
Returns a reference to the stored T value.
Definition Error.h:582
StringRef getBufferIdentifier() const
StringRef getBuffer() const
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,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:28
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition StringSaver.h:22
StringRef save(const char *S)
Definition StringSaver.h:31
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition StringSet.h:27
bool contains(StringRef key) const
Check if the set contains the given key.
Definition StringSet.h:62
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition StringSet.h:41
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition Archive.h:416
static Expected< std::unique_ptr< COFFObjectFile > > create(MemoryBufferRef Object)
A concrete instance of a particular driver option.
Definition Arg.h:35
LLVM_ABI std::string getAsString(const ArgList &Args) const
Return a formatted version of the argument and its values, for diagnostics.
Definition Arg.cpp:67
const char * getValue(unsigned N=0) const
Definition Arg.h:127
Provide access to the Option info table.
Definition OptTable.h:55
static LLVM_ABI std::optional< std::string > GetEnv(StringRef name)
MachineTypes
Definition COFF.h:93
@ IMAGE_FILE_MACHINE_ARM64
Definition COFF.h:101
@ IMAGE_FILE_MACHINE_UNKNOWN
Definition COFF.h:96
@ IMAGE_FILE_MACHINE_AMD64
Definition COFF.h:98
@ IMAGE_FILE_MACHINE_ARM64EC
Definition COFF.h:102
@ IMAGE_FILE_MACHINE_R4000
Definition COFF.h:113
@ IMAGE_FILE_MACHINE_I386
Definition COFF.h:105
@ IMAGE_FILE_MACHINE_ARM64X
Definition COFF.h:103
@ IMAGE_FILE_MACHINE_ARMNT
Definition COFF.h:100
bool isAnyArm64(T Machine)
Definition COFF.h:130
bool isArm64EC(T Machine)
Definition COFF.h:125
LLVM_ABI bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl< const char * > &Argv)
A convenience helper which supports the typical use case of expansion function call.
LLVM_ABI void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, SmallVectorImpl< const char * > &NewArgv, bool MarkEOLs=false)
Tokenizes a string of Windows command line arguments, which may contain quotes and escaped quotes.
LLVM_ABI Expected< COFFModuleDefinition > parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine, bool MingwDef=false, bool AddUnderscores=true)
LLVM_ABI Error writeImportLibrary(StringRef ImportName, StringRef Path, ArrayRef< COFFShortExport > Exports, COFF::MachineTypes Machine, bool MinGW, ArrayRef< COFFShortExport > NativeExports={})
Writes a COFF import library containing entries described by the Exports array.
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
Definition Path.cpp:1107
LLVM_ABI void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
Definition Path.cpp:491
LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition Path.cpp:716
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:467
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition Magic.cpp:33
LLVM_ABI Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, std::optional< bool > IsEC=std::nullopt, function_ref< void(Error)> Warn=warnToStderr)
LLVM_ABI int libDriverMain(ArrayRef< const char * > ARgs)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition Error.h:1013
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.
LLVM_ABI Expected< std::string > getBitcodeTargetTriple(MemoryBufferRef Buffer)
Read the header of the specified bitcode buffer and extract just the triple information.
LLVM_ABI COFF::MachineTypes getMachineType(StringRef S)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
LLVM_ABI StringRef machineToStr(COFF::MachineTypes MT)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI Expected< std::string > computeArchiveRelativePath(StringRef From, StringRef To)
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition Error.cpp:107
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
LLVM_ABI std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
Definition Error.cpp:113
std::unique_ptr< MemoryBuffer > Buf
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition Magic.h:21
@ coff_import_library
COFF import library.
Definition Magic.h:49
@ archive
ar style archive file
Definition Magic.h:26
@ bitcode
Bitcode file.
Definition Magic.h:24
@ windows_resource
Windows compiled resource file (.res)
Definition Magic.h:51
@ coff_object
COFF object file.
Definition Magic.h:48