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